1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-04-07 06:37:31 +00:00

Improved code by avoiding unnecesary casts

This commit is contained in:
jespergravgaard 2019-05-18 23:58:04 +02:00
parent abfa6f875f
commit b5a9d47472
47 changed files with 185 additions and 452 deletions

View File

@ -0,0 +1,3 @@
sta {c1},y
lda #0
sta {c1}+1,y

View File

@ -0,0 +1,7 @@
lda {z2}
sta {z1}
lda {z2}+1
sta {z1}+1
lda #0
sta {z1}+2
sta {z1}+3

View File

@ -252,16 +252,13 @@ public class Compiler {
optimizations.add(new Pass2ConstantValues(program));
optimizations.add(new PassNStatementIndices(program));
optimizations.add(new PassNVariableReferenceInfos(program));
//optimizations.add(new Pass2ConstantAdditionElimination(program));
optimizations.add(new Pass2ConstantIfs(program));
optimizations.add(new Pass2ConstantStringConsolidation(program));
//optimizations.add(new Pass2FixInlineConstructors(program));
optimizations.add(new Pass2FixInlineConstructorsNew(program));
optimizations.add(new PassNAddTypeConversionAssignment(program));
optimizations.add(new Pass2TypeInference(program));
optimizations.add(new PassNEliminateUnusedVars(program, true));
optimizations.add(new Pass2EliminateRedundantCasts(program));
//optimizations.add(new Pass2NopCastElimination(program));
optimizations.add(new Pass2EliminateUnusedBlocks(program));
optimizations.add(new Pass2RangeResolving(program));
optimizations.add(new Pass2ComparisonOptimization(program));
@ -386,7 +383,6 @@ public class Compiler {
new Pass3AssertConstants(program).check();
new Pass3AssertArrayLengths(program).check();
new Pass3AssertNoMulDivMod(program).check();
new Pass3AddAssignmentCasts(program).execute();
new PassNCastSimplification(program).execute();
new PassNBlockSequencePlanner(program).step();
// Phi lifting ensures that all variables in phi-blocks are in different live range equivalence classes

View File

@ -202,7 +202,8 @@ public class SymbolTypeConversion {
return false;
else
return true;
}
}

View File

@ -1,132 +0,0 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Comment;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.iterator.ProgramValueHandler;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.operators.Operator;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.symbols.VariableIntermediate;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeArray;
import dk.camelot64.kickc.model.types.SymbolTypeInference;
import dk.camelot64.kickc.model.types.SymbolTypeIntegerFixed;
import dk.camelot64.kickc.model.values.Value;
import dk.camelot64.kickc.model.values.ValueList;
import java.util.ListIterator;
/**
* Identifies word constructors <code>{ b1, b2 }</code> and replaces
* them with a binary operator <code>word w = b1 w= b2 ;</code>
*/
public class Pass2FixInlineConstructors extends Pass2SsaOptimization {
public Pass2FixInlineConstructors(Program program) {
super(program);
}
@Override
public boolean step() {
WordConstructor wordConstructor = new WordConstructor();
ProgramValueIterator.execute(getGraph(), wordConstructor);
DWordConstructor dwordConstructor = new DWordConstructor();
ProgramValueIterator.execute(getGraph(), dwordConstructor);
return wordConstructor.isOptimized() || dwordConstructor.isOptimized();
}
/** Replaces { b1, b2 } with a w= operator */
private class WordConstructor extends InlineConstructor {
public WordConstructor() {
super(SymbolType.WORD, Operators.WORD);
}
@Override
protected boolean isSubType(SymbolType elmType) {
return SymbolType.BYTE.equals(elmType);
}
}
/** Replaces { w1, w2 } with a dw= operator */
private class DWordConstructor extends InlineConstructor {
public DWordConstructor() {
super(SymbolType.DWORD, Operators.DWORD);
}
@Override
protected boolean isSubType(SymbolType elmType) {
return SymbolType.WORD.equals(elmType);
}
}
private abstract class InlineConstructor implements ProgramValueHandler {
private SymbolTypeIntegerFixed constructType;
private Operator constructOperator;
private boolean optimized;
public InlineConstructor(SymbolTypeIntegerFixed constructType, Operator constructOperator) {
this.constructType = constructType;
this.constructOperator = constructOperator;
}
protected abstract boolean isSubType(SymbolType elmType);
public boolean isOptimized() {
return optimized;
}
@Override
public void execute(ProgramValue programValue, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
Value rValue = programValue.get();
if(rValue instanceof ValueList) {
ValueList list = (ValueList) rValue;
if(list.getList().size() == 2) {
// We have a simple assignment of a length 2 value list to a variable
SymbolType elmType1 = SymbolTypeInference.inferType(Pass2FixInlineConstructors.this.getScope(), list.getList().get(0));
SymbolType elmType2 = SymbolTypeInference.inferType(Pass2FixInlineConstructors.this.getScope(), list.getList().get(1));
if(isSubType(elmType1) && isSubType(elmType2)) {
// We have a 2-element list { byte, byte }
// Check if we are assigning into a declared byte array
if(currentStmt instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) currentStmt;
if(assignment.getrValue1() == null && assignment.getOperator() == null && assignment.getrValue2().equals(rValue)) {
SymbolType lType = SymbolTypeInference.inferType(Pass2FixInlineConstructors.this.getScope(), assignment.getlValue());
if(lType instanceof SymbolTypeArray && isSubType(((SymbolTypeArray) lType).getElementType())) {
// We are assigning into a declared byte array - do not convert!
return;
}
}
}
// Convert list to a word constructor in a new tmp variable
Scope currentScope = Pass2FixInlineConstructors.this.getScope().getScope(currentBlock.getScope());
VariableIntermediate tmpVar = currentScope.addVariableIntermediate();
tmpVar.setTypeInferred(constructType);
// Move backward - to insert before the current statement
stmtIt.previous();
// Add assignment of the new tmpVar
StatementAssignment assignment = new StatementAssignment(tmpVar.getRef(), list.getList().get(0), constructOperator, list.getList().get(1), currentStmt.getSource(), Comment.NO_COMMENTS);
stmtIt.add(assignment);
// Move back before the current statement
stmtIt.next();
// Replace current value with the reference
programValue.set(tmpVar.getRef());
Pass2FixInlineConstructors.this.getLog().append("Fixing inline constructor with " + assignment.toString());
optimized = true;
}
}
}
}
}
}

