mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-20 15:29:10 +00:00
Implemented Voronoi renderer. Added missing fragments. Added combination limit and an iteration trying to uplift the remains.
This commit is contained in:
parent
ec1838adba
commit
2a19c52c1d
@ -73,16 +73,16 @@ public class Compiler {
|
||||
program.getLog().append("REGISTER UPLIFT POTENTIAL REGISTERS");
|
||||
program.getLog().append(program.getRegisterPotentials().toString());
|
||||
|
||||
|
||||
|
||||
|
||||
// Find register uplift scopes
|
||||
new Pass3RegisterUpliftScopeAnalysis(program).findScopes();
|
||||
program.getLog().append("REGISTER UPLIFT SCOPES");
|
||||
program.getLog().append(program.getRegisterUpliftProgram().toString((program.getVariableRegisterWeights())));
|
||||
|
||||
// Attempt uplifting registers through a lot of combinations
|
||||
new Pass3RegisterUpliftCombinations(program).performUplift();
|
||||
new Pass3RegisterUpliftCombinations(program).performUplift(10_000);
|
||||
|
||||
// Attempt uplifting registers one at a time to catch remaining potential not realized by combination search
|
||||
new Pass3RegisterUpliftRemains(program).performUplift();
|
||||
|
||||
// Final register coalesce and code generation
|
||||
new Pass3ZeroPageCoalesce(program).allocate();
|
||||
|
@ -1,10 +1,14 @@
|
||||
Features
|
||||
- Move the main code into a main() function, and disallow code outside functions. The main function per default has no parameters and exits with RTS.
|
||||
- Add a for loop for(init;condition;increment) {stmt} -> { init; do { stmt; increment } while (condition) }
|
||||
- Add Fixed Point number types
|
||||
- Add for loop for(byte i: 1..100) { } and for(byte i : 100..0) {} (plus maybe .+. and .-. to make the inc/dec unambiguous)
|
||||
- Add signed bytes
|
||||
- Add signed words
|
||||
- Add Fixed Point number types fixed[8.8], fixed[16.8] - maybe even fixed[24.4]
|
||||
- Add imports
|
||||
- Add structs
|
||||
- Let { stmt } introduce a new anonymous scope.
|
||||
- Add possibility of declaring in-program data - just like .byte/.fill in KickAss.
|
||||
- Let { stmt } introduce a new anonymous scope. (But not when optimizing)
|
||||
- Add preprocessing / find a way to allow some functions to run at compile time
|
||||
- Implement inline compilation of functions (and a mechanism for choosing which methods / calls to inline)
|
||||
- Add ability to call ASM code from KC.
|
||||
@ -13,27 +17,47 @@ Features
|
||||
- Add inline ASM (maybe?)
|
||||
- Handle long branches
|
||||
- Allow complex array expressions in lValues eg. (SCREEN+$100)[idx]
|
||||
- Optimize loops by unrolling them somewhat
|
||||
- Optimize loops with Strength reduction (https://en.wikipedia.org/wiki/Strength_reduction)
|
||||
+ Create a proper main function for the compiler
|
||||
+ Add ++/-- incrementing/decrementing operators.
|
||||
|
||||
Assembler Improvements
|
||||
- Make generated ASM human readable. Use hex-numbers, add labels for constants and zp-variables.
|
||||
- Eliminate unnecessary labels in ASM
|
||||
- Eliminate CPX from DEX, CPX #0, BNE la1
|
||||
- Eliminate LDA from DEC $2, LDA $2, BNE la1
|
||||
- Eliminate LDA from STA $11, LDA $11
|
||||
- Optimize by allowing resequencing of ASM (statements and phi assignments) in a final phase.
|
||||
|
||||
Known Problems
|
||||
- Procedures that modify variables outside their scope doew not work. Outer vars must be transfered in/out like parameters/return values to get it working.
|
||||
- Alive vars are propagated backward through procedures (correctly). However they are then propagated back through ALL calls to the procedure incorrectly. They should only be alive at calls where they are alive after the call. In summin.kc s1#0 is incirrectly backpropagated through the first call, where it is not alive.
|
||||
|
||||
Register Allocation
|
||||
- Limit number of combinations tested
|
||||
- Equivalences not tested through combinaitons should be tested individually afterwards.
|
||||
- Allow user to limit number of combinations tested
|
||||
- Safe-Copy based SSA deconstruction
|
||||
- Reuse phi-transitions that are identical
|
||||
- Optimize phi transitions by ensuring that identical phi-transitions with regards to register allocation are collected into a single transition.
|
||||
- Optimize by finding optimal sequence for multiple phi assignments in entry-segments.
|
||||
- Interval Analysis (variable liveness intervals)
|
||||
- ComputeLoopNestDepth(b) - Assign loop nesting levels to blocks.
|
||||
- ComputeRegisterPreference(v), ComputeWeight(v)
|
||||
- CalculateClobbering(i)
|
||||
- Maybe support several fragements for the same operation with different cost and clobbering profiles.
|
||||
- Register types: A, X, Y, ZP, (memory).
|
||||
- Maybe register preference should also incorporate the types of operations that can be effectively performed with the register? (Maybe based on fragment cost?)
|
||||
- Implement a register allocation (coloring) algorithm using by liveness intervals, preferences, weights & clobbering information.
|
||||
- Optimize register allocation by combining with knowledge of ASM program cost (bytes/cycles) and different ASM fragments with different clobbering.
|
||||
- Avoid clobbering alive vars
|
||||
- Maybe support several fragements for the same operation with different cost and clobbering profiles.
|
||||
- Add memory registers (if we need to free some ZP)
|
||||
+ Matrix Phi operation (instead of separate statements)
|
||||
+ Phi Lifting
|
||||
+ PhiLifting & PhiMemCoalesce (http://compilers.cs.ucla.edu/fernando/projects/soc/reports/short_tech.pdf)
|
||||
+ Interval Analysis (variable liveness intervals)
|
||||
+ ComputeLoopNestDepth(b) - Assign loop nesting levels to blocks.
|
||||
+ ComputeRegisterPreference(v), ComputeWeight(v)
|
||||
+ CalculateClobbering(i)
|
||||
+ Register types: A, X, Y, ZP, (memory).
|
||||
+ Implement a register allocation (coloring) algorithm using by liveness intervals, preferences, weights & clobbering information.
|
||||
+ Optimize register allocation by combining with knowledge of ASM program cost (bytes/cycles) and different ASM fragments with different clobbering.
|
||||
|
||||
Process/Code Structure Improvement
|
||||
- Eliminate copy visitor
|
||||
- Refactor Expression Operator Implementation & Evaluation into one class per operator
|
||||
- Improve error messages to give better context
|
||||
- Offer to compile resulting ASM with KickAssembler
|
||||
@ -47,10 +71,6 @@ Testing
|
||||
- Add assert statements to the language. Create KC programs that test the compiler by compiling, running and testing assertions.
|
||||
+ Test the ASM program output resulting from compiling specific KC program input.
|
||||
|
||||
Optimizations
|
||||
- Optimize by allowing resequencing of statements and phi assignemtns in a final phase. Perhaps by converting phi statements to "normal" statements and using some optimization step.
|
||||
- This phase could also help simplify LDA xx, CMP#0, BNE by expressing these in a language where CMP can be eliminated before.
|
||||
|
||||
Usages
|
||||
- Implement library for memory allocation in main memory
|
||||
- Implement library for output on the screen (using basic functions)
|
||||
|
@ -0,0 +1,3 @@
|
||||
lda {zpby1}
|
||||
sec
|
||||
sbc {zpby2}
|
@ -0,0 +1 @@
|
||||
jmp {la1}
|
@ -0,0 +1,3 @@
|
||||
stx $ff
|
||||
cmp $ff
|
||||
beq {la1}
|
@ -0,0 +1,3 @@
|
||||
sty $ff
|
||||
cmp $ff
|
||||
beq {la1}
|
@ -0,0 +1,2 @@
|
||||
cmp {zpby1}
|
||||
beq {la1}
|
@ -0,0 +1,2 @@
|
||||
cmp {zpby1}
|
||||
bcc {la1}
|
@ -0,0 +1,4 @@
|
||||
lda {zpby1}
|
||||
sec
|
||||
sbc {zpby2}
|
||||
tax
|
@ -0,0 +1,3 @@
|
||||
stx $ff
|
||||
cmp $ff
|
||||
beq {la1}
|
@ -0,0 +1 @@
|
||||
jmp {la1}
|
@ -0,0 +1,3 @@
|
||||
sty $ff
|
||||
cpx $ff
|
||||
beq {la1}
|
@ -0,0 +1,2 @@
|
||||
cpx {zpby1}
|
||||
beq {la1}
|
@ -0,0 +1,4 @@
|
||||
lda {zpby1}
|
||||
sec
|
||||
sbc {zpby2}
|
||||
tay
|
@ -0,0 +1,3 @@
|
||||
sty $ff
|
||||
cmp $ff
|
||||
beq {la1}
|
@ -0,0 +1,3 @@
|
||||
sty $ff
|
||||
cpx $ff
|
||||
beq {la1}
|
@ -0,0 +1 @@
|
||||
jmp {la1}
|
@ -0,0 +1,2 @@
|
||||
cpy {zpby1}
|
||||
beq {la1}
|
@ -0,0 +1,3 @@
|
||||
sec
|
||||
sbc {zpby2}
|
||||
sta {zpby1}
|
@ -0,0 +1,4 @@
|
||||
lda {zpby1}
|
||||
sec
|
||||
sbc {zpby2}
|
||||
sta {zpby1}
|
@ -0,0 +1,4 @@
|
||||
lda {zpby2}
|
||||
sec
|
||||
sbc {zpby1}
|
||||
sta {zpby1}
|
@ -0,0 +1,4 @@
|
||||
lda {zpby2}
|
||||
sec
|
||||
sbc {zpby3}
|
||||
sta {zpby1}
|
@ -0,0 +1,2 @@
|
||||
cmp {zpby1}
|
||||
beq {la1}
|
@ -0,0 +1,2 @@
|
||||
cpx {zpby1}
|
||||
beq {la1}
|
@ -0,0 +1,2 @@
|
||||
cpy {zpby1}
|
||||
beq {la1}
|
@ -0,0 +1,3 @@
|
||||
lda {zpby1}
|
||||
cmp {zpby2}
|
||||
beq {la1}
|
@ -0,0 +1,3 @@
|
||||
lda {zpby1}
|
||||
cmp {zpby2}
|
||||
bcc {la1}
|
@ -0,0 +1,3 @@
|
||||
tay
|
||||
lda #{coby1}
|
||||
sta ({zpptrby1}),y
|
@ -0,0 +1,4 @@
|
||||
txa
|
||||
tay
|
||||
lda #{coby1}
|
||||
sta ({zpptrby1}),y
|
@ -0,0 +1,2 @@
|
||||
lda #{coby1}
|
||||
sta ({zpptrby1}),y
|
@ -0,0 +1,3 @@
|
||||
lda #{coby1}
|
||||
ldy {zpby1}
|
||||
sta ({zpptrby1}),y
|
@ -0,0 +1,3 @@
|
||||
lda {zpby1}
|
||||
tay
|
||||
sta ({zpptrby1}),y
|
@ -28,7 +28,7 @@ public class RegisterCombinationIterator implements Iterator<RegisterCombination
|
||||
return nextIterationId < getNumIterations();
|
||||
}
|
||||
|
||||
private int getNumIterations() {
|
||||
public int getNumIterations() {
|
||||
int numIterations = 1;
|
||||
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
|
||||
List<RegisterAllocation.Register> registers = registerPotentials.getPotentialRegisters(equivalenceClass);
|
||||
|
@ -56,7 +56,7 @@ public class RegisterUpliftScope {
|
||||
* @param registerPotentials The potential registers to use for each live range equivalence class
|
||||
* @return Iterator of all combinations
|
||||
*/
|
||||
public Iterator<RegisterCombination> geCombinationIterator(RegisterPotentials registerPotentials) {
|
||||
public RegisterCombinationIterator getCombinationIterator(RegisterPotentials registerPotentials) {
|
||||
return new RegisterCombinationIterator(equivalenceClasses, registerPotentials);
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ import dk.camelot64.kickc.asm.AsmProgram;
|
||||
import dk.camelot64.kickc.asm.AsmSegment;
|
||||
import dk.camelot64.kickc.icl.*;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -17,8 +16,7 @@ public class Pass3RegisterUpliftCombinations extends Pass2Base {
|
||||
super(program);
|
||||
}
|
||||
|
||||
|
||||
public void performUplift() {
|
||||
public void performUplift(int maxCombinations) {
|
||||
// Test uplift combinations to find the best one.
|
||||
Set<String> unknownFragments = new LinkedHashSet<>();
|
||||
List<RegisterUpliftScope> registerUpliftScopes = getProgram().getRegisterUpliftProgram().getRegisterUpliftScopes();
|
||||
@ -26,8 +24,10 @@ public class Pass3RegisterUpliftCombinations extends Pass2Base {
|
||||
int bestScore = Integer.MAX_VALUE;
|
||||
RegisterCombination bestCombination = null;
|
||||
|
||||
Iterator<RegisterCombination> combinationIterator = upliftScope.geCombinationIterator(getProgram().getRegisterPotentials());
|
||||
while (combinationIterator.hasNext()) {
|
||||
RegisterCombinationIterator combinationIterator = upliftScope.getCombinationIterator(getProgram().getRegisterPotentials());
|
||||
int countCombinations = 0;
|
||||
while (combinationIterator.hasNext() && countCombinations<maxCombinations) {
|
||||
countCombinations++;
|
||||
RegisterCombination combination = combinationIterator.next();
|
||||
// Reset register allocation to original zero page allocation
|
||||
new Pass3RegistersFinalize(getProgram()).allocate(false);
|
||||
@ -74,6 +74,11 @@ public class Pass3RegisterUpliftCombinations extends Pass2Base {
|
||||
// Save the best combination in the equivalence class
|
||||
bestCombination.store(getProgram().getLiveRangeEquivalenceClassSet());
|
||||
getLog().append("Uplifting [" + upliftScope.getScopeRef() + "] best " + bestScore + " combination " + bestCombination.toString());
|
||||
|
||||
if(combinationIterator.hasNext()) {
|
||||
getLog().append("Limited combination testing to "+countCombinations+" combinations of "+combinationIterator.getNumIterations()+" possible.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (unknownFragments.size() > 0) {
|
||||
@ -83,7 +88,9 @@ public class Pass3RegisterUpliftCombinations extends Pass2Base {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private int getAsmScore(Program program) {
|
||||
int score = 0;
|
||||
AsmProgram asm = program.getAsm();
|
||||
|
@ -1,5 +1,6 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.asm.AsmFragment;
|
||||
import dk.camelot64.kickc.asm.AsmProgram;
|
||||
import dk.camelot64.kickc.asm.parser.AsmClobber;
|
||||
import dk.camelot64.kickc.icl.*;
|
||||
@ -132,6 +133,8 @@ public class Pass3RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
||||
alwaysClobbered.add(RegisterAllocation.getRegisterX());
|
||||
alwaysClobbered.add(RegisterAllocation.getRegisterY());
|
||||
|
||||
Set<String> unknownFragments = new LinkedHashSet<>();
|
||||
|
||||
while (combinations.hasNext()) {
|
||||
RegisterCombination combination = combinations.next();
|
||||
// Reset register allocation to original zero page allocation
|
||||
@ -142,7 +145,17 @@ public class Pass3RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
||||
AsmProgram asm = new AsmProgram();
|
||||
asm.startSegment(statement.getIndex(), statement.toString(getProgram()));
|
||||
Pass3CodeGeneration.AsmCodegenAluState aluState = new Pass3CodeGeneration.AsmCodegenAluState();
|
||||
(new Pass3CodeGeneration(getProgram())).generateStatementAsm(asm, block, statement, aluState, false);
|
||||
try {
|
||||
(new Pass3CodeGeneration(getProgram())).generateStatementAsm(asm, block, statement, aluState, false);
|
||||
} catch (AsmFragment.UnknownFragmentException e) {
|
||||
unknownFragments.add(e.getFragmentSignature());
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("Potential register analysis " + statement );
|
||||
msg.append(" missing fragment " + e.getFragmentSignature());
|
||||
msg.append(" allocation: ").append(combination.toString());
|
||||
getLog().append(msg.toString());
|
||||
continue;
|
||||
}
|
||||
AsmClobber clobber = asm.getClobber();
|
||||
Collection<RegisterAllocation.Register> clobberRegisters = Pass3AssertNoCpuClobber.getClobberRegisters(clobber);
|
||||
Iterator<RegisterAllocation.Register> alwaysClobberIt = alwaysClobbered.iterator();
|
||||
@ -157,6 +170,15 @@ public class Pass3RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (unknownFragments.size() > 0) {
|
||||
getLog().append("MISSING FRAGMENTS");
|
||||
for (String unknownFragment : unknownFragments) {
|
||||
getLog().append(" " + unknownFragment);
|
||||
}
|
||||
//throw new RuntimeException("Missing fragments!");
|
||||
}
|
||||
|
||||
return alwaysClobbered;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,115 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.asm.AsmFragment;
|
||||
import dk.camelot64.kickc.asm.AsmProgram;
|
||||
import dk.camelot64.kickc.asm.AsmSegment;
|
||||
import dk.camelot64.kickc.icl.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/*** For eac non-uplifted equivalence class attempt to put it in a register */
|
||||
public class Pass3RegisterUpliftRemains extends Pass2Base {
|
||||
|
||||
public Pass3RegisterUpliftRemains(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
public void performUplift() {
|
||||
|
||||
LiveRangeEquivalenceClassSet equivalenceClassSet = getProgram().getLiveRangeEquivalenceClassSet();
|
||||
List<LiveRangeEquivalenceClass> equivalenceClasses = new ArrayList<>(equivalenceClassSet.getEquivalenceClasses());
|
||||
final VariableRegisterWeights registerWeights = getProgram().getVariableRegisterWeights();
|
||||
Collections.sort(equivalenceClasses, new Comparator<LiveRangeEquivalenceClass>() {
|
||||
@Override
|
||||
public int compare(LiveRangeEquivalenceClass o1, LiveRangeEquivalenceClass o2) {
|
||||
return Double.compare(registerWeights.getTotalWeight(o2), registerWeights.getTotalWeight(o1));
|
||||
}
|
||||
});
|
||||
|
||||
Set<String> unknownFragments = new LinkedHashSet<>();
|
||||
|
||||
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
|
||||
if (equivalenceClass.getRegister().getType().equals(RegisterAllocation.RegisterType.ZP_BYTE)) {
|
||||
int bestScore = Integer.MAX_VALUE;
|
||||
RegisterCombination bestCombination = null;
|
||||
RegisterCombinationIterator combinationIterator = new RegisterCombinationIterator(Arrays.asList(equivalenceClass), getProgram().getRegisterPotentials());
|
||||
|
||||
while (combinationIterator.hasNext()) {
|
||||
RegisterCombination combination = combinationIterator.next();
|
||||
// Reset register allocation to original zero page allocation
|
||||
new Pass3RegistersFinalize(getProgram()).allocate(false);
|
||||
// Apply the uplift combination
|
||||
combination.allocate(getProgram().getAllocation());
|
||||
// Generate ASM
|
||||
try {
|
||||
new Pass3CodeGeneration(getProgram()).generate();
|
||||
} catch (AsmFragment.UnknownFragmentException e) {
|
||||
unknownFragments.add(e.getFragmentSignature());
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("Uplift remains attempt [" + equivalenceClass + "] ");
|
||||
msg.append("missing fragment " + e.getFragmentSignature());
|
||||
msg.append(" allocation: ").append(combination.toString());
|
||||
getLog().append(msg.toString());
|
||||
continue;
|
||||
} catch (AsmFragment.AluNotApplicableException e) {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("Uplift remains attempt [" + equivalenceClass + "] ");
|
||||
msg.append("alu not applicable");
|
||||
msg.append(" allocation: ").append(combination.toString());
|
||||
getLog().append(msg.toString());
|
||||
continue;
|
||||
}
|
||||
// If no clobber - Find value of the resulting allocation
|
||||
boolean hasClobberProblem = new Pass3AssertNoCpuClobber(getProgram()).hasClobberProblem(false);
|
||||
int combinationScore = getAsmScore(getProgram());
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("Uplift remains attempt [" + equivalenceClass + "] ");
|
||||
if (hasClobberProblem) {
|
||||
msg.append("clobber");
|
||||
} else {
|
||||
msg.append(combinationScore);
|
||||
}
|
||||
msg.append(" allocation: ").append(combination.toString());
|
||||
getLog().append(msg.toString());
|
||||
if (!hasClobberProblem) {
|
||||
if (combinationScore < bestScore) {
|
||||
bestScore = combinationScore;
|
||||
bestCombination = combination;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Save the best combination in the equivalence class
|
||||
bestCombination.store(equivalenceClassSet);
|
||||
getLog().append("Uplifting remains [" + equivalenceClass + "] best " + bestScore + " combination " + bestCombination.toString());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (unknownFragments.size() > 0) {
|
||||
getLog().append("MISSING FRAGMENTS");
|
||||
for (String unknownFragment : unknownFragments) {
|
||||
getLog().append(" " + unknownFragment);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private int getAsmScore(Program program) {
|
||||
int score = 0;
|
||||
AsmProgram asm = program.getAsm();
|
||||
ControlFlowGraph graph = program.getGraph();
|
||||
NaturalLoopSet loopSet = program.getLoopSet();
|
||||
for (AsmSegment asmSegment : asm.getSegments()) {
|
||||
double asmSegmentCycles = asmSegment.getCycles();
|
||||
if (asmSegmentCycles > 0) {
|
||||
Integer statementIdx = asmSegment.getStatementIdx();
|
||||
ControlFlowBlock block = graph.getBlockFromStatementIdx(statementIdx);
|
||||
int maxLoopDepth = loopSet.getMaxLoopDepth(block.getLabel());
|
||||
score += asmSegmentCycles * Math.pow(10, maxLoopDepth);
|
||||
}
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
}
|
@ -24,6 +24,10 @@ public class TestCompilationOutput extends TestCase {
|
||||
helper = new ReferenceHelper("dk/camelot64/kickc/test/ref/");
|
||||
}
|
||||
|
||||
public void testVoronoi() throws IOException, URISyntaxException {
|
||||
compileAndCompare("voronoi");
|
||||
}
|
||||
|
||||
public void testFlipper() throws IOException, URISyntaxException {
|
||||
compileAndCompare("flipper-rex2");
|
||||
}
|
||||
|
198
src/main/java/dk/camelot64/kickc/test/ref/voronoi.asm
Normal file
198
src/main/java/dk/camelot64/kickc/test/ref/voronoi.asm
Normal file
@ -0,0 +1,198 @@
|
||||
BBEGIN:
|
||||
jsr main
|
||||
BEND:
|
||||
main:
|
||||
addpoint_from_main:
|
||||
lda #1
|
||||
sta 2
|
||||
ldx #5
|
||||
ldy #0
|
||||
lda #5
|
||||
jsr addpoint
|
||||
main__B3:
|
||||
addpoint_from_B3:
|
||||
lda #2
|
||||
sta 2
|
||||
ldx #8
|
||||
ldy #1
|
||||
lda #15
|
||||
jsr addpoint
|
||||
main__B4:
|
||||
addpoint_from_B4:
|
||||
lda #3
|
||||
sta 2
|
||||
ldx #14
|
||||
ldy #2
|
||||
lda #6
|
||||
jsr addpoint
|
||||
main__B5:
|
||||
addpoint_from_B5:
|
||||
lda #4
|
||||
sta 2
|
||||
ldx #2
|
||||
ldy #3
|
||||
lda #34
|
||||
jsr addpoint
|
||||
main__B6:
|
||||
addpoint_from_B6:
|
||||
lda #5
|
||||
sta 2
|
||||
ldx #17
|
||||
ldy #4
|
||||
lda #21
|
||||
jsr addpoint
|
||||
main__B7:
|
||||
addpoint_from_B7:
|
||||
lda #7
|
||||
sta 2
|
||||
ldx #22
|
||||
ldy #5
|
||||
lda #31
|
||||
jsr addpoint
|
||||
main__B1:
|
||||
jsr render
|
||||
main__B9:
|
||||
jmp main__B1
|
||||
main__Breturn:
|
||||
rts
|
||||
render:
|
||||
render__B1_from_render:
|
||||
lda #<1024
|
||||
sta 5
|
||||
lda #>1024
|
||||
sta 5+1
|
||||
lda #<55296
|
||||
sta 3
|
||||
lda #>55296
|
||||
sta 3+1
|
||||
lda #0
|
||||
sta 2
|
||||
render__B1_from_B3:
|
||||
render__B1:
|
||||
render__B2_from_B1:
|
||||
ldy #0
|
||||
render__B2_from_B5:
|
||||
render__B2:
|
||||
sty 10
|
||||
lda 2
|
||||
sta 11
|
||||
jsr findcol
|
||||
render__B5:
|
||||
lda 9
|
||||
sta (3),y
|
||||
lda #230
|
||||
sta (5),y
|
||||
iny
|
||||
cpy #40
|
||||
bcc render__B2_from_B5
|
||||
render__B3:
|
||||
lda 5
|
||||
clc
|
||||
adc #40
|
||||
sta 5
|
||||
bcc !+
|
||||
inc 5+1
|
||||
!:
|
||||
lda 3
|
||||
clc
|
||||
adc #40
|
||||
sta 3
|
||||
bcc !+
|
||||
inc 3+1
|
||||
!:
|
||||
inc 2
|
||||
lda 2
|
||||
cmp #25
|
||||
bcc render__B1_from_B3
|
||||
render__Breturn:
|
||||
rts
|
||||
findcol:
|
||||
findcol__B1_from_findcol:
|
||||
lda #0
|
||||
sta 9
|
||||
lda #255
|
||||
sta 7
|
||||
ldx #0
|
||||
findcol__B1_from_B13:
|
||||
findcol__B1:
|
||||
lda 4096,x
|
||||
sta 8
|
||||
lda 4352,x
|
||||
sta 12
|
||||
lda 10
|
||||
cmp 8
|
||||
beq findcol__B2
|
||||
findcol__B3:
|
||||
lda 10
|
||||
cmp 8
|
||||
bcc findcol__B6
|
||||
findcol__B7:
|
||||
lda 10
|
||||
sec
|
||||
sbc 8
|
||||
sta 8
|
||||
findcol__B8_from_B7:
|
||||
findcol__B8:
|
||||
lda 11
|
||||
cmp 12
|
||||
bcc findcol__B9
|
||||
findcol__B10:
|
||||
lda 11
|
||||
sec
|
||||
sbc 12
|
||||
clc
|
||||
adc 8
|
||||
sta 8
|
||||
findcol__B11_from_B10:
|
||||
findcol__B11:
|
||||
lda 8
|
||||
cmp 7
|
||||
bcc findcol__B12
|
||||
findcol__B13_from_B11:
|
||||
findcol__B13:
|
||||
inx
|
||||
cpx #6
|
||||
bcc findcol__B1_from_B13
|
||||
findcol__Breturn_from_B13:
|
||||
jmp findcol__Breturn
|
||||
findcol__Breturn_from_B2:
|
||||
lda #0
|
||||
sta 9
|
||||
findcol__Breturn:
|
||||
rts
|
||||
findcol__B12:
|
||||
lda 4608,x
|
||||
sta 9
|
||||
lda 8
|
||||
sta 7
|
||||
findcol__B13_from_B12:
|
||||
jmp findcol__B13
|
||||
findcol__B9:
|
||||
lda 12
|
||||
sec
|
||||
sbc 11
|
||||
clc
|
||||
adc 8
|
||||
sta 8
|
||||
findcol__B11_from_B9:
|
||||
jmp findcol__B11
|
||||
findcol__B6:
|
||||
lda 8
|
||||
sec
|
||||
sbc 10
|
||||
sta 8
|
||||
findcol__B8_from_B6:
|
||||
jmp findcol__B8
|
||||
findcol__B2:
|
||||
lda 11
|
||||
cmp 12
|
||||
beq findcol__Breturn_from_B2
|
||||
jmp findcol__B3
|
||||
addpoint:
|
||||
sta 4096,y
|
||||
txa
|
||||
sta 4352,y
|
||||
lda 2
|
||||
sta 4608,y
|
||||
addpoint__Breturn:
|
||||
rts
|
124
src/main/java/dk/camelot64/kickc/test/ref/voronoi.cfg
Normal file
124
src/main/java/dk/camelot64/kickc/test/ref/voronoi.cfg
Normal file
@ -0,0 +1,124 @@
|
||||
@BEGIN: from
|
||||
[0] call main param-assignment [ findcol::return#0 ]
|
||||
to:@END
|
||||
@END: from @BEGIN
|
||||
main: from @BEGIN
|
||||
[1] call addpoint param-assignment [ findcol::return#0 ]
|
||||
to:main::@3
|
||||
main::@3: from main
|
||||
[2] call addpoint param-assignment [ findcol::return#0 ]
|
||||
to:main::@4
|
||||
main::@4: from main::@3
|
||||
[3] call addpoint param-assignment [ findcol::return#0 ]
|
||||
to:main::@5
|
||||
main::@5: from main::@4
|
||||
[4] call addpoint param-assignment [ findcol::return#0 ]
|
||||
to:main::@6
|
||||
main::@6: from main::@5
|
||||
[5] call addpoint param-assignment [ findcol::return#0 ]
|
||||
to:main::@7
|
||||
main::@7: from main::@6
|
||||
[6] call addpoint param-assignment [ findcol::return#0 ]
|
||||
to:main::@1
|
||||
main::@1: from main::@7 main::@9
|
||||
[7] call render param-assignment [ findcol::return#0 ]
|
||||
to:main::@9
|
||||
main::@9: from main::@1
|
||||
[8] if(true) goto main::@1 [ findcol::return#0 ]
|
||||
to:main::@return
|
||||
main::@return: from main::@9
|
||||
[9] return [ findcol::return#0 ]
|
||||
to:@RETURN
|
||||
render: from main::@1
|
||||
to:render::@1
|
||||
render::@1: from render render::@3
|
||||
[10] (byte*) render::chrline#2 ← phi( render/(word) 1024 render::@3/(byte*) render::chrline#1 ) [ render::y#2 findcol::return#0 render::colline#2 render::chrline#2 ]
|
||||
[10] (byte*) render::colline#2 ← phi( render/(word) 55296 render::@3/(byte*) render::colline#1 ) [ render::y#2 findcol::return#0 render::colline#2 render::chrline#2 ]
|
||||
[10] (byte) render::y#2 ← phi( render/(byte) 0 render::@3/(byte) render::y#1 ) [ render::y#2 findcol::return#0 render::colline#2 render::chrline#2 ]
|
||||
to:render::@2
|
||||
render::@2: from render::@1 render::@5
|
||||
[11] (byte) render::x#2 ← phi( render::@1/(byte) 0 render::@5/(byte) render::x#1 ) [ render::x#2 render::y#2 findcol::return#0 render::colline#2 render::chrline#2 ]
|
||||
[12] (byte) findcol::x#0 ← (byte) render::x#2 [ render::x#2 render::y#2 findcol::return#0 render::colline#2 render::chrline#2 findcol::x#0 ]
|
||||
[13] (byte) findcol::y#0 ← (byte) render::y#2 [ render::x#2 render::y#2 findcol::return#0 render::colline#2 render::chrline#2 findcol::x#0 findcol::y#0 ]
|
||||
[14] call findcol param-assignment [ render::x#2 render::y#2 findcol::return#0 render::colline#2 render::chrline#2 findcol::x#0 findcol::y#0 ]
|
||||
to:render::@5
|
||||
render::@5: from render::@2
|
||||
[15] (byte) render::col#0 ← (byte) findcol::return#0 [ render::x#2 render::y#2 findcol::return#0 render::colline#2 render::col#0 render::chrline#2 ]
|
||||
[16] *((byte*) render::colline#2 + (byte) render::x#2) ← (byte) render::col#0 [ render::x#2 render::y#2 findcol::return#0 render::colline#2 render::chrline#2 ]
|
||||
[17] *((byte*) render::chrline#2 + (byte) render::x#2) ← (byte) 230 [ render::x#2 render::y#2 findcol::return#0 render::colline#2 render::chrline#2 ]
|
||||
[18] (byte) render::x#1 ← ++ (byte) render::x#2 [ render::x#1 render::y#2 findcol::return#0 render::colline#2 render::chrline#2 ]
|
||||
[19] if((byte) render::x#1<(byte) 40) goto render::@2 [ render::x#1 render::y#2 findcol::return#0 render::colline#2 render::chrline#2 ]
|
||||
to:render::@3
|
||||
render::@3: from render::@5
|
||||
[20] (byte*) render::chrline#1 ← (byte*) render::chrline#2 + (byte) 40 [ render::chrline#1 render::y#2 findcol::return#0 render::colline#2 ]
|
||||
[21] (byte*) render::colline#1 ← (byte*) render::colline#2 + (byte) 40 [ render::colline#1 render::chrline#1 render::y#2 findcol::return#0 ]
|
||||
[22] (byte) render::y#1 ← ++ (byte) render::y#2 [ render::y#1 render::colline#1 render::chrline#1 findcol::return#0 ]
|
||||
[23] if((byte) render::y#1<(byte) 25) goto render::@1 [ render::y#1 render::colline#1 render::chrline#1 findcol::return#0 ]
|
||||
to:render::@return
|
||||
render::@return: from render::@3
|
||||
[24] return [ findcol::return#0 ]
|
||||
to:@RETURN
|
||||
findcol: from render::@2
|
||||
to:findcol::@1
|
||||
findcol::@1: from findcol findcol::@13
|
||||
[25] (byte) findcol::mincol#11 ← phi( findcol/(byte) 0 findcol::@13/(byte) findcol::mincol#2 ) [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
[25] (byte) findcol::mindiff#10 ← phi( findcol/(byte) 255 findcol::@13/(byte) findcol::mindiff#11 ) [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
[25] (byte) findcol::i#12 ← phi( findcol/(byte) 0 findcol::@13/(byte) findcol::i#1 ) [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
[26] (byte) findcol::xp#0 ← (word) 4096 *idx (byte) findcol::i#12 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::xp#0 findcol::y#0 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
[27] (byte) findcol::yp#0 ← (word) 4352 *idx (byte) findcol::i#12 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::xp#0 findcol::y#0 findcol::yp#0 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
[28] if((byte) findcol::x#0==(byte) findcol::xp#0) goto findcol::@2 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::xp#0 findcol::y#0 findcol::yp#0 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
to:findcol::@3
|
||||
findcol::@3: from findcol::@1 findcol::@2
|
||||
[29] if((byte) findcol::x#0<(byte) findcol::xp#0) goto findcol::@6 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::xp#0 findcol::y#0 findcol::yp#0 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
to:findcol::@7
|
||||
findcol::@7: from findcol::@3
|
||||
[30] (byte) findcol::diff#1 ← (byte) findcol::x#0 - (byte) findcol::xp#0 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::diff#1 findcol::y#0 findcol::yp#0 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
to:findcol::@8
|
||||
findcol::@8: from findcol::@6 findcol::@7
|
||||
[31] (byte) findcol::diff#4 ← phi( findcol::@6/(byte) findcol::diff#0 findcol::@7/(byte) findcol::diff#1 ) [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::yp#0 findcol::diff#4 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
[32] if((byte) findcol::y#0<(byte) findcol::yp#0) goto findcol::@9 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::yp#0 findcol::diff#4 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
to:findcol::@10
|
||||
findcol::@10: from findcol::@8
|
||||
[33] (byte~) findcol::$10 ← (byte) findcol::y#0 - (byte) findcol::yp#0 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::diff#4 findcol::$10 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
[34] (byte) findcol::diff#3 ← (byte) findcol::diff#4 + (byte~) findcol::$10 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::diff#3 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
to:findcol::@11
|
||||
findcol::@11: from findcol::@10 findcol::@9
|
||||
[35] (byte) findcol::diff#6 ← phi( findcol::@10/(byte) findcol::diff#3 findcol::@9/(byte) findcol::diff#2 ) [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::diff#6 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
[36] if((byte) findcol::diff#6<(byte) findcol::mindiff#10) goto findcol::@12 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::diff#6 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
to:findcol::@13
|
||||
findcol::@13: from findcol::@11 findcol::@12
|
||||
[37] (byte) findcol::mindiff#11 ← phi( findcol::@11/(byte) findcol::mindiff#10 findcol::@12/(byte~) findcol::diff#13 ) [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::mindiff#11 findcol::mincol#2 findcol::i#12 findcol::x#0 findcol::y#0 ]
|
||||
[37] (byte) findcol::mincol#2 ← phi( findcol::@11/(byte) findcol::mincol#11 findcol::@12/(byte) findcol::mincol#1 ) [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::mindiff#11 findcol::mincol#2 findcol::i#12 findcol::x#0 findcol::y#0 ]
|
||||
[38] (byte) findcol::i#1 ← ++ (byte) findcol::i#12 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#1 findcol::mindiff#11 findcol::mincol#2 findcol::x#0 findcol::y#0 ]
|
||||
[39] if((byte) findcol::i#1<(byte) 6) goto findcol::@1 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#1 findcol::mindiff#11 findcol::mincol#2 findcol::x#0 findcol::y#0 ]
|
||||
to:findcol::@return
|
||||
findcol::@return: from findcol::@13 findcol::@2
|
||||
[40] (byte) findcol::return#0 ← phi( findcol::@13/(byte) findcol::mincol#2 findcol::@2/(byte) 0 ) [ render::x#2 render::y#2 findcol::return#0 render::colline#2 render::chrline#2 findcol::x#0 findcol::y#0 ]
|
||||
[41] return [ render::x#2 render::y#2 findcol::return#0 render::colline#2 render::chrline#2 findcol::x#0 findcol::y#0 ]
|
||||
to:@RETURN
|
||||
findcol::@12: from findcol::@11
|
||||
[42] (byte) findcol::mincol#1 ← (word) 4608 *idx (byte) findcol::i#12 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::diff#6 findcol::mincol#1 ]
|
||||
[43] (byte~) findcol::diff#13 ← (byte) findcol::diff#6 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::mincol#1 findcol::diff#13 ]
|
||||
to:findcol::@13
|
||||
findcol::@9: from findcol::@8
|
||||
[44] (byte~) findcol::$8 ← (byte) findcol::yp#0 - (byte) findcol::y#0 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::diff#4 findcol::mindiff#10 findcol::mincol#11 findcol::$8 ]
|
||||
[45] (byte) findcol::diff#2 ← (byte) findcol::diff#4 + (byte~) findcol::$8 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::y#0 findcol::diff#2 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
to:findcol::@11
|
||||
findcol::@6: from findcol::@3
|
||||
[46] (byte) findcol::diff#0 ← (byte) findcol::xp#0 - (byte) findcol::x#0 [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::diff#0 findcol::y#0 findcol::yp#0 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
to:findcol::@8
|
||||
findcol::@2: from findcol::@1
|
||||
[47] if((byte) findcol::y#0==(byte) findcol::yp#0) goto findcol::@return [ render::x#2 render::y#2 render::colline#2 render::chrline#2 findcol::i#12 findcol::x#0 findcol::xp#0 findcol::y#0 findcol::yp#0 findcol::mindiff#10 findcol::mincol#11 ]
|
||||
to:findcol::@3
|
||||
addpoint: from main main::@3 main::@4 main::@5 main::@6 main::@7
|
||||
[48] (byte) addpoint::c#6 ← phi( main/(byte) 1 main::@3/(byte) 2 main::@4/(byte) 3 main::@5/(byte) 4 main::@6/(byte) 5 main::@7/(byte) 7 ) [ findcol::return#0 addpoint::idx#6 addpoint::x#6 addpoint::y#6 addpoint::c#6 ]
|
||||
[48] (byte) addpoint::y#6 ← phi( main/(byte) 5 main::@3/(byte) 8 main::@4/(byte) 14 main::@5/(byte) 2 main::@6/(byte) 17 main::@7/(byte) 22 ) [ findcol::return#0 addpoint::idx#6 addpoint::x#6 addpoint::y#6 addpoint::c#6 ]
|
||||
[48] (byte) addpoint::idx#6 ← phi( main/(byte) 0 main::@3/(byte) 1 main::@4/(byte) 2 main::@5/(byte) 3 main::@6/(byte) 4 main::@7/(byte) 5 ) [ findcol::return#0 addpoint::idx#6 addpoint::x#6 addpoint::y#6 addpoint::c#6 ]
|
||||
[48] (byte) addpoint::x#6 ← phi( main/(byte) 5 main::@3/(byte) 15 main::@4/(byte) 6 main::@5/(byte) 34 main::@6/(byte) 21 main::@7/(byte) 31 ) [ findcol::return#0 addpoint::idx#6 addpoint::x#6 addpoint::y#6 addpoint::c#6 ]
|
||||
[49] *((word) 4096 + (byte) addpoint::idx#6) ← (byte) addpoint::x#6 [ findcol::return#0 addpoint::idx#6 addpoint::y#6 addpoint::c#6 ]
|
||||
[50] *((word) 4352 + (byte) addpoint::idx#6) ← (byte) addpoint::y#6 [ findcol::return#0 addpoint::idx#6 addpoint::c#6 ]
|
||||
[51] *((word) 4608 + (byte) addpoint::idx#6) ← (byte) addpoint::c#6 [ findcol::return#0 ]
|
||||
to:addpoint::@return
|
||||
addpoint::@return: from addpoint
|
||||
[52] return [ findcol::return#0 ]
|
||||
to:@RETURN
|
17629
src/main/java/dk/camelot64/kickc/test/ref/voronoi.log
Normal file
17629
src/main/java/dk/camelot64/kickc/test/ref/voronoi.log
Normal file
File diff suppressed because it is too large
Load Diff
109
src/main/java/dk/camelot64/kickc/test/ref/voronoi.sym
Normal file
109
src/main/java/dk/camelot64/kickc/test/ref/voronoi.sym
Normal file
@ -0,0 +1,109 @@
|
||||
(label) @BEGIN
|
||||
(label) @END
|
||||
(byte*) COLORS
|
||||
(byte[256]) COLS
|
||||
(byte) FILL
|
||||
(byte*) SCREEN
|
||||
(byte[256]) XPOS
|
||||
(byte[256]) YPOS
|
||||
(void()) addpoint((byte) addpoint::idx , (byte) addpoint::x , (byte) addpoint::y , (byte) addpoint::c)
|
||||
(label) addpoint::@return
|
||||
(byte) addpoint::c
|
||||
(byte) addpoint::c#6 zp byte:2 0.6666666666666666
|
||||
(byte) addpoint::idx
|
||||
(byte) addpoint::idx#6 reg byte y 2.0
|
||||
(byte) addpoint::x
|
||||
(byte) addpoint::x#6 reg byte a 2.0
|
||||
(byte) addpoint::y
|
||||
(byte) addpoint::y#6 reg byte x 1.0
|
||||
(byte()) findcol((byte) findcol::x , (byte) findcol::y)
|
||||
(byte~) findcol::$10 reg byte a 20002.0
|
||||
(byte~) findcol::$8 reg byte a 20002.0
|
||||
(label) findcol::@1
|
||||
(label) findcol::@10
|
||||
(label) findcol::@11
|
||||
(label) findcol::@12
|
||||
(label) findcol::@13
|
||||
(label) findcol::@2
|
||||
(label) findcol::@3
|
||||
(label) findcol::@6
|
||||
(label) findcol::@7
|
||||
(label) findcol::@8
|
||||
(label) findcol::@9
|
||||
(label) findcol::@return
|
||||
(byte) findcol::diff
|
||||
(byte) findcol::diff#0 zp byte:8 20002.0
|
||||
(byte) findcol::diff#1 zp byte:8 20002.0
|
||||
(byte~) findcol::diff#13 zp byte:7 20002.0
|
||||
(byte) findcol::diff#2 zp byte:8 20002.0
|
||||
(byte) findcol::diff#3 zp byte:8 20002.0
|
||||
(byte) findcol::diff#4 zp byte:8 10001.0
|
||||
(byte) findcol::diff#6 zp byte:8 13334.666666666666
|
||||
(byte) findcol::i
|
||||
(byte) findcol::i#1 reg byte x 15001.5
|
||||
(byte) findcol::i#12 reg byte x 2631.842105263158
|
||||
(byte) findcol::mincol
|
||||
(byte) findcol::mincol#1 zp byte:9 10001.0
|
||||
(byte) findcol::mincol#11 zp byte:9 1250.125
|
||||
(byte) findcol::mincol#2 zp byte:9 13334.666666666666
|
||||
(byte) findcol::mindiff
|
||||
(byte) findcol::mindiff#10 zp byte:7 1875.1875
|
||||
(byte) findcol::mindiff#11 zp byte:7 10001.0
|
||||
(byte) findcol::return
|
||||
(byte) findcol::return#0 zp byte:9 343.8125
|
||||
(byte) findcol::x
|
||||
(byte) findcol::x#0 zp byte:10 1577.1153846153845
|
||||
(byte) findcol::xp
|
||||
(byte) findcol::xp#0 zp byte:8 10001.0
|
||||
(byte) findcol::y
|
||||
(byte) findcol::y#0 zp byte:11 1640.2
|
||||
(byte) findcol::yp
|
||||
(byte) findcol::yp#0 zp byte:12 6250.625
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@3
|
||||
(label) main::@4
|
||||
(label) main::@5
|
||||
(label) main::@6
|
||||
(label) main::@7
|
||||
(label) main::@9
|
||||
(label) main::@return
|
||||
(byte) numpoints
|
||||
(void()) render()
|
||||
(label) render::@1
|
||||
(label) render::@2
|
||||
(label) render::@3
|
||||
(label) render::@5
|
||||
(label) render::@return
|
||||
(byte*) render::chrline
|
||||
(byte*) render::chrline#1 zp ptr byte:5 50.5
|
||||
(byte*) render::chrline#2 zp ptr byte:5 36.45454545454545
|
||||
(byte) render::col
|
||||
(byte) render::col#0 reg byte a 2002.0
|
||||
(byte*) render::colline
|
||||
(byte*) render::colline#1 zp ptr byte:3 67.33333333333333
|
||||
(byte*) render::colline#2 zp ptr byte:3 35.38235294117647
|
||||
(byte) render::x
|
||||
(byte) render::x#1 reg byte y 1501.5
|
||||
(byte) render::x#2 reg byte y 166.83333333333334
|
||||
(byte) render::y
|
||||
(byte) render::y#1 zp byte:2 151.5
|
||||
(byte) render::y#2 zp byte:2 34.371428571428574
|
||||
|
||||
zp byte:2 [ render::y#2 render::y#1 addpoint::c#6 ]
|
||||
zp ptr byte:3 [ render::colline#2 render::colline#1 ]
|
||||
zp ptr byte:5 [ render::chrline#2 render::chrline#1 ]
|
||||
reg byte y [ render::x#2 render::x#1 ]
|
||||
reg byte x [ findcol::i#12 findcol::i#1 ]
|
||||
zp byte:7 [ findcol::mindiff#10 findcol::mindiff#11 findcol::diff#13 ]
|
||||
zp byte:8 [ findcol::diff#4 findcol::diff#0 findcol::diff#1 findcol::diff#6 findcol::diff#3 findcol::diff#2 findcol::xp#0 ]
|
||||
zp byte:9 [ findcol::return#0 findcol::mincol#11 findcol::mincol#2 findcol::mincol#1 ]
|
||||
reg byte a [ addpoint::x#6 ]
|
||||
reg byte y [ addpoint::idx#6 ]
|
||||
reg byte x [ addpoint::y#6 ]
|
||||
zp byte:10 [ findcol::x#0 ]
|
||||
zp byte:11 [ findcol::y#0 ]
|
||||
reg byte a [ render::col#0 ]
|
||||
zp byte:12 [ findcol::yp#0 ]
|
||||
reg byte a [ findcol::$10 ]
|
||||
reg byte a [ findcol::$8 ]
|
82
src/main/java/dk/camelot64/kickc/test/voronoi.kc
Normal file
82
src/main/java/dk/camelot64/kickc/test/voronoi.kc
Normal file
@ -0,0 +1,82 @@
|
||||
// The screen
|
||||
byte *SCREEN = $0400;
|
||||
byte *COLORS = $D800;
|
||||
|
||||
byte FILL = 230;
|
||||
|
||||
// The total number of voronoi points
|
||||
byte numpoints = 6;
|
||||
|
||||
// Points to create the Voronoi from
|
||||
byte[$100] XPOS = $1000;
|
||||
byte[$100] YPOS = $1100;
|
||||
byte[$100] COLS = $1200;
|
||||
|
||||
main();
|
||||
|
||||
void main() {
|
||||
addpoint(0, 5, 5, 1);
|
||||
addpoint(1, 15, 8, 2);
|
||||
addpoint(2, 6, 14, 3);
|
||||
addpoint(3, 34, 2, 4);
|
||||
addpoint(4, 21, 17, 5);
|
||||
addpoint(5, 31, 22, 7);
|
||||
do {
|
||||
render();
|
||||
} while(true)
|
||||
}
|
||||
|
||||
void addpoint(byte idx, byte x, byte y, byte c) {
|
||||
XPOS[idx] = x;
|
||||
YPOS[idx] = y;
|
||||
COLS[idx] = c;
|
||||
}
|
||||
|
||||
void render() {
|
||||
byte* chrline = SCREEN;
|
||||
byte* colline = COLORS;
|
||||
byte y=0;
|
||||
do {
|
||||
byte x=0;
|
||||
do {
|
||||
byte col = findcol(x, y);
|
||||
colline[x] = col;
|
||||
chrline[x] = FILL;
|
||||
} while(++x < 40)
|
||||
chrline = chrline+40;
|
||||
colline = colline+40;
|
||||
} while(++y < 25)
|
||||
}
|
||||
|
||||
byte findcol(byte x, byte y) {
|
||||
byte mindiff = 255;
|
||||
byte mincol = 0;
|
||||
byte i=0;
|
||||
do {
|
||||
byte xp = XPOS[i];
|
||||
byte yp = YPOS[i];
|
||||
if(x==xp) {
|
||||
if(y==yp) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
byte diff;
|
||||
if(x<xp) {
|
||||
diff = xp-x;
|
||||
} else {
|
||||
diff = x-xp;
|
||||
}
|
||||
if(y<yp) {
|
||||
diff = diff + (yp-y);
|
||||
} else {
|
||||
diff = diff + (y-yp);
|
||||
}
|
||||
if(diff<mindiff) {
|
||||
mindiff=diff;
|
||||
mincol = COLS[i];
|
||||
}
|
||||
} while(++i<numpoints)
|
||||
return mincol;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user