View File

@ -1,87 +0,0 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.operators.OperatorCastPtr;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.values.*;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeInference;
import dk.camelot64.kickc.model.types.SymbolTypePointer;
import java.util.LinkedHashMap;
import java.util.ListIterator;
/**
* Compiler Pass eliminating cast assignments that has no effect (byte to/from signed byte, word to/from signed word)
*/
public class Pass2NopCastElimination extends Pass2SsaOptimization {
public Pass2NopCastElimination(Program program) {
super(program);
}
/**
* Eliminate cast assignments that has no effect (byte to/from signed byte, word to/from signed word)
*/
@Override
public boolean step() {
LinkedHashMap<SymbolRef, RValue> castAliasses = new LinkedHashMap<>();
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
ListIterator<Statement> stmtIt = block.getStatements().listIterator();
while(stmtIt.hasNext()) {
Statement stmt = stmtIt.next();
if(stmt instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) stmt;
if(assignment.getlValue() instanceof VariableRef && assignment.getrValue1()==null && assignment.getOperator()!=null ) {
// It is a simple cast assignment - check if it is no-op
SymbolType rValType = SymbolTypeInference.inferType(getScope(), assignment.getrValue2());
boolean isNopCast = false;
SymbolType toType = null;
if(SymbolType.BYTE.equals(rValType) && Operators.CAST_SBYTE.equals(assignment.getOperator())) {
isNopCast = true;
toType = SymbolType.SBYTE;
} else if(SymbolType.SBYTE.equals(rValType) && Operators.CAST_BYTE.equals(assignment.getOperator())) {
isNopCast = true;
toType = SymbolType.BYTE;
} else if(SymbolType.WORD.equals(rValType) && Operators.CAST_SWORD.equals(assignment.getOperator())) {
isNopCast = true;
toType = SymbolType.SWORD;
} else if(SymbolType.SWORD.equals(rValType) && Operators.CAST_WORD.equals(assignment.getOperator())) {
isNopCast = true;
toType = SymbolType.WORD;
} else if(SymbolType.WORD.equals(rValType) && assignment.getOperator() instanceof OperatorCastPtr) {
isNopCast = true;
OperatorCastPtr castOperator = (OperatorCastPtr) (assignment.getOperator());
toType = new SymbolTypePointer(castOperator.getElementType());
} else if(rValType instanceof SymbolTypePointer && Operators.CAST_WORD.equals(assignment.getOperator())) {
isNopCast = true;
toType = SymbolType.WORD;
} else if(rValType instanceof SymbolTypePointer && assignment.getOperator() instanceof OperatorCastPtr) {
isNopCast = true;
toType = new SymbolTypePointer(((OperatorCastPtr) assignment.getOperator()).getElementType());
}
if(isNopCast) {
getLog().append("Eliminating Noop Cast "+assignment.toString(getProgram(), false));
// Add the alias for replacement
if(assignment.getrValue2() instanceof ConstantValue) {
castAliasses.put((VariableRef) assignment.getlValue(), new ConstantCastValue(toType, (ConstantValue) assignment.getrValue2()));
} else {
castAliasses.put((VariableRef) assignment.getlValue(), new CastValue(toType, assignment.getrValue2()));
}
// Remove the assignment
stmtIt.remove();
}
}
}
}
}
replaceVariables(castAliasses);
deleteSymbols(getScope(), castAliasses.keySet());
return (castAliasses.size() > 0);
}
}

View File

@ -1,41 +0,0 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ProgramExpressionBinary;
import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeConversion;
import dk.camelot64.kickc.model.types.SymbolTypeInference;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Add casts to assignments where the lvalue and rvalue have different matching types.
*/
public class Pass3AddAssignmentCasts extends Pass2SsaOptimization {
public Pass3AddAssignmentCasts(Program program) {
super(program);
}
@Override
public boolean step() {
AtomicBoolean modified = new AtomicBoolean(false);
ProgramExpressionIterator.execute(getProgram(), (programExpression, currentStmt, stmtIt, currentBlock) -> {
if(programExpression instanceof ProgramExpressionBinary) {
if(Operators.ASSIGNMENT.equals(programExpression.getOperator())) {
ProgramExpressionBinary binary = (ProgramExpressionBinary) programExpression;
SymbolType leftType = SymbolTypeInference.inferType(getScope(), binary.getLeft());
SymbolType rightType = SymbolTypeInference.inferType(getScope(), binary.getRight());
if(SymbolTypeConversion.assignmentTypeMatch(leftType, rightType) && SymbolTypeConversion.assignmentCastNeeded(leftType, rightType)) {
binary.addRightCast(leftType, stmtIt, currentBlock.getScope(), getScope());
getLog().append("Adding assignment cast to " + currentStmt.toString(getProgram(), false));
modified.set(true);
}
}
}
});
return modified.get();
}
}

View File

@ -1,6 +1,8 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeConversion;
import dk.camelot64.kickc.model.values.ConstantValue;
import dk.camelot64.kickc.model.values.VariableRef;
import dk.camelot64.kickc.model.statements.StatementAssignment;
@ -49,9 +51,12 @@ public class Pass3PhiMemCoalesce extends Pass2SsaOptimization {
*/
public static class EquivalenceClassPhiInitializer extends ControlFlowGraphBaseVisitor<Void> {
private Program program;
private LiveRangeEquivalenceClassSet phiEquivalenceClasses;
public EquivalenceClassPhiInitializer(Program program) {
this.program = program;
this.phiEquivalenceClasses = new LiveRangeEquivalenceClassSet(program);
}
@ -65,7 +70,13 @@ public class Pass3PhiMemCoalesce extends Pass2SsaOptimization {
VariableRef phiRVar = (VariableRef) phiRValue.getrValue();
LiveRangeEquivalenceClass rValEquivalenceClass = phiEquivalenceClasses.getOrCreateEquivalenceClass(phiRVar);
if(!rValEquivalenceClass.equals(equivalenceClass)) {
phiEquivalenceClasses.consolidate(equivalenceClass, rValEquivalenceClass);
SymbolType varType = program.getScope().getVariable(variable).getType();
SymbolType rVarType = program.getScope().getVariable(phiRVar).getType();
if(varType.getSizeBytes()==rVarType.getSizeBytes()) {
phiEquivalenceClasses.consolidate(equivalenceClass, rValEquivalenceClass);
} else {
program.getLog().append("Not consolidating phi with different size "+variable.toString()+" "+phiRVar.toString());
}
}
}
}

View File

@ -63,6 +63,11 @@ public class TestPrograms {
*/
@Test
public void testMul8uMin() throws IOException, URISyntaxException {
compileAndCompare("mul8u-min");
}
@Test
public void testNumberInferenceSum() throws IOException, URISyntaxException {
compileAndCompare("number-inference-sum");

14
src/test/kc/mul8u-min.kc Normal file
View File

@ -0,0 +1,14 @@
// Minimal test of mul8u
import "multiply"
void main() {
const word* screen = 0x0400;
byte i = 0;
for(byte a: 0..5)
for (byte b: 0..5)
screen[i++] = mul8u(a,b);
}

View File

@ -19,7 +19,7 @@ main: {
ldx #yd/2
lda #x0
sta x
lda #<0
lda #0
sta idx
sta idx+1
b1:

View File

@ -205,7 +205,7 @@ gfx_init_chunky: {
lda #>$4000
sta gfxb+1
b1:
lda #<0
lda #0
sta x
sta x+1
b2:

View File

@ -85,9 +85,8 @@ main: {
sta DTV_BLITTER_SRCA_HI
sta DTV_BLITTER_SRCA_MOD_LO
sta DTV_BLITTER_SRCA_MOD_HI
lda #<$80
sta DTV_BLITTER_SRCA_LIN_LO
lda #0
lda #>$100
sta DTV_BLITTER_SRCA_LIN_HI
lda #$10
sta DTV_BLITTER_SRCA_STEP

View File

@ -214,11 +214,8 @@ main: {
sta level
sta score_bcd
sta score_bcd+1
lda #<0>>$10
sta score_bcd+2
lda #>0>>$10
sta score_bcd+3
lda #<0
sta lines_bcd
sta lines_bcd+1
sta current_movedown_counter

View File

@ -6,7 +6,7 @@ main: {
.label screen = $400
.label i = 2
.label _1 = 4
lda #<0
lda #0
sta i
sta i+1
b1:

View File

@ -240,9 +240,9 @@ mulf_init: {
.label val = 6
.label sqr = 2
.label add = 4
lda #<1
lda #1
sta add
lda #>1
lda #0
sta add+1
tax
sta sqr

View File

@ -312,11 +312,10 @@ mul8u: {
.label mb = $b
.label res = 9
.label return = 9
lda #<b
lda #b
sta mb
lda #>b
lda #0
sta mb+1
lda #<0
sta res
sta res+1
b1:

View File

@ -307,7 +307,7 @@ sid_rnd_init: {
fillscreen: {
.label screen = 2
.label i = 4
lda #<0
lda #0
sta i
sta i+1
b1:

View File

@ -219,11 +219,11 @@ init: {
lda #VIC_DEN|VIC_RSEL|3
sta D011
jsr plexInit
lda #<$20
lda #$20
sta xp
lda #>$20
lda #0
sta xp+1
ldx #0
tax
b1:
lda #SPRITE/$40
sta PLEX_PTR,x

View File

@ -254,7 +254,7 @@ makecharset: {
sta print_char_cursor
lda #>print_line_cursor
sta print_char_cursor+1
lda #<0
lda #0
sta c
sta c+1
b1:

View File

@ -190,7 +190,7 @@ makecharset: {
sta print_char_cursor
lda #>print_line_cursor
sta print_char_cursor+1
lda #<0
lda #0
sta c
sta c+1
b1:

View File

@ -258,7 +258,7 @@ mulf_init: {
sta sqr1_lo
lda #>mulf_sqr1_lo+1
sta sqr1_lo+1
lda #<0
lda #0
sta sqr
sta sqr+1
tax

View File

@ -68,7 +68,7 @@ loop: {
.label _1 = 9
.label _5 = 9
.label xpos = 9
lda #<0
lda #0
sta xsin_idx
sta xsin_idx+1
b1:
@ -109,7 +109,7 @@ loop: {
lda xsin_idx
cmp #<XSIN_SIZE
bne b4
lda #<0
lda #0
sta xsin_idx
sta xsin_idx+1
b4:
@ -260,19 +260,17 @@ sin16s_gen2: {
.label x = 5
.label i = 9
jsr div32u16u
lda #<0
lda #0
sta i
sta i+1
lda #<xsin
sta sintab
lda #>xsin
sta sintab+1
lda #<0
lda #0
sta x
sta x+1
lda #<0>>$10
sta x+2
lda #>0>>$10
sta x+3
// u[4.28]
b1:
@ -332,13 +330,13 @@ sin16s_gen2: {
}
// Multiply of two signed words to a signed double word
// Fixes offsets introduced by using unsigned multiplication
// mul16s(signed word zeropage($15) a)
// mul16s(signed word zeropage($f) a)
mul16s: {
.label _9 = $f
.label _16 = $f
.label m = $b
.label return = $b
.label a = $15
.label a = $f
lda a
sta mul16u.a
lda a+1
@ -373,19 +371,17 @@ mul16s: {
rts
}
// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word
// mul16u(word zeropage($f) a, word zeropage($17) b)
// mul16u(word zeropage($11) a, word zeropage($f) b)
mul16u: {
.label mb = $11
.label a = $f
.label mb = $13
.label a = $11
.label res = $b
.label return = $b
.label b = $17
lda #<0
.label b = $f
lda #0
sta res
sta res+1
lda #<0>>$10
sta res+2
lda #>0>>$10
sta res+3
b1:
lda a
@ -427,18 +423,18 @@ mul16u: {
// sin16s(dword zeropage($b) x)
sin16s: {
.label _4 = $b
.label _20 = $15
.label _20 = $f
.label x = $b
.label return = $15
.label return = $f
.label x1 = $1d
.label x2 = $15
.label x3 = $15
.label x2 = $17
.label x3 = $17
.label x3_6 = $f
.label usinx = $1f
.label x4 = $15
.label x4 = $17
.label x5 = $f
.label x5_128 = $f
.label sinx = $15
.label sinx = $f
.label isUpper = 4
lda x+3
cmp #>PI_u4f28>>$10
@ -609,15 +605,15 @@ sin16s: {
}
// Calculate val*val for two unsigned word values - the result is 16 selected bits of the 32-bit result.
// The select parameter indicates how many of the highest bits of the 32-bit result to skip
// mulu16_sel(word zeropage($15) v1, word zeropage($17) v2, byte register(X) select)
// mulu16_sel(word zeropage($17) v1, word zeropage($f) v2, byte register(X) select)
mulu16_sel: {
.label _0 = $b
.label _1 = $b
.label v1 = $15
.label v2 = $17
.label v1 = $17
.label v2 = $f
.label return = $f
.label return_1 = $15
.label return_10 = $15
.label return_1 = $17
.label return_10 = $17
lda v1
sta mul16u.a
lda v1+1
@ -649,14 +645,14 @@ mulu16_sel: {
// Divide unsigned 32-bit dword dividend with a 16-bit word divisor
// The 16-bit word remainder can be found in rem16u after the division
div32u16u: {
.label quotient_hi = $15
.label quotient_hi = $11
.label quotient_lo = $f
.label return = $19
lda #<PI2_u4f28>>$10
sta divr16u.dividend
lda #>PI2_u4f28>>$10
sta divr16u.dividend+1
lda #<0
lda #0
sta divr16u.rem
sta divr16u.rem+1
jsr divr16u

View File

@ -73,7 +73,7 @@ render_sine: {
.label sin2_val = 6
.label xpos = 4
.label sin_idx = 2
lda #<0
lda #0
sta xpos
sta xpos+1
sta sin_idx
@ -149,7 +149,7 @@ render_sine: {
lda xpos
cmp #<$140
bne b2
lda #<0
lda #0
sta xpos
sta xpos+1
b2:
@ -174,9 +174,9 @@ render_sine: {
// Plot a single dot in the bitmap
// bitmap_plot(word zeropage(4) x, byte register(X) y)
bitmap_plot: {
.label _1 = $15
.label _1 = $10
.label plotter = 6
.label plotter_1 = $15
.label plotter_1 = $10
.label x = 4
.label _4 = 6
lda bitmap_plot_yhi,x
@ -256,19 +256,17 @@ sin16s_gen2: {
.label x = 8
.label i = 4
jsr div32u16u
lda #<0
lda #0
sta i
sta i+1
lda #<sin
sta sintab
lda #>sin
sta sintab+1
lda #<0
lda #0
sta x
sta x+1
lda #<0>>$10
sta x+2
lda #>0>>$10
sta x+3
// u[4.28]
b1:
@ -328,13 +326,13 @@ sin16s_gen2: {
}
// Multiply of two signed words to a signed double word
// Fixes offsets introduced by using unsigned multiplication
// mul16s(signed word zeropage($15) a)
// mul16s(signed word zeropage(6) a)
mul16s: {
.label _9 = 6
.label _16 = 6
.label m = $c
.label return = $c
.label a = $15
.label a = 6
lda a
sta mul16u.a
lda a+1
@ -369,19 +367,17 @@ mul16s: {
rts
}
// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word
// mul16u(word zeropage(6) a, word zeropage($17) b)
// mul16u(word zeropage($10) a, word zeropage(6) b)
mul16u: {
.label mb = $10
.label a = 6
.label mb = $12
.label a = $10
.label res = $c
.label return = $c
.label b = $17
lda #<0
.label b = 6
lda #0
sta res
sta res+1
lda #<0>>$10
sta res+2
lda #>0>>$10
sta res+3
b1:
lda a
@ -423,19 +419,19 @@ mul16u: {
// sin16s(dword zeropage($c) x)
sin16s: {
.label _4 = $c
.label _20 = $15
.label _20 = 6
.label x = $c
.label return = $15
.label return = 6
.label x1 = $1d
.label x2 = $15
.label x3 = $15
.label x2 = $17
.label x3 = $17
.label x3_6 = 6
.label usinx = $1f
.label x4 = $15
.label x4 = $17
.label x5 = 6
.label x5_128 = 6
.label sinx = $15
.label isUpper = $14
.label sinx = 6
.label isUpper = $16
lda x+3
cmp #>PI_u4f28>>$10
bcc b4
@ -605,15 +601,15 @@ sin16s: {
}
// Calculate val*val for two unsigned word values - the result is 16 selected bits of the 32-bit result.
// The select parameter indicates how many of the highest bits of the 32-bit result to skip
// mulu16_sel(word zeropage($15) v1, word zeropage($17) v2, byte register(X) select)
// mulu16_sel(word zeropage($17) v1, word zeropage(6) v2, byte register(X) select)
mulu16_sel: {
.label _0 = $c
.label _1 = $c
.label v1 = $15
.label v2 = $17
.label v1 = $17
.label v2 = 6
.label return = 6
.label return_1 = $15
.label return_10 = $15
.label return_1 = $17
.label return_10 = $17
lda v1
sta mul16u.a
lda v1+1
@ -645,14 +641,14 @@ mulu16_sel: {
// Divide unsigned 32-bit dword dividend with a 16-bit word divisor
// The 16-bit word remainder can be found in rem16u after the division
div32u16u: {
.label quotient_hi = $15
.label quotient_hi = $10
.label quotient_lo = 6
.label return = $19
lda #<PI2_u4f28>>$10
sta divr16u.dividend
lda #>PI2_u4f28>>$10
sta divr16u.dividend+1
lda #<0
lda #0
sta divr16u.rem
sta divr16u.rem+1
jsr divr16u
@ -732,7 +728,7 @@ divr16u: {
// Clear all graphics on the bitmap
bitmap_clear: {
.label bitmap = 2
.label y = $14
.label y = $16
.label _4 = 2
lda bitmap_plot_ylo
sta _4
@ -761,7 +757,7 @@ bitmap_clear: {
}
// Initialize bitmap plotting tables
bitmap_init: {
.label _3 = $14
.label _3 = $16
.label yoffs = 2
ldx #0
lda #$80

View File

@ -228,9 +228,9 @@ gen_sintab: {
lda #>f_amp
sta setMEMtoFAC.mem+1
jsr setMEMtoFAC
lda #<2
lda #2
sta setFAC.w
lda #>2
lda #0
sta setFAC.w+1
jsr setFAC
lda #<f_amp

View File

@ -5,7 +5,7 @@ main: {
.label SCREEN = $400
.label w = 2
.label sw = 2
lda #<0
lda #0
sta w
sta w+1
b1:

View File

@ -8,17 +8,15 @@ main: {
.label screen = $400
.label _0 = 2
.label _1 = 2
lda #<$a
lda #$a
sta mul16u.a
lda #>$a
lda #0
sta mul16u.a+1
lda #<$a
lda #$a
sta mul16u.mb
lda #>$a
lda #0
sta mul16u.mb+1
lda #<$a>>$10
sta mul16u.mb+2
lda #>$a>>$10
sta mul16u.mb+3
jsr mul16u
lda _0

View File

@ -38,7 +38,7 @@ main: {
sta lin16u_gen.lintab
lda #>lintab3
sta lin16u_gen.lintab+1
lda #<0
lda #0
sta lin16u_gen.min
sta lin16u_gen.min+1
lda #<$6488
@ -76,7 +76,7 @@ main: {
lda #>str1
sta print_str.str+1
jsr print_str
lda #<0
lda #0
sta print_word.w
sta print_word.w+1
jsr print_word
@ -309,11 +309,10 @@ lin16u_gen: {
lda ampl+1
sbc min+1
sta ampl+1
lda #<$14-1
lda #$14-1
sta divr16u.divisor
lda #>$14-1
lda #0
sta divr16u.divisor+1
lda #<0
sta divr16u.rem
sta divr16u.rem+1
jsr divr16u
@ -321,11 +320,10 @@ lin16u_gen: {
sta stepi
lda divr16u.return+1
sta stepi+1
lda #<$14-1
lda #$14-1
sta divr16u.divisor
lda #>$14-1
lda #0
sta divr16u.divisor+1
lda #<0
sta divr16u.dividend
sta divr16u.dividend+1
jsr divr16u
@ -344,7 +342,7 @@ lin16u_gen: {
sta val+2
lda min+1
sta val+3
lda #<0
lda #0
sta i
sta i+1
b1:

View File

@ -8,11 +8,11 @@
.label w2 = 2
main: {
.label SCREEN = $400
lda #<0
lda #0
sta w1
sta w1+1
jsr incw1
lda #<0
lda #0
sta w2
sta w2+1
jsr incw2

View File

@ -226,7 +226,7 @@ mulf_init: {
sta sqr1_lo
lda #>mulf_sqr1_lo+1
sta sqr1_lo+1
lda #<0
lda #0
sta sqr
sta sqr+1
tax

View File

@ -167,11 +167,11 @@ init: {
lda #VIC_DEN|VIC_RSEL|3
sta D011
jsr plexInit
lda #<$20
lda #$20
sta xp
lda #>$20
lda #0
sta xp+1
ldx #0
tax
b1:
lda #SPRITE/$40
sta PLEX_PTR,x

View File

@ -7,11 +7,11 @@
.label SPRITES_XMSB = $d010
main: {
.label xpos = 2
lda #<$c8
lda #$c8
sta xpos
lda #>$c8
lda #0
sta xpos+1
ldx #0
tax
b1:
stx position_sprite.spriteno
jsr position_sprite

View File

@ -76,6 +76,7 @@ draw_block: {
asl
sta x1
lda #0
rol
sta x1+1
txa
asl
@ -172,11 +173,10 @@ mul8u: {
.label mb = 6
.label res = 4
.label return = 4
lda #<b
lda #b
sta mb
lda #>b
lda #0
sta mb+1
lda #<0
sta res
sta res+1
b1:

View File

@ -730,11 +730,10 @@ mul8u: {
.label mb = 2
.label res = 8
.label return = 8
lda #<SIZEOF_ENTRY
lda #SIZEOF_ENTRY
sta mb
lda #>SIZEOF_ENTRY
lda #0
sta mb+1
lda #<0
sta res
sta res+1
b1:

View File

@ -25,22 +25,22 @@
.label yvel_22 = 6
main: {
jsr init
lda #<$64
lda #$64
sta yvel_init
lda #>$64
lda #0
sta yvel_init+1
lda #<$c8
sta xvel
lda #>$c8
sta xvel+1
lda #<0
lda #0
sta ypos
sta ypos+1
sta xpos
sta xpos+1
lda #<$64
lda #$64
sta yvel_12
lda #>$64
lda #0
sta yvel_12+1
b1:
lda #$ff
@ -96,7 +96,7 @@ anim: {
sta yvel_22
lda yvel+1
sta yvel_22+1
lda #<0
lda #0
sta ypos
sta ypos+1
sta xpos

View File

@ -46,9 +46,9 @@ main: {
lda #>f_i
sta setMEMtoFAC.mem+1
jsr setMEMtoFAC
lda #<$19
lda #$19
sta setFAC.w
lda #>$19
lda #0
sta setFAC.w+1
jsr setFAC
jsr divMEMbyFAC

View File

@ -185,19 +185,17 @@ sin16s_gen: {
.label x = $a
.label i = 4
jsr div32u16u
lda #<0
lda #0
sta i
sta i+1
lda #<main.sintab1
sta sintab
lda #>main.sintab1
sta sintab+1
lda #<0
lda #0
sta x
sta x+1
lda #<0>>$10
sta x+2
lda #>0>>$10
sta x+3
// u[4.28]
b1:
@ -485,9 +483,7 @@ mul16u: {
sta mb+3
sta res
sta res+1
lda #<0>>$10
sta res+2
lda #>0>>$10
sta res+3
b1:
lda a
@ -533,7 +529,7 @@ div32u16u: {
sta divr16u.dividend
lda #>PI2_u4f28>>$10
sta divr16u.dividend+1
lda #<0
lda #0
sta divr16u.rem
sta divr16u.rem+1
jsr divr16u

View File

@ -204,19 +204,17 @@ sin16s_genb: {
.label x = $d
.label i = 4
jsr div32u16u
lda #<0
lda #0
sta i
sta i+1
lda #<main.sintab2
sta sintab
lda #>main.sintab2
sta sintab+1
lda #<0
lda #0
sta x
sta x+1
lda #<0>>$10
sta x+2
lda #>0>>$10
sta x+3
// u[4.28]
b1:
@ -469,9 +467,7 @@ mul16u: {
sta mb+3
sta res
sta res+1
lda #<0>>$10
sta res+2
lda #>0>>$10
sta res+3
b1:
lda a
@ -517,7 +513,7 @@ div32u16u: {
sta divr16u.dividend
lda #>PI2_u4f28>>$10
sta divr16u.dividend+1
lda #<0
lda #0
sta divr16u.rem
sta divr16u.rem+1
jsr divr16u
@ -605,19 +601,17 @@ sin16s_gen: {
.label x = $d
.label i = 4
jsr div32u16u
lda #<0
lda #0
sta i
sta i+1
lda #<main.sintab1
sta sintab
lda #>main.sintab1
sta sintab+1
lda #<0
lda #0
sta x
sta x+1
lda #<0>>$10
sta x+2
lda #>0>>$10
sta x+3
// u[4.28]
b1:

View File

@ -158,14 +158,14 @@ sin8s_gen: {
.label x = 2
.label i = 7
jsr div16u
lda #<0
lda #0
sta i
sta i+1
lda #<main.sintab2
sta sintab
lda #>main.sintab2
sta sintab+1
lda #<0
lda #0
sta x
sta x+1
// u[4.12]

View File

@ -181,19 +181,17 @@ sin16s_gen: {
.label x = 7
.label i = 5
jsr div32u16u
lda #<0
lda #0
sta i
sta i+1
lda #<main.sintabw
sta sintab
lda #>main.sintabw
sta sintab+1
lda #<0
lda #0
sta x
sta x+1
lda #<0>>$10
sta x+2
lda #>0>>$10
sta x+3
// u[4.28]
b1:
@ -481,9 +479,7 @@ mul16u: {
sta mb+3
sta res
sta res+1
lda #<0>>$10
sta res+2
lda #>0>>$10
sta res+3
b1:
lda a
@ -529,7 +525,7 @@ div32u16u: {
sta divr16u.dividend
lda #>PI2_u4f28>>$10
sta divr16u.dividend+1
lda #<0
lda #0
sta divr16u.rem
sta divr16u.rem+1
jsr divr16u
@ -616,14 +612,14 @@ sin8s_gen: {
.label x = 2
.label i = $11
jsr div16u
lda #<0
lda #0
sta i
sta i+1
lda #<main.sintabb
sta sintab
lda #>main.sintabb
sta sintab+1
lda #<0
lda #0
sta x
sta x+1
// u[4.12]
@ -839,7 +835,7 @@ div16u: {
sta divr16u.dividend
lda #>PI2_u4f12
sta divr16u.dividend+1
lda #<0
lda #0
sta divr16u.rem
sta divr16u.rem+1
jsr divr16u

View File

@ -86,14 +86,14 @@ sin8u_table: {
lda #>$400
sta print_line_cursor+1
jsr print_ln
lda #<0
lda #0
sta i
sta i+1
lda #<main.sintab
sta sintab
lda #>main.sintab
sta sintab+1
lda #<0
lda #0
sta x
sta x+1
// u[4.12]
@ -326,9 +326,9 @@ mul8su: {
.label return = $f
tya
tax
lda #<b
lda #b
sta mul8u.mb
lda #>b
lda #0
sta mul8u.mb+1
jsr mul8u
cpy #0
@ -346,7 +346,7 @@ mul8u: {
.label mb = $b
.label res = $f
.label return = $f
lda #<0
lda #0
sta res
sta res+1
b1:

View File

@ -601,20 +601,18 @@ mul16s: {
rts
}
// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word
// mul16u(word zeropage(9) a, word zeropage($15) b)
// mul16u(word zeropage($1d) a, word zeropage(9) b)
mul16u: {
.label mb = $11
.label a = 9
.label a = $1d
.label res = $19
.label b = $15
.label b = 9
.label return = $19
.label b_1 = $17
lda #<0
lda #0
sta res
sta res+1
lda #<0>>$10
sta res+2
lda #>0>>$10
sta res+3
b1:
lda a
@ -667,14 +665,12 @@ muls16s: {
lda a
beq b5
!:
lda #<0
lda #0
sta j
sta j+1
sta m
sta m+1
lda #<0>>$10
sta m+2
lda #>0>>$10
sta m+3
b3:
lda b+1
@ -708,23 +704,19 @@ muls16s: {
bne b3
rts
b5:
lda #<0
lda #0
sta return
sta return+1
lda #<0>>$10
sta return+2
lda #>0>>$10
sta return+3
rts
b6:
lda #<0
lda #0
sta i
sta i+1
sta m
sta m+1
lda #<0>>$10
sta m+2
lda #>0>>$10
sta m+3
b4:
lda b+1
@ -965,14 +957,12 @@ muls16u: {
lda a+1
beq b3
!:
lda #<0
lda #0
sta i
sta i+1
sta m
sta m+1
lda #<0>>$10
sta m+2
lda #>0>>$10
sta m+3
b2:
lda m
@ -1000,12 +990,10 @@ muls16u: {
bne b2
rts
b3:
lda #<0
lda #0
sta return
sta return+1
lda #<0>>$10
sta return+2
lda #>0>>$10
sta return+3
rts
}
@ -1028,7 +1016,7 @@ mulf_init: {
sta sqr1_lo
lda #>mulf_sqr1_lo+1
sta sqr1_lo+1
lda #<0
lda #0
sta sqr
sta sqr+1
tax

View File

@ -307,7 +307,7 @@ mul8u: {
.label mb = 6
.label res = $c
.label return = $c
lda #<0
lda #0
sta res
sta res+1
b1:
@ -451,7 +451,7 @@ muls8s: {
bne b3
rts
b5:
lda #<0
lda #0
sta return
sta return+1
rts
@ -634,7 +634,7 @@ muls8u: {
bne b2
rts
b3:
lda #<0
lda #0
sta return
sta return+1
rts
@ -796,7 +796,7 @@ mulf_init: {
sta sqr1_lo
lda #>mulf_sqr1_lo+1
sta sqr1_lo+1
lda #<0
lda #0
sta sqr
sta sqr+1
tax

View File

@ -17,7 +17,7 @@ scrollup3: {
.label _4 = 7
.label _5 = 9
.label l2_4 = 4
lda #<0
lda #0
sta l2
sta l2+1
b1:
@ -111,7 +111,7 @@ scrollup1: {
.label line = 2
.label _6 = 7
.label _7 = 4
lda #<0
lda #0
sta line
sta line+1
b1:

View File

@ -10,7 +10,7 @@ main: {
.label _8 = 6
.label _9 = 4
.label _10 = 4
lda #<0
lda #0
sta line
sta line+1
b1: