mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-04-05 07:40:39 +00:00
Fixed negative numbers, zero-addition, zero inlining.
This commit is contained in:
parent
fe41c2ba42
commit
9cec38d075
@ -269,8 +269,12 @@ public class Compiler {
|
||||
optimizations.add(new Pass2SizeOfSimplification(program));
|
||||
optimizations.add(new Pass2InlineCast(program));
|
||||
optimizations.add(new PassNCastSimplification(program));
|
||||
optimizations.add(new PassNStatementIndices(program));
|
||||
optimizations.add(new PassNVariableReferenceInfos(program));
|
||||
optimizations.add(new Pass2InlineDerefIdx(program));
|
||||
optimizations.add(new Pass2DeInlineWordDerefIdx(program));
|
||||
optimizations.add(new PassNSimplifyConstantZero(program));
|
||||
optimizations.add(new PassNSimplifyExpressionWithZero(program));
|
||||
pass2Execute(optimizations);
|
||||
}
|
||||
|
||||
@ -319,6 +323,9 @@ public class Compiler {
|
||||
constantOptimizations.add(new Pass2ConstantIfs(program));
|
||||
constantOptimizations.add(new Pass2InlineDerefIdx(program));
|
||||
constantOptimizations.add(new PassNEliminateUnusedVars(program, true));
|
||||
constantOptimizations.add(new PassNSimplifyConstantZero(program));
|
||||
constantOptimizations.add(new PassNSimplifyExpressionWithZero(program));
|
||||
|
||||
|
||||
pass2Execute(constantOptimizations);
|
||||
|
||||
|
@ -231,7 +231,7 @@ public class AsmFormat {
|
||||
return SHORT_ASM_NUMBERS[number.intValue()];
|
||||
} else {
|
||||
if(number.longValue()<0) {
|
||||
return String.format("-$%x", -number.longValue());
|
||||
return "-"+getAsmNumber(-number.longValue());
|
||||
} else {
|
||||
return String.format("$%x", number.longValue());
|
||||
}
|
||||
|
@ -300,8 +300,7 @@ public class AsmFragmentInstance {
|
||||
@Override
|
||||
public AsmParameter visitAsmExprInt(KickCParser.AsmExprIntContext ctx) {
|
||||
Number number = NumberParser.parseLiteral(ctx.NUMBER().getText());
|
||||
ConstantInteger intVal = new ConstantInteger(number.longValue());
|
||||
boolean isZp = SymbolType.BYTE.equals(intVal.getType()) || SymbolType.SBYTE.equals(intVal.getType());
|
||||
boolean isZp = SymbolType.BYTE.contains(number.longValue()) || SymbolType.SBYTE.contains(number.longValue());
|
||||
String param = AsmFormat.getAsmNumber(number);
|
||||
return new AsmParameter(param, isZp);
|
||||
}
|
||||
|
@ -1,9 +1,6 @@
|
||||
package dk.camelot64.kickc.fragment;
|
||||
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.ControlFlowGraph;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.Registers;
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.operators.OperatorUnary;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
@ -17,6 +14,7 @@ import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.types.*;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.lang.InternalError;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -242,17 +240,32 @@ public class AsmFragmentInstanceSpecFactory {
|
||||
if(castType == null) {
|
||||
SymbolType toType = castVal.getToType();
|
||||
// If value literal not matching cast type then add expression code to transform it into the value space ( eg. value & 0xff )
|
||||
ConstantLiteral constantLiteral = val.calculateLiteral(program.getScope());
|
||||
if(constantLiteral instanceof ConstantInteger) {
|
||||
if(toType instanceof SymbolTypeIntegerFixed) {
|
||||
if(!((SymbolTypeIntegerFixed) toType).contains(((ConstantInteger) constantLiteral).getValue())) {
|
||||
if(toType.getSizeBytes() == 1) {
|
||||
val = new ConstantBinary(new ConstantInteger(0xffL, SymbolType.BYTE), Operators.BOOL_AND, val);
|
||||
} else if(toType.getSizeBytes() == 2) {
|
||||
val = new ConstantBinary(new ConstantInteger(0xffffL, SymbolType.WORD), Operators.BOOL_AND, val);
|
||||
} else {
|
||||
throw new InternalError("Not implemented!");
|
||||
}
|
||||
|
||||
if(toType instanceof SymbolTypeIntegerFixed) {
|
||||
SymbolTypeIntegerFixed integerFixed = (SymbolTypeIntegerFixed) toType;
|
||||
ConstantLiteral constantLiteral;
|
||||
Long integerValue;
|
||||
try {
|
||||
constantLiteral = val.calculateLiteral(program.getScope());
|
||||
if(constantLiteral instanceof ConstantInteger) {
|
||||
integerValue = ((ConstantInteger) constantLiteral).getValue();
|
||||
} else if(constantLiteral instanceof ConstantPointer) {
|
||||
integerValue = ((ConstantPointer) constantLiteral).getValue();
|
||||
} else {
|
||||
throw new InternalError("Not implemented "+constantLiteral);
|
||||
}
|
||||
} catch (ConstantNotLiteral e) {
|
||||
// Assume it is a word
|
||||
integerValue = 0xffffL;
|
||||
}
|
||||
|
||||
if(!integerFixed.contains(integerValue)) {
|
||||
if(toType.getSizeBytes() == 1) {
|
||||
val = new ConstantBinary(new ConstantInteger(0xffL, SymbolType.BYTE), Operators.BOOL_AND, val);
|
||||
} else if(toType.getSizeBytes() == 2) {
|
||||
val = new ConstantBinary(new ConstantInteger(0xffffL, SymbolType.WORD), Operators.BOOL_AND, val);
|
||||
} else {
|
||||
throw new InternalError("Not implemented "+toType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,10 @@ public class OperatorBitwiseAnd extends OperatorBinary {
|
||||
}
|
||||
// Handle numeric types
|
||||
if(SymbolType.isInteger(type1) && SymbolType.isInteger(type2)) {
|
||||
return SymbolTypeConversion.convertedMathType((SymbolTypeInteger) type1, (SymbolTypeInteger) type2);
|
||||
if(type1.getSizeBytes()<type2.getSizeBytes())
|
||||
return type1;
|
||||
else
|
||||
return type2;
|
||||
}
|
||||
|
||||
throw new CompileError("Type inference case not handled " + type1 + " " + getOperator() + " " + type2);
|
||||
|
@ -26,6 +26,10 @@ public class OperatorGetHigh extends OperatorUnary {
|
||||
return new ConstantInteger(operandInt.getInteger()>>8);
|
||||
} else if(SymbolType.DWORD.equals(operandInt.getType()) || SymbolType.SDWORD.equals(operandInt.getType())) {
|
||||
return new ConstantInteger(operandInt.getInteger()>>16);
|
||||
} else if(SymbolType.BYTE.equals(operandInt.getType()) || SymbolType.SBYTE.equals(operandInt.getType())) {
|
||||
return new ConstantInteger(0L, SymbolType.BYTE);
|
||||
} else if(SymbolType.NUMBER.equals(operandInt.getType())) {
|
||||
throw new ConstantNotLiteral("Operand not resolved "+operand);
|
||||
}
|
||||
} else if(operand instanceof ConstantPointer) {
|
||||
return new ConstantInteger(((ConstantPointer) operand).getLocation()>>8);
|
||||
@ -41,6 +45,8 @@ public class OperatorGetHigh extends OperatorUnary {
|
||||
return SymbolType.BYTE;
|
||||
} else if(SymbolType.DWORD.equals(operandType) || SymbolType.SDWORD.equals(operandType)) {
|
||||
return SymbolType.WORD;
|
||||
} else if(SymbolType.BYTE.equals(operandType) || SymbolType.SBYTE.equals(operandType)) {
|
||||
return SymbolType.BYTE;
|
||||
} else if(SymbolType.STRING.equals(operandType)) {
|
||||
return SymbolType.BYTE;
|
||||
} else if(SymbolType.NUMBER.equals(operandType)) {
|
||||
|
@ -26,13 +26,17 @@ public class OperatorGetLow extends OperatorUnary {
|
||||
return new ConstantInteger(operandInt.getInteger()&0xff);
|
||||
} else if(SymbolType.DWORD.equals(operandInt.getType()) || SymbolType.SDWORD.equals(operandInt.getType())) {
|
||||
return new ConstantInteger(operandInt.getInteger()&0xffff);
|
||||
} else if(SymbolType.BYTE.equals(operandInt.getType()) || SymbolType.SBYTE.equals(operandInt.getType())) {
|
||||
return operandInt;
|
||||
} else if(SymbolType.NUMBER.equals(operandInt.getType())) {
|
||||
throw new ConstantNotLiteral("Operand not resolved "+operand);
|
||||
}
|
||||
} else if(operand instanceof ConstantPointer) {
|
||||
return new ConstantInteger(((ConstantPointer) operand).getLocation()&0xff);
|
||||
} else if(operand instanceof ConstantString) {
|
||||
throw new ConstantNotLiteral("address of string is not literal");
|
||||
}
|
||||
throw new CompileError("Calculation not implemented " + getOperator() + " " + operand );
|
||||
throw new ConstantNotLiteral("Calculation not implemented " + getOperator() + " " + operand );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,6 +45,8 @@ public class OperatorGetLow extends OperatorUnary {
|
||||
return SymbolType.BYTE;
|
||||
} else if(SymbolType.DWORD.equals(operandType) || SymbolType.SDWORD.equals(operandType)) {
|
||||
return SymbolType.WORD;
|
||||
} else if(SymbolType.BYTE.equals(operandType) || SymbolType.SBYTE.equals(operandType)) {
|
||||
return SymbolType.BYTE;
|
||||
} else if(SymbolType.STRING.equals(operandType)) {
|
||||
return SymbolType.BYTE;
|
||||
} else if(SymbolType.NUMBER.equals(operandType)) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package dk.camelot64.kickc.model.types;
|
||||
|
||||
import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.ConstantNotLiteral;
|
||||
import dk.camelot64.kickc.model.InternalError;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
@ -103,7 +104,13 @@ public class SymbolTypeConversion {
|
||||
|
||||
// Find the cast type if possible
|
||||
if(numberVal instanceof ConstantValue) {
|
||||
ConstantLiteral constantLiteral = ((ConstantValue) numberVal).calculateLiteral(symbols);
|
||||
ConstantLiteral constantLiteral;
|
||||
try {
|
||||
constantLiteral = ((ConstantValue) numberVal).calculateLiteral(symbols);
|
||||
} catch( ConstantNotLiteral e) {
|
||||
// Postpone til later!
|
||||
return null;
|
||||
}
|
||||
if(constantLiteral instanceof ConstantInteger) {
|
||||
ConstantInteger constantInteger = (ConstantInteger) constantLiteral;
|
||||
if(SymbolType.NUMBER.equals(constantInteger.getType())) {
|
||||
@ -161,7 +168,11 @@ public class SymbolTypeConversion {
|
||||
if(lValueType.equals(SymbolType.SDWORD) && rValueType.equals(SymbolType.SWORD))
|
||||
return true;
|
||||
if(SymbolType.NUMBER.equals(rValueType) && SymbolType.isInteger(lValueType)) {
|
||||
// L-value is still a number - constants are probably not done being identified & typed
|
||||
// R-value is still a number - constants are probably not done being identified & typed
|
||||
return true;
|
||||
}
|
||||
if(SymbolType.NUMBER.equals(lValueType) && SymbolType.isInteger(rValueType)) {
|
||||
// R-value is still a number - constants are probably not done being identified & typed
|
||||
return true;
|
||||
}
|
||||
if(SymbolType.STRING.equals(rValueType) && lValueType instanceof SymbolTypePointer && ((SymbolTypePointer) lValueType).getElementType().equals(SymbolType.BYTE)) {
|
||||
|
@ -12,6 +12,7 @@ import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/** Identify derefs of pointers that are defined as pointer + value - and inline them as derefidx instead */
|
||||
@ -71,6 +72,11 @@ public class Pass2InlineDerefIdx extends Pass2SsaOptimization {
|
||||
|
||||
|
||||
public RValue attemptInlineDeref(StatementAssignment derefAssignment) {
|
||||
VariableRef derefVar = (VariableRef) derefAssignment.getlValue();
|
||||
Collection<Integer> varUseStatements = getProgram().getVariableReferenceInfos().getVarUseStatements(derefVar);
|
||||
if(varUseStatements.size()>2) {
|
||||
return null;
|
||||
}
|
||||
if(Operators.PLUS.equals(derefAssignment.getOperator())) {
|
||||
SymbolType derefLeftType = SymbolTypeInference.inferType(getScope(), derefAssignment.getrValue1());
|
||||
if(derefLeftType instanceof SymbolTypePointer) {
|
||||
|
@ -18,12 +18,7 @@ public class Pass4RegisterUpliftRemains extends Pass2Base {
|
||||
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));
|
||||
}
|
||||
});
|
||||
Collections.sort(equivalenceClasses, (o1, o2) -> Double.compare(registerWeights.getTotalWeight(o2), registerWeights.getTotalWeight(o1)));
|
||||
|
||||
Set<String> unknownFragments = new LinkedHashSet<>();
|
||||
|
||||
|
@ -0,0 +1,44 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.ConstantNotLiteral;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Simplify any constant expression evaluating to zero
|
||||
*/
|
||||
public class PassNSimplifyConstantZero extends Pass2SsaOptimization {
|
||||
|
||||
public PassNSimplifyConstantZero(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean step() {
|
||||
AtomicBoolean modified = new AtomicBoolean(false);
|
||||
|
||||
ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
Value value = programValue.get();
|
||||
if(value instanceof ConstantValue && !(value instanceof ConstantInteger) &&!(value instanceof ConstantRef)) {
|
||||
ConstantLiteral literal;
|
||||
try {
|
||||
literal = ((ConstantValue) value).calculateLiteral(getProgram().getScope());
|
||||
} catch( ConstantNotLiteral e) {
|
||||
return;
|
||||
}
|
||||
if(literal instanceof ConstantInteger) {
|
||||
if(((ConstantInteger) literal).getInteger()==0L) {
|
||||
getLog().append("Simplifying constant evaluating to zero "+value.toString(getProgram()) + " in "+(currentStmt==null?"":currentStmt.toString(getProgram(), false)));
|
||||
programValue.set(new ConstantInteger(0L, ((ConstantInteger) literal).getType()));
|
||||
modified.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return modified.get();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
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.Operator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||
import dk.camelot64.kickc.model.values.PointerDereferenceSimple;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Simplify any binary expression containing a zero value (if possible
|
||||
*/
|
||||
public class PassNSimplifyExpressionWithZero extends Pass2SsaOptimization {
|
||||
|
||||
public PassNSimplifyExpressionWithZero(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean step() {
|
||||
AtomicBoolean modified = new AtomicBoolean(false);
|
||||
|
||||
ProgramExpressionIterator.execute(getProgram(), (programExpression, currentStmt, stmtIt, currentBlock) -> {
|
||||
if(programExpression instanceof ProgramExpressionBinary) {
|
||||
ProgramExpressionBinary binary = (ProgramExpressionBinary) programExpression;
|
||||
RValue left = binary.getLeft();
|
||||
RValue right = binary.getRight();
|
||||
Operator operator = programExpression.getOperator();
|
||||
if(Operators.PLUS.equals(operator) || Operators.MINUS.equals(operator) || Operators.BOOL_OR.equals(operator) || Operators.BOOL_XOR.equals(operator)) {
|
||||
if(left instanceof ConstantInteger && ((ConstantInteger) left).getInteger() == 0) {
|
||||
getLog().append("Simplifying expression containing zero " + binary.getRight().toString()+ " in "+ (currentStmt==null?"":currentStmt.toString(getProgram(), false)));
|
||||
if(programExpression instanceof ProgramExpressionBinary.ProgramExpressionBinaryPointerDereferenceIndexed) {
|
||||
programExpression.set(new PointerDereferenceSimple(binary.getRight()));
|
||||
} else {
|
||||
programExpression.set(binary.getRight());
|
||||
}
|
||||
modified.set(true);
|
||||
} else if(right instanceof ConstantInteger && ((ConstantInteger) right).getInteger() == 0) {
|
||||
getLog().append("Simplifying expression containing zero " + binary.getLeft().toString()+ " in "+ (currentStmt==null?"":currentStmt.toString(getProgram(), false)));
|
||||
if(programExpression instanceof ProgramExpressionBinary.ProgramExpressionBinaryPointerDereferenceIndexed) {
|
||||
programExpression.set(new PointerDereferenceSimple(binary.getLeft()));
|
||||
} else {
|
||||
programExpression.set(binary.getLeft());
|
||||
}
|
||||
modified.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return modified.get();
|
||||
}
|
||||
|
||||
}
|
@ -63,6 +63,11 @@ public class TestPrograms {
|
||||
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testGfxBankOptimization() throws IOException, URISyntaxException {
|
||||
compileAndCompare("gfxbank");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoubleIndexingArrays() throws IOException, URISyntaxException {
|
||||
compileAndCompare("double-indexing-arrays");
|
||||
@ -1743,7 +1748,7 @@ public class TestPrograms {
|
||||
|
||||
@Test
|
||||
public void testForClassicMin() throws IOException, URISyntaxException {
|
||||
compileAndCompare("forclassicmin", log());
|
||||
compileAndCompare("forclassicmin");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -12,7 +12,7 @@ const word SIN_SIZE = 512;
|
||||
|
||||
signed word[512] align($100) sin;
|
||||
|
||||
signed word* sin2 = $1500;
|
||||
signed word* sin2 = $1400;
|
||||
|
||||
kickasm(pc sin2) {{
|
||||
.for(var i=0; i<512; i++) {
|
||||
|
8
src/test/kc/gfxbank.kc
Normal file
8
src/test/kc/gfxbank.kc
Normal file
@ -0,0 +1,8 @@
|
||||
// Test minimization of constants
|
||||
|
||||
import "c64"
|
||||
|
||||
void main() {
|
||||
const byte* PLAYFIELD_CHARSET = $2800;
|
||||
vicSelectGfxBank(PLAYFIELD_CHARSET);
|
||||
}
|
@ -19,9 +19,8 @@ main: {
|
||||
ldx #yd/2
|
||||
lda #x0
|
||||
sta x
|
||||
lda #x0+y0*$28
|
||||
lda #<0
|
||||
sta idx
|
||||
lda #0
|
||||
sta idx+1
|
||||
b1:
|
||||
lda idx
|
||||
|
@ -77,7 +77,7 @@ main: {
|
||||
lda #VIC_MCM|VIC_CSEL
|
||||
sta VIC_CONTROL2
|
||||
// Plane A: SCREEN
|
||||
lda #<SCREEN
|
||||
lda #0
|
||||
sta DTV_PLANEA_START_LO
|
||||
lda #>SCREEN
|
||||
sta DTV_PLANEA_START_MI
|
||||
@ -89,7 +89,6 @@ main: {
|
||||
sta DTV_PLANEA_MODULO_LO
|
||||
sta DTV_PLANEA_MODULO_HI
|
||||
// Plane B: CHARSET8
|
||||
lda #<CHARSET8
|
||||
sta DTV_PLANEB_START_LO
|
||||
lda #>CHARSET8
|
||||
sta DTV_PLANEB_START_MI
|
||||
@ -233,9 +232,9 @@ gfx_init_plane_charset8: {
|
||||
lda #0
|
||||
sta ch
|
||||
sta col
|
||||
lda #<$4000+(CHARSET8&$3fff)
|
||||
lda #<$4000
|
||||
sta gfxa
|
||||
lda #>$4000+(CHARSET8&$3fff)
|
||||
lda #>$4000
|
||||
sta gfxa+1
|
||||
lda #<CHARGEN+1
|
||||
sta chargen
|
||||
|
@ -65,7 +65,7 @@ main: {
|
||||
lda #VIC_MCM|VIC_CSEL
|
||||
sta VIC_CONTROL2
|
||||
// Plane B: CHUNKY
|
||||
lda #<CHUNKY
|
||||
lda #0
|
||||
sta DTV_PLANEB_START_LO
|
||||
lda #>CHUNKY
|
||||
sta DTV_PLANEB_START_MI
|
||||
@ -84,9 +84,9 @@ main: {
|
||||
sta CIA2_PORT_A
|
||||
// Set VIC Bank
|
||||
// VIC memory
|
||||
lda #(CHUNKY&$3fff)/$40|(0)/4
|
||||
lda #0
|
||||
sta VIC_MEMORY
|
||||
ldx #0
|
||||
tax
|
||||
// DTV Palette - Grey Tones
|
||||
b1:
|
||||
txa
|
||||
@ -195,7 +195,7 @@ gfx_init_chunky: {
|
||||
.label gfxb = 5
|
||||
.label x = 3
|
||||
.label y = 2
|
||||
lda #$ff&CHUNKY/$4000
|
||||
lda #CHUNKY/$4000
|
||||
jsr dtvSetCpuBankSegment1
|
||||
ldx #($ff&CHUNKY/$4000)+1
|
||||
lda #0
|
||||
@ -205,7 +205,7 @@ gfx_init_chunky: {
|
||||
lda #>$4000
|
||||
sta gfxb+1
|
||||
b1:
|
||||
lda #0
|
||||
lda #<0
|
||||
sta x
|
||||
sta x+1
|
||||
b2:
|
||||
|
@ -85,9 +85,9 @@ main: {
|
||||
sta DTV_BLITTER_SRCA_HI
|
||||
sta DTV_BLITTER_SRCA_MOD_LO
|
||||
sta DTV_BLITTER_SRCA_MOD_HI
|
||||
lda #<$100
|
||||
lda #<$80
|
||||
sta DTV_BLITTER_SRCA_LIN_LO
|
||||
lda #>$100
|
||||
lda #0
|
||||
sta DTV_BLITTER_SRCA_LIN_HI
|
||||
lda #$10
|
||||
sta DTV_BLITTER_SRCA_STEP
|
||||
@ -100,14 +100,12 @@ main: {
|
||||
sta DTV_BLITTER_SRCB_HI
|
||||
sta DTV_BLITTER_SRCB_MOD_LO
|
||||
sta DTV_BLITTER_SRCB_MOD_HI
|
||||
lda #<$100
|
||||
sta DTV_BLITTER_SRCB_LIN_LO
|
||||
lda #>$100
|
||||
sta DTV_BLITTER_SRCB_LIN_HI
|
||||
lda #0
|
||||
sta DTV_BLITTER_SRCB_STEP
|
||||
// Step 0.0
|
||||
lda #<SCREEN
|
||||
sta DTV_BLITTER_DEST_LO
|
||||
lda #>SCREEN
|
||||
sta DTV_BLITTER_DEST_MI
|
||||
@ -115,7 +113,6 @@ main: {
|
||||
sta DTV_BLITTER_DEST_HI
|
||||
sta DTV_BLITTER_DEST_MOD_LO
|
||||
sta DTV_BLITTER_DEST_MOD_HI
|
||||
lda #<$100
|
||||
sta DTV_BLITTER_DEST_LIN_LO
|
||||
lda #>$100
|
||||
sta DTV_BLITTER_DEST_LIN_HI
|
||||
|
@ -2,14 +2,12 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const SIZEOF_POINTER = 2
|
||||
main: {
|
||||
.const getScreen1_id = 0
|
||||
.label getScreen1_return = 2
|
||||
.label spritePtr1_return = 2
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER
|
||||
lda screens
|
||||
sta getScreen1_return
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER+1
|
||||
lda screens+1
|
||||
sta getScreen1_return+1
|
||||
clc
|
||||
lda spritePtr1_return
|
||||
|
@ -2,15 +2,13 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const SIZEOF_POINTER = 2
|
||||
main: {
|
||||
.label DSP = $400
|
||||
.const getScreen1_id = 0
|
||||
.label getScreen1_return = 2
|
||||
.label spritePtr1__0 = 2
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER
|
||||
lda screens
|
||||
sta getScreen1_return
|
||||
lda screens+getScreen1_id*SIZEOF_POINTER+1
|
||||
lda screens+1
|
||||
sta getScreen1_return+1
|
||||
clc
|
||||
lda spritePtr1__0
|
||||
|
@ -7,8 +7,8 @@ main: {
|
||||
.const min = $a
|
||||
.const max = $c8
|
||||
.label BGCOL = $d021
|
||||
.const sumb = min+max
|
||||
.const sumw = min+max
|
||||
.const sumb = min+max
|
||||
.const midb = (sumb>>1)+1
|
||||
.const midw = (sumw>>1)+1
|
||||
lda #midw
|
||||
|
@ -84,7 +84,7 @@ bbegin:
|
||||
rts
|
||||
main: {
|
||||
.const toSpritePtr2_return = SIN_SPRITE/$40
|
||||
.const vicSelectGfxBank1_toDd001_return = 3^(>PLAYFIELD_SCREEN_1)/$40
|
||||
.const vicSelectGfxBank1_toDd001_return = 3
|
||||
.const toD0181_return = (>(PLAYFIELD_SCREEN_1&$3fff)*4)|(>PLAYFIELD_CHARSET)/4&$f
|
||||
.label xpos = 2
|
||||
.label ypos = 3
|
||||
|
@ -205,18 +205,20 @@ main: {
|
||||
ldx play_spawn_current.piece_idx
|
||||
lda #$20
|
||||
jsr render_next
|
||||
ldy play_spawn_current._7
|
||||
lda PIECES,y
|
||||
lda current_piece_gfx
|
||||
sta current_piece
|
||||
lda PIECES+1,y
|
||||
lda current_piece_gfx+1
|
||||
sta current_piece+1
|
||||
lda #0
|
||||
sta level_bcd
|
||||
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
|
||||
@ -308,16 +310,16 @@ render_score: {
|
||||
jsr render_bcd
|
||||
ldx score_bytes+1
|
||||
ldy #0
|
||||
lda #score_offset+2
|
||||
lda #<score_offset+2
|
||||
sta render_bcd.offset
|
||||
tya
|
||||
lda #>score_offset+2
|
||||
sta render_bcd.offset+1
|
||||
jsr render_bcd
|
||||
ldx score_bytes
|
||||
ldy #0
|
||||
lda #score_offset+4
|
||||
lda #<score_offset+4
|
||||
sta render_bcd.offset
|
||||
tya
|
||||
lda #>score_offset+4
|
||||
sta render_bcd.offset+1
|
||||
jsr render_bcd
|
||||
lda lines_bcd+1
|
||||
@ -331,9 +333,9 @@ render_score: {
|
||||
lda lines_bcd
|
||||
tax
|
||||
ldy #0
|
||||
lda #lines_offset+1
|
||||
lda #<lines_offset+1
|
||||
sta render_bcd.offset
|
||||
tya
|
||||
lda #>lines_offset+1
|
||||
sta render_bcd.offset+1
|
||||
jsr render_bcd
|
||||
ldx level_bcd
|
||||
@ -390,8 +392,8 @@ render_bcd: {
|
||||
// Render the next tetromino in the "next" area
|
||||
render_next: {
|
||||
.const next_area_offset = $28*$c+$18+4
|
||||
.label next_piece_char = $a
|
||||
.label next_piece_gfx = 5
|
||||
.label next_piece_char = $a
|
||||
.label screen_next_area = 7
|
||||
.label l = 9
|
||||
cmp #0
|
||||
@ -409,13 +411,14 @@ render_next: {
|
||||
b1:
|
||||
txa
|
||||
asl
|
||||
// Render the next piece
|
||||
tay
|
||||
lda PIECES_NEXT_CHARS,x
|
||||
sta next_piece_char
|
||||
lda PIECES,y
|
||||
sta next_piece_gfx
|
||||
lda PIECES+1,y
|
||||
sta next_piece_gfx+1
|
||||
lda PIECES_NEXT_CHARS,x
|
||||
sta next_piece_char
|
||||
lda #0
|
||||
sta l
|
||||
b3:
|
||||
@ -816,10 +819,9 @@ play_move_down: {
|
||||
tax
|
||||
jsr play_update_score
|
||||
jsr play_spawn_current
|
||||
ldy play_spawn_current._7
|
||||
lda PIECES,y
|
||||
lda current_piece_gfx
|
||||
sta current_piece
|
||||
lda PIECES+1,y
|
||||
lda current_piece_gfx+1
|
||||
sta current_piece+1
|
||||
lda #0
|
||||
sta current_orientation
|
||||
@ -838,20 +840,18 @@ play_move_down: {
|
||||
// Spawn a new piece
|
||||
// Moves the next piece into the current and spawns a new next piece
|
||||
play_spawn_current: {
|
||||
.label _7 = 4
|
||||
.label piece_idx = $21
|
||||
// Move next piece into current
|
||||
ldx next_piece_idx
|
||||
txa
|
||||
asl
|
||||
sta _7
|
||||
lda PIECES_CHARS,x
|
||||
sta current_piece_char
|
||||
ldy _7
|
||||
tay
|
||||
lda PIECES,y
|
||||
sta current_piece_gfx
|
||||
lda PIECES+1,y
|
||||
sta current_piece_gfx+1
|
||||
lda PIECES_CHARS,x
|
||||
sta current_piece_char
|
||||
lda PIECES_START_X,x
|
||||
sta current_xpos
|
||||
lda PIECES_START_Y,x
|
||||
@ -860,9 +860,9 @@ play_spawn_current: {
|
||||
sta play_collision.xpos
|
||||
lda current_ypos
|
||||
sta play_collision.ypos
|
||||
lda PIECES,y
|
||||
lda current_piece_gfx
|
||||
sta current_piece_104
|
||||
lda PIECES+1,y
|
||||
lda current_piece_gfx+1
|
||||
sta current_piece_104+1
|
||||
ldx #0
|
||||
jsr play_collision
|
||||
@ -1378,7 +1378,7 @@ sprites_init: {
|
||||
}
|
||||
// Initialize rendering
|
||||
render_init: {
|
||||
.const vicSelectGfxBank1_toDd001_return = 3^(>PLAYFIELD_CHARSET)/$40
|
||||
.const vicSelectGfxBank1_toDd001_return = 3
|
||||
.label li_1 = 5
|
||||
.label li_2 = 7
|
||||
lda #3
|
||||
|
@ -6,7 +6,7 @@ main: {
|
||||
lda #0
|
||||
sta screen+$27
|
||||
sta screen+$26
|
||||
sta $28*1+screen+$27
|
||||
sta screen+$26+$28*1
|
||||
sta screen+$28*1+$27
|
||||
sta screen+$28*1+$26
|
||||
rts
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const SIZEOF_SIGNED_WORD = 2
|
||||
main: {
|
||||
.label screen = $400
|
||||
ldx #0
|
||||
|
@ -5,12 +5,11 @@
|
||||
.const STAR = $51
|
||||
.label VIC = $d000
|
||||
.const RED = 2
|
||||
.label BGCOL = VIC+$10*2+1
|
||||
main: {
|
||||
lda #STAR
|
||||
sta SCREEN
|
||||
lda #RED
|
||||
sta BGCOL
|
||||
sta VIC+$10*2+1
|
||||
ldx #$28
|
||||
b1:
|
||||
lda #STAR+1
|
||||
|
@ -18,8 +18,8 @@ main: {
|
||||
test_sbytes: {
|
||||
.const bb = 0
|
||||
.const bc = bb+2
|
||||
.const bd = bc-4
|
||||
.const bf = $ff&-$7f-$7f
|
||||
.const bd = bc-4
|
||||
.const be = -bd
|
||||
lda #0
|
||||
sta assert_sbyte.c
|
||||
|
39
src/test/ref/derefidx-word-0.asm
Normal file
39
src/test/ref/derefidx-word-0.asm
Normal file
@ -0,0 +1,39 @@
|
||||
// Tests that array-indexing by a word variable is turned into pointer addition
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
.label screen = $400
|
||||
.label i = 2
|
||||
.label _1 = 4
|
||||
lda #<0
|
||||
sta i
|
||||
sta i+1
|
||||
b1:
|
||||
lda i
|
||||
clc
|
||||
adc #<screen
|
||||
sta _1
|
||||
lda i+1
|
||||
adc #>screen
|
||||
sta _1+1
|
||||
lda #'a'
|
||||
ldy #0
|
||||
sta (_1),y
|
||||
lda #$28
|
||||
clc
|
||||
adc i
|
||||
sta i
|
||||
bcc !+
|
||||
inc i+1
|
||||
!:
|
||||
lda i+1
|
||||
cmp #>$3e8
|
||||
bcc b1
|
||||
bne !+
|
||||
lda i
|
||||
cmp #<$3e8
|
||||
bcc b1
|
||||
!:
|
||||
rts
|
||||
}
|
10
src/test/ref/derefidx-word-1.asm
Normal file
10
src/test/ref/derefidx-word-1.asm
Normal file
@ -0,0 +1,10 @@
|
||||
// Tests that array-indexing by a constant word is turned into a constant pointer
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
.label screen = $400
|
||||
lda #'a'
|
||||
sta screen+$28*$a
|
||||
rts
|
||||
}
|
15
src/test/ref/derefidx-word-2.asm
Normal file
15
src/test/ref/derefidx-word-2.asm
Normal file
@ -0,0 +1,15 @@
|
||||
// Tests that array-indexing by a word variable that is a sum of a constant word and a byte is turned back into derefidx
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
.label screen = $400
|
||||
ldx #0
|
||||
b1:
|
||||
lda #'a'
|
||||
sta screen+$28*$a,x
|
||||
inx
|
||||
cpx #$28
|
||||
bne b1
|
||||
rts
|
||||
}
|
@ -129,13 +129,13 @@ anim: {
|
||||
tya
|
||||
asl
|
||||
tax
|
||||
lda #$80
|
||||
lda xp
|
||||
clc
|
||||
adc xp
|
||||
adc #$80
|
||||
sta SPRITES_XPOS,x
|
||||
lda #$80
|
||||
lda yp
|
||||
clc
|
||||
adc yp
|
||||
adc #$80
|
||||
sta SPRITES_YPOS,x
|
||||
inc i
|
||||
lda #8
|
||||
@ -149,10 +149,9 @@ anim: {
|
||||
// Increment angles
|
||||
inc sx
|
||||
inc sx
|
||||
lda sy
|
||||
sec
|
||||
sbc #3
|
||||
sta sy
|
||||
lax sy
|
||||
axs #3
|
||||
stx sy
|
||||
jmp b2
|
||||
}
|
||||
debug_print: {
|
||||
@ -336,8 +335,7 @@ print_sbyte_at: {
|
||||
.label at = 6
|
||||
cpx #0
|
||||
bmi b1
|
||||
lda #' '
|
||||
sta print_char_at.ch
|
||||
ldy #' '
|
||||
jsr print_char_at
|
||||
b2:
|
||||
inc print_byte_at.at
|
||||
@ -347,8 +345,7 @@ print_sbyte_at: {
|
||||
jsr print_byte_at
|
||||
rts
|
||||
b1:
|
||||
lda #'-'
|
||||
sta print_char_at.ch
|
||||
ldy #'-'
|
||||
jsr print_char_at
|
||||
txa
|
||||
eor #$ff
|
||||
@ -358,17 +355,16 @@ print_sbyte_at: {
|
||||
jmp b2
|
||||
}
|
||||
// Print a single char
|
||||
// print_char_at(byte zeropage(8) ch, byte* zeropage(6) at)
|
||||
// print_char_at(byte register(Y) ch, byte* zeropage(6) at)
|
||||
print_char_at: {
|
||||
.label at = 6
|
||||
.label ch = 8
|
||||
lda ch
|
||||
tya
|
||||
ldy #0
|
||||
sta (at),y
|
||||
rts
|
||||
}
|
||||
// Print a byte as HEX at a specific position
|
||||
// print_byte_at(byte* zeropage(6) at)
|
||||
// print_byte_at(byte register(X) b, byte* zeropage(6) at)
|
||||
print_byte_at: {
|
||||
.label at = 6
|
||||
txa
|
||||
@ -378,7 +374,7 @@ print_byte_at: {
|
||||
lsr
|
||||
tay
|
||||
lda print_hextab,y
|
||||
sta print_char_at.ch
|
||||
tay
|
||||
jsr print_char_at
|
||||
lda #$f
|
||||
axs #0
|
||||
@ -386,8 +382,7 @@ print_byte_at: {
|
||||
bne !+
|
||||
inc print_char_at.at+1
|
||||
!:
|
||||
lda print_hextab,x
|
||||
sta print_char_at.ch
|
||||
ldy print_hextab,x
|
||||
jsr print_char_at
|
||||
rts
|
||||
}
|
||||
@ -395,10 +390,10 @@ print_byte_at: {
|
||||
// The rotation matrix is prepared by calling prepare_matrix()
|
||||
// The passed points must be in the interval [-$3f;$3f].
|
||||
// Implemented in assembler to utilize seriously fast multiplication
|
||||
// rotate_matrix(signed byte register(X) x, signed byte zeropage(5) y, signed byte zeropage(8) z)
|
||||
// rotate_matrix(signed byte register(X) x, signed byte zeropage(5) y, signed byte zeropage($a) z)
|
||||
rotate_matrix: {
|
||||
.label y = 5
|
||||
.label z = 8
|
||||
.label z = $a
|
||||
txa
|
||||
sta xr
|
||||
lda y
|
||||
@ -543,7 +538,7 @@ calculate_matrix: {
|
||||
.label sy = 3
|
||||
.label t1 = 4
|
||||
.label t3 = 5
|
||||
.label t4 = 8
|
||||
.label t4 = $a
|
||||
.label t5 = $b
|
||||
.label t6 = $c
|
||||
.label t7 = $d
|
||||
@ -959,9 +954,9 @@ debug_print_init: {
|
||||
str11: .text "yp@"
|
||||
}
|
||||
// Print a string at a specific screen position
|
||||
// print_str_at(byte* zeropage(6) str, byte* zeropage(9) at)
|
||||
// print_str_at(byte* zeropage(6) str, byte* zeropage(8) at)
|
||||
print_str_at: {
|
||||
.label at = 9
|
||||
.label at = 8
|
||||
.label str = 6
|
||||
b1:
|
||||
ldy #0
|
||||
@ -1014,7 +1009,7 @@ sprites_init: {
|
||||
sta SPRITES_ENABLE
|
||||
ldx #0
|
||||
b1:
|
||||
lda #$ff&SPRITE/$40
|
||||
lda #SPRITE/$40
|
||||
sta sprites_ptr,x
|
||||
lda #GREEN
|
||||
sta SPRITES_COLS,x
|
||||
@ -1024,6 +1019,9 @@ sprites_init: {
|
||||
rts
|
||||
}
|
||||
print_hextab: .text "0123456789abcdef"
|
||||
// Positions to rotate
|
||||
xs: .byte -$34, -$34, -$34, 0, 0, $34, $34, $34
|
||||
ys: .byte -$34, 0, $34, -$34, $34, -$34, 0, $34
|
||||
zs: .byte $34, $34, $34, $34, $34, $34, $34, $34
|
||||
// Rotated positions
|
||||
xrs: .fill 8, 0
|
||||
@ -1036,9 +1034,6 @@ sprites_init: {
|
||||
yps: .fill 8, 0
|
||||
// The rotation matrix
|
||||
rotation_matrix: .fill 9, 0
|
||||
// Positions to rotate
|
||||
xs: .byte -$34, -$34, -$34, 0, 0, $34, $34, $34
|
||||
ys: .byte -$34, 0, $34, -$34, $34, -$34, 0, $34
|
||||
.pc = mulf_sqr1 "mulf_sqr1"
|
||||
.for(var i=0;i<$200;i++) {
|
||||
.if(i<=159) { .byte round((i*i)/256) }
|
||||
|
@ -32,8 +32,8 @@ main: {
|
||||
rts
|
||||
}
|
||||
do_perspective: {
|
||||
.label y = -$47
|
||||
.label x = $39
|
||||
.label y = -$47
|
||||
.label z = $36
|
||||
lda #<$400
|
||||
sta print_char_cursor
|
||||
@ -240,9 +240,9 @@ mulf_init: {
|
||||
.label val = 6
|
||||
.label sqr = 2
|
||||
.label add = 4
|
||||
lda #1
|
||||
lda #<1
|
||||
sta add
|
||||
lda #0
|
||||
lda #>1
|
||||
sta add+1
|
||||
tax
|
||||
sta sqr
|
||||
|
@ -187,6 +187,7 @@ bitmap_plot: {
|
||||
.label _0 = 9
|
||||
.label plotter_x = 9
|
||||
.label plotter_y = $b
|
||||
.label plotter = 9
|
||||
lda bitmap_plot_xhi,x
|
||||
sta plotter_x+1
|
||||
lda bitmap_plot_xlo,x
|
||||
@ -204,8 +205,8 @@ bitmap_plot: {
|
||||
sta _0+1
|
||||
lda bitmap_plot_bit,x
|
||||
ldy #0
|
||||
ora (_0),y
|
||||
sta (_0),y
|
||||
ora (plotter),y
|
||||
sta (plotter),y
|
||||
rts
|
||||
}
|
||||
// bitmap_line_ydxi(byte zeropage(7) y, byte register(X) x, byte zeropage(6) y1, byte zeropage(3) yd, byte zeropage(4) xd)
|
||||
@ -335,11 +336,11 @@ init_screen: {
|
||||
bitmap_clear: {
|
||||
.label bitmap = 9
|
||||
.label y = 2
|
||||
.label _3 = 9
|
||||
.label _4 = 9
|
||||
lda bitmap_plot_xlo
|
||||
sta _3
|
||||
sta _4
|
||||
lda bitmap_plot_xhi
|
||||
sta _3+1
|
||||
sta _4+1
|
||||
lda #0
|
||||
sta y
|
||||
b1:
|
||||
|
@ -312,10 +312,11 @@ mul8u: {
|
||||
.label mb = $b
|
||||
.label res = 9
|
||||
.label return = 9
|
||||
lda #b
|
||||
lda #<b
|
||||
sta mb
|
||||
lda #0
|
||||
lda #>b
|
||||
sta mb+1
|
||||
lda #<0
|
||||
sta res
|
||||
sta res+1
|
||||
b1:
|
||||
|
@ -145,10 +145,11 @@ print_char_at: {
|
||||
rts
|
||||
}
|
||||
// Print a byte as HEX at a specific position
|
||||
// print_byte_at(byte* zeropage(8) at)
|
||||
// print_byte_at(byte zeropage($a) b, byte* zeropage(8) at)
|
||||
print_byte_at: {
|
||||
.label b = $a
|
||||
.label at = 8
|
||||
lda print_sbyte_at.b
|
||||
lda b
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
@ -158,7 +159,7 @@ print_byte_at: {
|
||||
sta print_char_at.ch
|
||||
jsr print_char_at
|
||||
lda #$f
|
||||
and print_sbyte_at.b
|
||||
and b
|
||||
tay
|
||||
inc print_char_at.at
|
||||
bne !+
|
||||
|
@ -307,7 +307,7 @@ sid_rnd_init: {
|
||||
fillscreen: {
|
||||
.label screen = 2
|
||||
.label i = 4
|
||||
lda #0
|
||||
lda #<0
|
||||
sta i
|
||||
sta i+1
|
||||
b1:
|
||||
|
@ -219,13 +219,13 @@ init: {
|
||||
lda #VIC_DEN|VIC_RSEL|3
|
||||
sta D011
|
||||
jsr plexInit
|
||||
lda #$20
|
||||
lda #<$20
|
||||
sta xp
|
||||
lda #0
|
||||
lda #>$20
|
||||
sta xp+1
|
||||
tax
|
||||
ldx #0
|
||||
b1:
|
||||
lda #$ff&SPRITE/$40
|
||||
lda #SPRITE/$40
|
||||
sta PLEX_PTR,x
|
||||
txa
|
||||
asl
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -27,14 +27,16 @@ main: {
|
||||
rts
|
||||
}
|
||||
anim: {
|
||||
.label _4 = 7
|
||||
.label _6 = 9
|
||||
.label _4 = 5
|
||||
.label _6 = 5
|
||||
.label _9 = 5
|
||||
.label _10 = 5
|
||||
.label _11 = 5
|
||||
.label _12 = 5
|
||||
.label x = $b
|
||||
.label y = $c
|
||||
.label cos_a = $b
|
||||
.label sin_a = $c
|
||||
.label x = $d
|
||||
.label y = $e
|
||||
.label xr = 7
|
||||
.label yr = 9
|
||||
.label xpos = 5
|
||||
@ -48,6 +50,11 @@ anim: {
|
||||
cmp RASTER
|
||||
bne b2
|
||||
inc BORDERCOL
|
||||
ldy angle
|
||||
lda COS,y
|
||||
sta cos_a
|
||||
lda SIN,y
|
||||
sta sin_a
|
||||
lda #0
|
||||
sta sprite_msb
|
||||
sta i
|
||||
@ -58,27 +65,25 @@ anim: {
|
||||
// signed fixed[7.0]
|
||||
lda ys,y
|
||||
sta y
|
||||
ldy angle
|
||||
lda COS,y
|
||||
lda cos_a
|
||||
jsr mulf8u_prepare
|
||||
ldy x
|
||||
jsr mulf8s_prepared
|
||||
lda mulf8s_prepared.return
|
||||
sta _4
|
||||
lda mulf8s_prepared.return+1
|
||||
sta _4+1
|
||||
asl xr
|
||||
rol xr+1
|
||||
lda _4
|
||||
asl
|
||||
sta xr
|
||||
lda _4+1
|
||||
rol
|
||||
sta xr+1
|
||||
ldy y
|
||||
jsr mulf8s_prepared
|
||||
lda mulf8s_prepared.return
|
||||
sta _6
|
||||
lda mulf8s_prepared.return+1
|
||||
sta _6+1
|
||||
asl yr
|
||||
rol yr+1
|
||||
ldy angle
|
||||
lda SIN,y
|
||||
lda _6
|
||||
asl
|
||||
sta yr
|
||||
lda _6+1
|
||||
rol
|
||||
sta yr+1
|
||||
lda sin_a
|
||||
jsr mulf8u_prepare
|
||||
ldy y
|
||||
jsr mulf8s_prepared
|
||||
@ -104,18 +109,16 @@ anim: {
|
||||
adc _12+1
|
||||
sta yr+1
|
||||
lda xr+1
|
||||
tax
|
||||
clc
|
||||
adc #<$18+$95
|
||||
sta xpos
|
||||
txa
|
||||
ora #$7f
|
||||
bmi !+
|
||||
lda #0
|
||||
!:
|
||||
sta xpos+1
|
||||
lda xpos
|
||||
clc
|
||||
adc #$18+$95
|
||||
sta xpos
|
||||
lda xpos+1
|
||||
adc #0
|
||||
adc #>$18+$95
|
||||
sta xpos+1
|
||||
lsr sprite_msb
|
||||
cmp #0
|
||||
@ -153,35 +156,44 @@ anim: {
|
||||
// mulf8s_prepared(signed byte register(Y) b)
|
||||
mulf8s_prepared: {
|
||||
.label memA = $fd
|
||||
.label _8 = $f
|
||||
.label _12 = $f
|
||||
.label m = 5
|
||||
.label return = 5
|
||||
tya
|
||||
jsr mulf8u_prepared
|
||||
lda memA
|
||||
cmp #0
|
||||
bpl b1
|
||||
lda m+1
|
||||
sty $ff
|
||||
sta _8
|
||||
tya
|
||||
eor #$ff
|
||||
sec
|
||||
sbc $ff
|
||||
adc _8
|
||||
sta m+1
|
||||
b1:
|
||||
cpy #0
|
||||
bpl b2
|
||||
lda m+1
|
||||
sta _12
|
||||
lda memA
|
||||
eor #$ff
|
||||
sec
|
||||
sbc memA
|
||||
adc _12
|
||||
sta m+1
|
||||
b2:
|
||||
rts
|
||||
}
|
||||
// Calculate fast multiply with a prepared unsigned byte to a word result
|
||||
// The prepared number is set by calling mulf8u_prepare(byte a)
|
||||
// mulf8u_prepared(byte register(A) b)
|
||||
mulf8u_prepared: {
|
||||
.label resL = $fe
|
||||
.label memB = $ff
|
||||
.label return = 5
|
||||
sty memB
|
||||
ldx memB
|
||||
sta memB
|
||||
tax
|
||||
sec
|
||||
sm1:
|
||||
lda mulf_sqr1_lo,x
|
||||
@ -218,7 +230,7 @@ init: {
|
||||
sta SPRITES_ENABLE
|
||||
ldx #0
|
||||
b1:
|
||||
lda #$ff&SPRITE/$40
|
||||
lda #SPRITE/$40
|
||||
sta sprites_ptr,x
|
||||
lda #GREEN
|
||||
sta SPRITES_COLS,x
|
||||
@ -246,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
|
||||
|
@ -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:
|
||||
@ -120,8 +120,8 @@ loop: {
|
||||
render_logo: {
|
||||
.label _3 = $f
|
||||
.label xpos = 9
|
||||
.label x_char = 4
|
||||
.label logo_idx = 4
|
||||
.label logo_start = 4
|
||||
lda xpos
|
||||
and #7
|
||||
ora #VIC_MCM
|
||||
@ -142,20 +142,21 @@ render_logo: {
|
||||
ror _3+1
|
||||
ror _3
|
||||
lda _3
|
||||
sta x_char
|
||||
tax
|
||||
lda xpos+1
|
||||
bmi b1
|
||||
stx logo_start
|
||||
ldy #0
|
||||
b2:
|
||||
cpy x_char
|
||||
bne b3
|
||||
b3:
|
||||
cpy logo_start
|
||||
bne b4
|
||||
lda #0
|
||||
sta logo_idx
|
||||
b5:
|
||||
cpy #$28
|
||||
bne b6
|
||||
rts
|
||||
b6:
|
||||
cpy #$28
|
||||
bne b7
|
||||
rts
|
||||
b7:
|
||||
lda logo_idx
|
||||
sta SCREEN,y
|
||||
lda #$28*1
|
||||
@ -180,8 +181,8 @@ render_logo: {
|
||||
sta SCREEN+$28*5,y
|
||||
iny
|
||||
inc logo_idx
|
||||
jmp b5
|
||||
b3:
|
||||
jmp b6
|
||||
b4:
|
||||
lda #0
|
||||
sta SCREEN,y
|
||||
sta SCREEN+$28*1,y
|
||||
@ -190,23 +191,23 @@ render_logo: {
|
||||
sta SCREEN+$28*4,y
|
||||
sta SCREEN+$28*5,y
|
||||
iny
|
||||
jmp b2
|
||||
jmp b3
|
||||
b1:
|
||||
lda x_char
|
||||
txa
|
||||
eor #$ff
|
||||
clc
|
||||
adc #1
|
||||
sta logo_idx
|
||||
ldy #0
|
||||
b8:
|
||||
b9:
|
||||
lda #$28
|
||||
cmp logo_idx
|
||||
bne b9
|
||||
b11:
|
||||
cpy #$28
|
||||
bne b12
|
||||
rts
|
||||
bne b10
|
||||
b12:
|
||||
cpy #$28
|
||||
bne b13
|
||||
rts
|
||||
b13:
|
||||
lda #0
|
||||
sta SCREEN,y
|
||||
sta SCREEN+$28*1,y
|
||||
@ -215,8 +216,8 @@ render_logo: {
|
||||
sta SCREEN+$28*4,y
|
||||
sta SCREEN+$28*5,y
|
||||
iny
|
||||
jmp b11
|
||||
b9:
|
||||
jmp b12
|
||||
b10:
|
||||
lda logo_idx
|
||||
sta SCREEN,y
|
||||
lda #$28*1
|
||||
@ -241,7 +242,7 @@ render_logo: {
|
||||
sta SCREEN+$28*5,y
|
||||
iny
|
||||
inc logo_idx
|
||||
jmp b8
|
||||
jmp b9
|
||||
}
|
||||
// Generate signed word sinus table - with values in the range min-max.
|
||||
// sintab - the table to generate into
|
||||
@ -254,22 +255,24 @@ sin16s_gen2: {
|
||||
.label _5 = $b
|
||||
.label _6 = $f
|
||||
.label _8 = $f
|
||||
.label step = $1b
|
||||
.label step = $19
|
||||
.label sintab = 2
|
||||
.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:
|
||||
@ -329,21 +332,25 @@ sin16s_gen2: {
|
||||
}
|
||||
// Multiply of two signed words to a signed double word
|
||||
// Fixes offsets introduced by using unsigned multiplication
|
||||
// mul16s(signed word zeropage($17) a)
|
||||
// mul16s(signed word zeropage($15) a)
|
||||
mul16s: {
|
||||
.label _9 = $f
|
||||
.label _16 = $f
|
||||
.label m = $b
|
||||
.label return = $b
|
||||
.label a = $17
|
||||
.label a = $15
|
||||
lda a
|
||||
sta mul16u.a
|
||||
lda a+1
|
||||
sta mul16u.a+1
|
||||
lda #<sin16s_gen2.ampl
|
||||
sta mul16u.b
|
||||
sta mul16u.mb
|
||||
lda #>sin16s_gen2.ampl
|
||||
sta mul16u.b+1
|
||||
sta mul16u.mb+1
|
||||
lda #<sin16s_gen2.ampl>>$10
|
||||
sta mul16u.mb+2
|
||||
lda #>sin16s_gen2.ampl>>$10
|
||||
sta mul16u.mb+3
|
||||
jsr mul16u
|
||||
lda a+1
|
||||
bpl b2
|
||||
@ -366,23 +373,19 @@ mul16s: {
|
||||
rts
|
||||
}
|
||||
// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word
|
||||
// mul16u(word zeropage($11) a, word zeropage($f) b)
|
||||
// mul16u(word zeropage($f) a, word zeropage($17) b)
|
||||
mul16u: {
|
||||
.label mb = $13
|
||||
.label a = $11
|
||||
.label mb = $11
|
||||
.label a = $f
|
||||
.label res = $b
|
||||
.label return = $b
|
||||
.label b = $f
|
||||
lda b
|
||||
sta mb
|
||||
lda b+1
|
||||
sta mb+1
|
||||
lda #0
|
||||
sta mb+2
|
||||
sta mb+3
|
||||
.label b = $17
|
||||
lda #<0
|
||||
sta res
|
||||
sta res+1
|
||||
lda #<0>>$10
|
||||
sta res+2
|
||||
lda #>0>>$10
|
||||
sta res+3
|
||||
b1:
|
||||
lda a
|
||||
@ -424,17 +427,18 @@ mul16u: {
|
||||
// sin16s(dword zeropage($b) x)
|
||||
sin16s: {
|
||||
.label _4 = $b
|
||||
.label _20 = $15
|
||||
.label x = $b
|
||||
.label return = $17
|
||||
.label x1 = $1f
|
||||
.label x2 = $19
|
||||
.label x3 = $19
|
||||
.label return = $15
|
||||
.label x1 = $1d
|
||||
.label x2 = $15
|
||||
.label x3 = $15
|
||||
.label x3_6 = $f
|
||||
.label usinx = $17
|
||||
.label x4 = $19
|
||||
.label usinx = $1f
|
||||
.label x4 = $15
|
||||
.label x5 = $f
|
||||
.label x5_128 = $f
|
||||
.label sinx = $17
|
||||
.label sinx = $15
|
||||
.label isUpper = 4
|
||||
lda x+3
|
||||
cmp #>PI_u4f28>>$10
|
||||
@ -580,9 +584,17 @@ sin16s: {
|
||||
lda usinx+1
|
||||
adc x5_128+1
|
||||
sta usinx+1
|
||||
lda usinx
|
||||
sta sinx
|
||||
lda usinx+1
|
||||
sta sinx+1
|
||||
lda isUpper
|
||||
cmp #0
|
||||
beq b3
|
||||
lda usinx
|
||||
sta _20
|
||||
lda usinx+1
|
||||
sta _20+1
|
||||
sec
|
||||
lda sinx
|
||||
eor #$ff
|
||||
@ -597,19 +609,26 @@ 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($19) v1, word zeropage($f) v2, byte register(X) select)
|
||||
// mulu16_sel(word zeropage($15) v1, word zeropage($17) v2, byte register(X) select)
|
||||
mulu16_sel: {
|
||||
.label _0 = $b
|
||||
.label _1 = $b
|
||||
.label v1 = $19
|
||||
.label v2 = $f
|
||||
.label v1 = $15
|
||||
.label v2 = $17
|
||||
.label return = $f
|
||||
.label return_1 = $19
|
||||
.label return_10 = $19
|
||||
.label return_1 = $15
|
||||
.label return_10 = $15
|
||||
lda v1
|
||||
sta mul16u.a
|
||||
lda v1+1
|
||||
sta mul16u.a+1
|
||||
lda mul16u.b
|
||||
sta mul16u.mb
|
||||
lda mul16u.b+1
|
||||
sta mul16u.mb+1
|
||||
lda #0
|
||||
sta mul16u.mb+2
|
||||
sta mul16u.mb+3
|
||||
jsr mul16u
|
||||
cpx #0
|
||||
beq !e+
|
||||
@ -630,14 +649,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 = $11
|
||||
.label quotient_hi = $15
|
||||
.label quotient_lo = $f
|
||||
.label return = $1b
|
||||
.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
|
||||
|
@ -36,7 +36,7 @@
|
||||
.label sin2 = $1400
|
||||
.label rem16u = 2
|
||||
main: {
|
||||
.const vicSelectGfxBank1_toDd001_return = 3^(>SCREEN)/$40
|
||||
.const vicSelectGfxBank1_toDd001_return = 3
|
||||
.const toD0181_return = (>(SCREEN&$3fff)*4)|(>BITMAP)/4&$f
|
||||
sei
|
||||
// Disable normal interrupt
|
||||
@ -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,33 +174,34 @@ render_sine: {
|
||||
// Plot a single dot in the bitmap
|
||||
// bitmap_plot(word zeropage(4) x, byte register(X) y)
|
||||
bitmap_plot: {
|
||||
.label _1 = $10
|
||||
.label _1 = $15
|
||||
.label plotter = 6
|
||||
.label plotter_1 = $15
|
||||
.label x = 4
|
||||
.label _3 = 6
|
||||
.label _4 = 6
|
||||
lda bitmap_plot_yhi,x
|
||||
sta _3+1
|
||||
sta _4+1
|
||||
lda bitmap_plot_ylo,x
|
||||
sta _3
|
||||
sta _4
|
||||
lda x
|
||||
and #<$fff8
|
||||
sta _1
|
||||
lda x+1
|
||||
and #>$fff8
|
||||
sta _1+1
|
||||
lda plotter
|
||||
lda plotter_1
|
||||
clc
|
||||
adc _1
|
||||
sta plotter
|
||||
lda plotter+1
|
||||
adc _1+1
|
||||
sta plotter+1
|
||||
adc plotter
|
||||
sta plotter_1
|
||||
lda plotter_1+1
|
||||
adc plotter+1
|
||||
sta plotter_1+1
|
||||
lda x
|
||||
tay
|
||||
lda bitmap_plot_bit,y
|
||||
ldy #0
|
||||
ora (plotter),y
|
||||
sta (plotter),y
|
||||
ora (plotter_1),y
|
||||
sta (plotter_1),y
|
||||
rts
|
||||
}
|
||||
// wrap_y(signed word zeropage(6) y)
|
||||
@ -230,13 +231,13 @@ wrap_y: {
|
||||
sta y+1
|
||||
jmp b3
|
||||
b2:
|
||||
sec
|
||||
lda y
|
||||
sbc #$c8
|
||||
sec
|
||||
sbc #<$c8
|
||||
sta y
|
||||
bcs !+
|
||||
dec y+1
|
||||
!:
|
||||
lda y+1
|
||||
sbc #>$c8
|
||||
sta y+1
|
||||
jmp b1
|
||||
}
|
||||
// Generate signed word sinus table - with values in the range min-max.
|
||||
@ -250,22 +251,24 @@ sin16s_gen2: {
|
||||
.label _5 = $c
|
||||
.label _6 = 6
|
||||
.label _8 = 6
|
||||
.label step = $1b
|
||||
.label step = $19
|
||||
.label sintab = 2
|
||||
.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:
|
||||
@ -325,21 +328,25 @@ sin16s_gen2: {
|
||||
}
|
||||
// Multiply of two signed words to a signed double word
|
||||
// Fixes offsets introduced by using unsigned multiplication
|
||||
// mul16s(signed word zeropage($17) a)
|
||||
// mul16s(signed word zeropage($15) a)
|
||||
mul16s: {
|
||||
.label _9 = 6
|
||||
.label _16 = 6
|
||||
.label m = $c
|
||||
.label return = $c
|
||||
.label a = $17
|
||||
.label a = $15
|
||||
lda a
|
||||
sta mul16u.a
|
||||
lda a+1
|
||||
sta mul16u.a+1
|
||||
lda #<sin16s_gen2.ampl
|
||||
sta mul16u.b
|
||||
sta mul16u.mb
|
||||
lda #>sin16s_gen2.ampl
|
||||
sta mul16u.b+1
|
||||
sta mul16u.mb+1
|
||||
lda #<sin16s_gen2.ampl>>$10
|
||||
sta mul16u.mb+2
|
||||
lda #>sin16s_gen2.ampl>>$10
|
||||
sta mul16u.mb+3
|
||||
jsr mul16u
|
||||
lda a+1
|
||||
bpl b2
|
||||
@ -362,23 +369,19 @@ mul16s: {
|
||||
rts
|
||||
}
|
||||
// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word
|
||||
// mul16u(word zeropage($10) a, word zeropage(6) b)
|
||||
// mul16u(word zeropage(6) a, word zeropage($17) b)
|
||||
mul16u: {
|
||||
.label mb = $12
|
||||
.label a = $10
|
||||
.label mb = $10
|
||||
.label a = 6
|
||||
.label res = $c
|
||||
.label return = $c
|
||||
.label b = 6
|
||||
lda b
|
||||
sta mb
|
||||
lda b+1
|
||||
sta mb+1
|
||||
lda #0
|
||||
sta mb+2
|
||||
sta mb+3
|
||||
.label b = $17
|
||||
lda #<0
|
||||
sta res
|
||||
sta res+1
|
||||
lda #<0>>$10
|
||||
sta res+2
|
||||
lda #>0>>$10
|
||||
sta res+3
|
||||
b1:
|
||||
lda a
|
||||
@ -420,18 +423,19 @@ mul16u: {
|
||||
// sin16s(dword zeropage($c) x)
|
||||
sin16s: {
|
||||
.label _4 = $c
|
||||
.label _20 = $15
|
||||
.label x = $c
|
||||
.label return = $17
|
||||
.label x1 = $1f
|
||||
.label x2 = $19
|
||||
.label x3 = $19
|
||||
.label return = $15
|
||||
.label x1 = $1d
|
||||
.label x2 = $15
|
||||
.label x3 = $15
|
||||
.label x3_6 = 6
|
||||
.label usinx = $17
|
||||
.label x4 = $19
|
||||
.label usinx = $1f
|
||||
.label x4 = $15
|
||||
.label x5 = 6
|
||||
.label x5_128 = 6
|
||||
.label sinx = $17
|
||||
.label isUpper = $16
|
||||
.label sinx = $15
|
||||
.label isUpper = $14
|
||||
lda x+3
|
||||
cmp #>PI_u4f28>>$10
|
||||
bcc b4
|
||||
@ -576,9 +580,17 @@ sin16s: {
|
||||
lda usinx+1
|
||||
adc x5_128+1
|
||||
sta usinx+1
|
||||
lda usinx
|
||||
sta sinx
|
||||
lda usinx+1
|
||||
sta sinx+1
|
||||
lda isUpper
|
||||
cmp #0
|
||||
beq b3
|
||||
lda usinx
|
||||
sta _20
|
||||
lda usinx+1
|
||||
sta _20+1
|
||||
sec
|
||||
lda sinx
|
||||
eor #$ff
|
||||
@ -593,19 +605,26 @@ 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($19) v1, word zeropage(6) v2, byte register(X) select)
|
||||
// mulu16_sel(word zeropage($15) v1, word zeropage($17) v2, byte register(X) select)
|
||||
mulu16_sel: {
|
||||
.label _0 = $c
|
||||
.label _1 = $c
|
||||
.label v1 = $19
|
||||
.label v2 = 6
|
||||
.label v1 = $15
|
||||
.label v2 = $17
|
||||
.label return = 6
|
||||
.label return_1 = $19
|
||||
.label return_10 = $19
|
||||
.label return_1 = $15
|
||||
.label return_10 = $15
|
||||
lda v1
|
||||
sta mul16u.a
|
||||
lda v1+1
|
||||
sta mul16u.a+1
|
||||
lda mul16u.b
|
||||
sta mul16u.mb
|
||||
lda mul16u.b+1
|
||||
sta mul16u.mb+1
|
||||
lda #0
|
||||
sta mul16u.mb+2
|
||||
sta mul16u.mb+3
|
||||
jsr mul16u
|
||||
cpx #0
|
||||
beq !e+
|
||||
@ -626,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 = $10
|
||||
.label quotient_hi = $15
|
||||
.label quotient_lo = 6
|
||||
.label return = $1b
|
||||
.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
|
||||
@ -713,12 +732,12 @@ divr16u: {
|
||||
// Clear all graphics on the bitmap
|
||||
bitmap_clear: {
|
||||
.label bitmap = 2
|
||||
.label y = $16
|
||||
.label _3 = 2
|
||||
.label y = $14
|
||||
.label _4 = 2
|
||||
lda bitmap_plot_ylo
|
||||
sta _3
|
||||
sta _4
|
||||
lda bitmap_plot_yhi
|
||||
sta _3+1
|
||||
sta _4+1
|
||||
lda #0
|
||||
sta y
|
||||
b1:
|
||||
@ -742,7 +761,7 @@ bitmap_clear: {
|
||||
}
|
||||
// Initialize bitmap plotting tables
|
||||
bitmap_init: {
|
||||
.label _3 = $16
|
||||
.label _3 = $14
|
||||
.label yoffs = 2
|
||||
ldx #0
|
||||
lda #$80
|
||||
|
@ -228,9 +228,9 @@ gen_sintab: {
|
||||
lda #>f_amp
|
||||
sta setMEMtoFAC.mem+1
|
||||
jsr setMEMtoFAC
|
||||
lda #2
|
||||
lda #<2
|
||||
sta setFAC.w
|
||||
lda #0
|
||||
lda #>2
|
||||
sta setFAC.w+1
|
||||
jsr setFAC
|
||||
lda #<f_amp
|
||||
@ -596,7 +596,7 @@ place_sprites: {
|
||||
sta spr_x
|
||||
lda #0
|
||||
sta j
|
||||
lda #$ff&sprites/$40
|
||||
lda #sprites/$40
|
||||
sta spr_id
|
||||
b1:
|
||||
lda spr_id
|
||||
|
@ -5,7 +5,7 @@ main: {
|
||||
.label SCREEN = $400
|
||||
.label w = 2
|
||||
.label sw = 2
|
||||
lda #0
|
||||
lda #<0
|
||||
sta w
|
||||
sta w+1
|
||||
b1:
|
||||
|
74
src/test/ref/fragment-variations.asm
Normal file
74
src/test/ref/fragment-variations.asm
Normal file
@ -0,0 +1,74 @@
|
||||
// Tests that ASM fragment variations works
|
||||
// ASM fragment variations "cast" constants to different types
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const SIZEOF_DWORD = 4
|
||||
main: {
|
||||
.label screen = $400
|
||||
.label _0 = 2
|
||||
.label _1 = 2
|
||||
lda #<$a
|
||||
sta mul16u.a
|
||||
lda #>$a
|
||||
sta mul16u.a+1
|
||||
lda #<$a
|
||||
sta mul16u.mb
|
||||
lda #>$a
|
||||
sta mul16u.mb+1
|
||||
lda #<$a>>$10
|
||||
sta mul16u.mb+2
|
||||
lda #>$a>>$10
|
||||
sta mul16u.mb+3
|
||||
jsr mul16u
|
||||
lda _0
|
||||
sta screen
|
||||
lda _0+1
|
||||
sta screen+1
|
||||
lda _0+2
|
||||
sta screen+2
|
||||
lda _0+3
|
||||
sta screen+3
|
||||
lda #<$3e8
|
||||
sta mul16u.a
|
||||
lda #>$3e8
|
||||
sta mul16u.a+1
|
||||
lda #<$3e8
|
||||
sta mul16u.mb
|
||||
lda #>$3e8
|
||||
sta mul16u.mb+1
|
||||
lda #<$3e8>>$10
|
||||
sta mul16u.mb+2
|
||||
lda #>$3e8>>$10
|
||||
sta mul16u.mb+3
|
||||
jsr mul16u
|
||||
lda _1
|
||||
sta screen+1*SIZEOF_DWORD
|
||||
lda _1+1
|
||||
sta screen+1*SIZEOF_DWORD+1
|
||||
lda _1+2
|
||||
sta screen+1*SIZEOF_DWORD+2
|
||||
lda _1+3
|
||||
sta screen+1*SIZEOF_DWORD+3
|
||||
rts
|
||||
}
|
||||
// mul16u(word zeropage(6) a)
|
||||
mul16u: {
|
||||
.label return = 2
|
||||
.label mb = 2
|
||||
.label a = 6
|
||||
lda return
|
||||
clc
|
||||
adc a
|
||||
sta return
|
||||
lda return+1
|
||||
adc a+1
|
||||
sta return+1
|
||||
lda return+2
|
||||
adc #0
|
||||
sta return+2
|
||||
lda return+3
|
||||
adc #0
|
||||
sta return+3
|
||||
rts
|
||||
}
|
16
src/test/ref/gfxbank.asm
Normal file
16
src/test/ref/gfxbank.asm
Normal file
@ -0,0 +1,16 @@
|
||||
// Test minimization of constants
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
|
||||
.label CIA2_PORT_A = $dd00
|
||||
// CIA #2 Port A data direction register.
|
||||
.label CIA2_PORT_A_DDR = $dd02
|
||||
main: {
|
||||
.const vicSelectGfxBank1_toDd001_return = 3
|
||||
lda #3
|
||||
sta CIA2_PORT_A_DDR
|
||||
lda #vicSelectGfxBank1_toDd001_return
|
||||
sta CIA2_PORT_A
|
||||
rts
|
||||
}
|
@ -7,10 +7,11 @@
|
||||
.label D018 = $d018
|
||||
.label CHARSET4 = $2800
|
||||
main: {
|
||||
.label _1 = 6
|
||||
.label _11 = 6
|
||||
.label _21 = 6
|
||||
.label _30 = 6
|
||||
.label _1 = 8
|
||||
.label _11 = 8
|
||||
.label _21 = 8
|
||||
.label _30 = 8
|
||||
.label chargen1 = 6
|
||||
.label charset4 = 4
|
||||
.label chargen = 2
|
||||
sei
|
||||
@ -25,13 +26,19 @@ main: {
|
||||
lda #>CHARGEN
|
||||
sta chargen+1
|
||||
b1:
|
||||
lda chargen
|
||||
clc
|
||||
adc #1
|
||||
sta chargen1
|
||||
lda chargen+1
|
||||
adc #0
|
||||
sta chargen1+1
|
||||
lda #$60
|
||||
ldy #0
|
||||
and (chargen),y
|
||||
sta _1
|
||||
lda #$60
|
||||
ldy #1
|
||||
and (chargen),y
|
||||
and (chargen1),y
|
||||
lsr
|
||||
lsr
|
||||
ora _1
|
||||
@ -54,8 +61,7 @@ main: {
|
||||
and (chargen),y
|
||||
sta _11
|
||||
lda #$18
|
||||
ldy #1
|
||||
and (chargen),y
|
||||
and (chargen1),y
|
||||
lsr
|
||||
lsr
|
||||
ora _11
|
||||
@ -75,8 +81,7 @@ main: {
|
||||
asl
|
||||
sta _21
|
||||
lda #6
|
||||
ldy #1
|
||||
and (chargen),y
|
||||
and (chargen1),y
|
||||
lsr
|
||||
ora _21
|
||||
tay
|
||||
@ -95,8 +100,7 @@ main: {
|
||||
asl
|
||||
sta _30
|
||||
lda #1
|
||||
tay
|
||||
and (chargen),y
|
||||
and (chargen1),y
|
||||
ora _30
|
||||
tay
|
||||
lda bits_count,y
|
||||
|
@ -6,8 +6,8 @@
|
||||
main: {
|
||||
.const toUpper1_ch = 'c'
|
||||
.const toUpper2_ch = 'm'
|
||||
.const toUpper1_res = toUpper1_ch+$40
|
||||
lda #toUpper1_res
|
||||
.const toUpper1_return = toUpper1_ch+$40
|
||||
lda #toUpper1_return
|
||||
sta screen
|
||||
lda #toUpper2_ch
|
||||
sta screen+1
|
||||
|
@ -8,7 +8,7 @@
|
||||
.label SPRITES_XPOS = $d000
|
||||
.label SPRITES_YPOS = $d001
|
||||
main: {
|
||||
lda #$ff&SPRITE/$40
|
||||
lda #SPRITE/$40
|
||||
sta SCREEN+$3f8
|
||||
lda #1
|
||||
sta SPRITES_ENABLE
|
||||
|
10
src/test/ref/inline-pointer-0.asm
Normal file
10
src/test/ref/inline-pointer-0.asm
Normal file
@ -0,0 +1,10 @@
|
||||
// Tests creating a literal pointer from two bytes
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
.label screen = 4*$100
|
||||
lda #'a'
|
||||
sta screen
|
||||
rts
|
||||
}
|
24
src/test/ref/inline-pointer-1.asm
Normal file
24
src/test/ref/inline-pointer-1.asm
Normal file
@ -0,0 +1,24 @@
|
||||
// Tests creating a literal pointer from two bytes
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
ldx #0
|
||||
lda #4
|
||||
jsr puta
|
||||
ldx #$18
|
||||
lda #5
|
||||
jsr puta
|
||||
rts
|
||||
}
|
||||
// puta(byte register(A) ph, byte register(X) pl)
|
||||
puta: {
|
||||
.label screen = 2
|
||||
.label _2 = 2
|
||||
sta _2+1
|
||||
stx _2
|
||||
lda #'a'
|
||||
ldy #0
|
||||
sta (screen),y
|
||||
rts
|
||||
}
|
9
src/test/ref/inline-pointer-2.asm
Normal file
9
src/test/ref/inline-pointer-2.asm
Normal file
@ -0,0 +1,9 @@
|
||||
// Tests creating a literal pointer from two bytes
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
lda #'a'
|
||||
sta 4*$100+$28
|
||||
rts
|
||||
}
|
@ -7,17 +7,18 @@
|
||||
main: {
|
||||
.label PTR = $9ffe
|
||||
.label SCREEN = $400
|
||||
.label _6 = 2
|
||||
.label ptr = 2
|
||||
.label _7 = 2
|
||||
lda #<STRING
|
||||
sta PTR
|
||||
lda #>STRING
|
||||
sta PTR+1
|
||||
lda PTR
|
||||
sta _6
|
||||
sta _7
|
||||
lda PTR+1
|
||||
sta _6+1
|
||||
sta _7+1
|
||||
ldy #0
|
||||
lda (_6),y
|
||||
lda (ptr),y
|
||||
sta SCREEN
|
||||
rts
|
||||
STRING: .text "camelot"
|
||||
|
13
src/test/ref/inline-word-0.asm
Normal file
13
src/test/ref/inline-word-0.asm
Normal file
@ -0,0 +1,13 @@
|
||||
// Tests minimal inline word
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
.label screen = $400
|
||||
.const w = 2*$100+1
|
||||
lda #<w
|
||||
sta screen
|
||||
lda #>w
|
||||
sta screen+1
|
||||
rts
|
||||
}
|
13
src/test/ref/inline-word-1.asm
Normal file
13
src/test/ref/inline-word-1.asm
Normal file
@ -0,0 +1,13 @@
|
||||
// Tests minimal inline word
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
.label screen = $400
|
||||
.const w = 1*$100+2
|
||||
lda #<w
|
||||
sta screen
|
||||
lda #>w
|
||||
sta screen+1
|
||||
rts
|
||||
}
|
13
src/test/ref/inline-word-2.asm
Normal file
13
src/test/ref/inline-word-2.asm
Normal file
@ -0,0 +1,13 @@
|
||||
// Tests minimal inline word
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
.label screen = $400
|
||||
.const w = 1*$100+2
|
||||
lda #<w
|
||||
sta screen
|
||||
lda #>w
|
||||
sta screen+1
|
||||
rts
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
.label SCREEN = $400
|
||||
main: {
|
||||
.label w = 3
|
||||
.label sc = 3
|
||||
.label h = 2
|
||||
lda #0
|
||||
sta h
|
||||
@ -17,7 +18,7 @@ main: {
|
||||
stx w
|
||||
lda #'*'
|
||||
ldy #0
|
||||
sta (w),y
|
||||
sta (sc),y
|
||||
inx
|
||||
cpx #8
|
||||
bne b2
|
||||
|
@ -10,11 +10,13 @@
|
||||
.const TYPEID_SIGNED_DWORD = 6
|
||||
.const RED = 2
|
||||
.const GREEN = 5
|
||||
.label SCREEN = $400
|
||||
.label COLS = $d800
|
||||
main: {
|
||||
.label s = 2
|
||||
lda #<$400
|
||||
lda #<SCREEN
|
||||
sta s
|
||||
lda #>$400
|
||||
lda #>SCREEN
|
||||
sta s+1
|
||||
b1:
|
||||
lda #' '
|
||||
@ -25,11 +27,11 @@ main: {
|
||||
inc s+1
|
||||
!:
|
||||
lda s+1
|
||||
cmp #>$400+$3e8
|
||||
cmp #>SCREEN+$3e8
|
||||
bcc b1
|
||||
bne !+
|
||||
lda s
|
||||
cmp #<$400+$3e8
|
||||
cmp #<SCREEN+$3e8
|
||||
bcc b1
|
||||
!:
|
||||
jsr testSimpleTypes
|
||||
@ -109,14 +111,14 @@ assertType: {
|
||||
cmp t2
|
||||
beq b1
|
||||
lda #RED
|
||||
sta $d800,x
|
||||
sta COLS,x
|
||||
b2:
|
||||
tya
|
||||
sta $400,x
|
||||
sta SCREEN,x
|
||||
inx
|
||||
rts
|
||||
b1:
|
||||
lda #GREEN
|
||||
sta $d800,x
|
||||
sta COLS,x
|
||||
jmp b2
|
||||
}
|
||||
|
@ -80,35 +80,38 @@ bitmap_plot: {
|
||||
.label _1 = 7
|
||||
.label x = 3
|
||||
.label plotter = 5
|
||||
.label _3 = 5
|
||||
.label plotter_1 = 7
|
||||
.label _4 = 5
|
||||
lda bitmap_plot_yhi,x
|
||||
sta _3+1
|
||||
sta _4+1
|
||||
lda bitmap_plot_ylo,x
|
||||
sta _3
|
||||
sta _4
|
||||
lda x
|
||||
and #<$fff8
|
||||
sta _1
|
||||
lda x+1
|
||||
and #>$fff8
|
||||
sta _1+1
|
||||
lda plotter
|
||||
lda plotter_1
|
||||
clc
|
||||
adc _1
|
||||
sta plotter
|
||||
lda plotter+1
|
||||
adc _1+1
|
||||
sta plotter+1
|
||||
adc plotter
|
||||
sta plotter_1
|
||||
lda plotter_1+1
|
||||
adc plotter+1
|
||||
sta plotter_1+1
|
||||
lda x
|
||||
tay
|
||||
lda bitmap_plot_bit,y
|
||||
ldy #0
|
||||
ora (plotter),y
|
||||
sta (plotter),y
|
||||
ora (plotter_1),y
|
||||
sta (plotter_1),y
|
||||
rts
|
||||
}
|
||||
// Initialize the points to be animated
|
||||
// point_init(byte zeropage(2) point_idx)
|
||||
point_init: {
|
||||
.label _0 = 9
|
||||
.label _1 = 3
|
||||
.label _3 = 7
|
||||
.label _4 = 3
|
||||
.label _9 = 3
|
||||
@ -120,20 +123,28 @@ point_init: {
|
||||
.label abs16s1_return = 3
|
||||
.label abs16s2__2 = 5
|
||||
.label abs16s2_return = 5
|
||||
.label x_stepf = 5
|
||||
.label x_stepf = 3
|
||||
.label x_diff = 9
|
||||
lda point_idx
|
||||
asl
|
||||
tax
|
||||
tay
|
||||
lda x_end,y
|
||||
sta _0
|
||||
lda x_end+1,y
|
||||
sta _0+1
|
||||
lda point_idx
|
||||
asl
|
||||
tay
|
||||
lda x_start,y
|
||||
sta _1
|
||||
lda x_start+1,y
|
||||
sta _1+1
|
||||
lda x_diff
|
||||
sec
|
||||
lda x_end,x
|
||||
sbc x_start,y
|
||||
sbc _1
|
||||
sta x_diff
|
||||
lda x_end+1,x
|
||||
sbc x_start+1,y
|
||||
lda x_diff+1
|
||||
sbc _1+1
|
||||
sta x_diff+1
|
||||
ldy point_idx
|
||||
lda y_end,y
|
||||
@ -229,8 +240,8 @@ point_init: {
|
||||
lda x_diff+1
|
||||
bmi b4
|
||||
// x add = 1.0
|
||||
ldy point_idx
|
||||
lda #$10
|
||||
ldy point_idx
|
||||
sta x_add,y
|
||||
b5:
|
||||
jsr divr16s
|
||||
@ -278,23 +289,18 @@ point_init: {
|
||||
// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5
|
||||
// divr16s(signed word zeropage(9) divisor, signed word zeropage(7) rem)
|
||||
divr16s: {
|
||||
.const dividend = 0
|
||||
.label _10 = 7
|
||||
.label _13 = 9
|
||||
.label resultu = 5
|
||||
.label return = 5
|
||||
.label _18 = 3
|
||||
.label remu = 7
|
||||
.label divisoru = 9
|
||||
.label resultu = 3
|
||||
.label return = 3
|
||||
.label divisor = 9
|
||||
.label rem = 7
|
||||
.label dividendu = 3
|
||||
.label divisoru = 9
|
||||
.label remu = 7
|
||||
lda rem+1
|
||||
bmi b1
|
||||
lda #dividend
|
||||
sta dividendu
|
||||
lda #0
|
||||
sta dividendu+1
|
||||
tay
|
||||
ldy #0
|
||||
b2:
|
||||
lda divisor+1
|
||||
bmi b3
|
||||
@ -337,10 +343,6 @@ divr16s: {
|
||||
eor #$ff
|
||||
adc #0
|
||||
sta _10+1
|
||||
lda #-dividend
|
||||
sta dividendu
|
||||
lda #0
|
||||
sta dividendu+1
|
||||
ldy #1
|
||||
jmp b2
|
||||
}
|
||||
@ -348,17 +350,19 @@ divr16s: {
|
||||
// Returns the quotient dividend/divisor.
|
||||
// The final remainder will be set into the global variable rem16u
|
||||
// Implemented using simple binary division
|
||||
// divr16u(word zeropage(3) dividend, word zeropage(9) divisor, word zeropage(7) rem)
|
||||
// divr16u(word zeropage(5) dividend, word zeropage(9) divisor, word zeropage(7) rem)
|
||||
divr16u: {
|
||||
.label rem = 7
|
||||
.label dividend = 3
|
||||
.label quotient = 5
|
||||
.label return = 5
|
||||
.label dividend = 5
|
||||
.label quotient = 3
|
||||
.label return = 3
|
||||
.label divisor = 9
|
||||
ldx #0
|
||||
txa
|
||||
sta quotient
|
||||
sta quotient+1
|
||||
sta dividend
|
||||
sta dividend+1
|
||||
b1:
|
||||
asl rem
|
||||
rol rem+1
|
||||
@ -434,11 +438,11 @@ screen_fill: {
|
||||
bitmap_clear: {
|
||||
.label bitmap = 3
|
||||
.label y = 2
|
||||
.label _3 = 3
|
||||
.label _4 = 3
|
||||
lda bitmap_plot_ylo
|
||||
sta _3
|
||||
sta _4
|
||||
lda bitmap_plot_yhi
|
||||
sta _3+1
|
||||
sta _4+1
|
||||
lda #0
|
||||
sta y
|
||||
b1:
|
||||
|
@ -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,10 +309,11 @@ lin16u_gen: {
|
||||
lda ampl+1
|
||||
sbc min+1
|
||||
sta ampl+1
|
||||
lda #$14-1
|
||||
lda #<$14-1
|
||||
sta divr16u.divisor
|
||||
lda #0
|
||||
lda #>$14-1
|
||||
sta divr16u.divisor+1
|
||||
lda #<0
|
||||
sta divr16u.rem
|
||||
sta divr16u.rem+1
|
||||
jsr divr16u
|
||||
@ -320,10 +321,11 @@ lin16u_gen: {
|
||||
sta stepi
|
||||
lda divr16u.return+1
|
||||
sta stepi+1
|
||||
lda #$14-1
|
||||
lda #<$14-1
|
||||
sta divr16u.divisor
|
||||
lda #0
|
||||
lda #>$14-1
|
||||
sta divr16u.divisor+1
|
||||
lda #<0
|
||||
sta divr16u.dividend
|
||||
sta divr16u.dividend+1
|
||||
jsr divr16u
|
||||
@ -342,7 +344,7 @@ lin16u_gen: {
|
||||
sta val+2
|
||||
lda min+1
|
||||
sta val+3
|
||||
lda #0
|
||||
lda #<0
|
||||
sta i
|
||||
sta i+1
|
||||
b1:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
15
src/test/ref/mixed-array-0.asm
Normal file
15
src/test/ref/mixed-array-0.asm
Normal file
@ -0,0 +1,15 @@
|
||||
// Test an array with mixed byte/number types
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
lda msg
|
||||
sta SCREEN
|
||||
lda msg+1
|
||||
sta SCREEN+1
|
||||
lda msg+2
|
||||
sta SCREEN+2
|
||||
rts
|
||||
msg: .byte 1, 2, 3
|
||||
}
|
15
src/test/ref/mixed-array-1.asm
Normal file
15
src/test/ref/mixed-array-1.asm
Normal file
@ -0,0 +1,15 @@
|
||||
// Test an array with mixed byte/number types
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
lda msg
|
||||
sta SCREEN
|
||||
lda msg+1
|
||||
sta SCREEN+1
|
||||
lda msg+2
|
||||
sta SCREEN+2
|
||||
rts
|
||||
msg: .byte -1, 0, 1
|
||||
}
|
@ -167,13 +167,13 @@ init: {
|
||||
lda #VIC_DEN|VIC_RSEL|3
|
||||
sta D011
|
||||
jsr plexInit
|
||||
lda #$20
|
||||
lda #<$20
|
||||
sta xp
|
||||
lda #0
|
||||
lda #>$20
|
||||
sta xp+1
|
||||
tax
|
||||
ldx #0
|
||||
b1:
|
||||
lda #$ff&SPRITE/$40
|
||||
lda #SPRITE/$40
|
||||
sta PLEX_PTR,x
|
||||
txa
|
||||
asl
|
||||
|
@ -11,6 +11,8 @@
|
||||
.const TYPEID_DWORD = 5
|
||||
.const RED = 2
|
||||
.const GREEN = 5
|
||||
.label SCREEN = $400
|
||||
.label COLS = $d800
|
||||
main: {
|
||||
ldx #0
|
||||
lda #TYPEID_SIGNED_BYTE
|
||||
@ -167,14 +169,14 @@ assertType: {
|
||||
cmp t2
|
||||
beq b1
|
||||
lda #RED
|
||||
sta $d800,x
|
||||
sta COLS,x
|
||||
b2:
|
||||
tya
|
||||
sta $400,x
|
||||
sta SCREEN,x
|
||||
inx
|
||||
rts
|
||||
b1:
|
||||
lda #GREEN
|
||||
sta $d800,x
|
||||
sta COLS,x
|
||||
jmp b2
|
||||
}
|
||||
|
@ -9,11 +9,9 @@
|
||||
.label SCREEN = $400
|
||||
main: {
|
||||
.const dw = $2000
|
||||
.const w1 = dw&$ffff
|
||||
.const w2 = <dw+1
|
||||
lda #<w1
|
||||
.const w2 = dw+1&$ffff
|
||||
lda #0
|
||||
sta SCREEN
|
||||
lda #>w1
|
||||
sta SCREEN+1
|
||||
lda #<w2
|
||||
sta SCREEN+3
|
||||
|
@ -7,7 +7,6 @@ main: {
|
||||
.label screen = $400
|
||||
// Increment on a const named pointer
|
||||
.label BGCOL = $d020
|
||||
.label sc2 = screen+$51
|
||||
ldx #0
|
||||
// RValue pointer expression (variable)
|
||||
b1:
|
||||
@ -17,7 +16,7 @@ main: {
|
||||
cpx #$b
|
||||
bne b1
|
||||
lda screen+$79
|
||||
sta sc2
|
||||
sta screen+$51
|
||||
// LValue pointer expression (constant - directly)
|
||||
lda screen+$7a
|
||||
sta screen+$52
|
||||
|
@ -7,11 +7,11 @@
|
||||
.label SPRITES_XMSB = $d010
|
||||
main: {
|
||||
.label xpos = 2
|
||||
lda #$c8
|
||||
lda #<$c8
|
||||
sta xpos
|
||||
lda #0
|
||||
lda #>$c8
|
||||
sta xpos+1
|
||||
tax
|
||||
ldx #0
|
||||
b1:
|
||||
stx position_sprite.spriteno
|
||||
jsr position_sprite
|
||||
|
@ -172,10 +172,11 @@ mul8u: {
|
||||
.label mb = 6
|
||||
.label res = 4
|
||||
.label return = 4
|
||||
lda #b
|
||||
lda #<b
|
||||
sta mb
|
||||
lda #0
|
||||
lda #>b
|
||||
sta mb+1
|
||||
lda #<0
|
||||
sta res
|
||||
sta res+1
|
||||
b1:
|
||||
|
@ -730,10 +730,11 @@ mul8u: {
|
||||
.label mb = 2
|
||||
.label res = 8
|
||||
.label return = 8
|
||||
lda #SIZEOF_ENTRY
|
||||
lda #<SIZEOF_ENTRY
|
||||
sta mb
|
||||
lda #0
|
||||
lda #>SIZEOF_ENTRY
|
||||
sta mb+1
|
||||
lda #<0
|
||||
sta res
|
||||
sta res+1
|
||||
b1:
|
||||
|
@ -2,22 +2,25 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.label print_line_cursor = 2
|
||||
.label print_line_cursor = 3
|
||||
.label print_char_cursor = 7
|
||||
main: {
|
||||
ldy #0
|
||||
.label i = 2
|
||||
lda #0
|
||||
sta i
|
||||
b1:
|
||||
tya
|
||||
lda i
|
||||
ldx #$80
|
||||
jsr sub
|
||||
tya
|
||||
lda i
|
||||
ldx #$40
|
||||
jsr sub
|
||||
tya
|
||||
lda i
|
||||
ldx #$40
|
||||
jsr sub
|
||||
iny
|
||||
cpy #9
|
||||
inc i
|
||||
lda #9
|
||||
cmp i
|
||||
bne b1
|
||||
jsr print_cls
|
||||
lda #<$400
|
||||
@ -71,9 +74,9 @@ print_ln: {
|
||||
rts
|
||||
}
|
||||
// Print a signed word as HEX
|
||||
// print_sword(signed word zeropage(4) w)
|
||||
// print_sword(signed word zeropage(5) w)
|
||||
print_sword: {
|
||||
.label w = 4
|
||||
.label w = 5
|
||||
lda w+1
|
||||
bpl b1
|
||||
lda #'-'
|
||||
@ -92,19 +95,21 @@ print_sword: {
|
||||
rts
|
||||
}
|
||||
// Print a word as HEX
|
||||
// print_word(word zeropage(5) w)
|
||||
print_word: {
|
||||
lda print_sword.w+1
|
||||
.label w = 5
|
||||
lda w+1
|
||||
sta print_byte.b
|
||||
jsr print_byte
|
||||
lda print_sword.w
|
||||
lda w
|
||||
sta print_byte.b
|
||||
jsr print_byte
|
||||
rts
|
||||
}
|
||||
// Print a byte as HEX
|
||||
// print_byte(byte zeropage(6) b)
|
||||
// print_byte(byte zeropage(2) b)
|
||||
print_byte: {
|
||||
.label b = 6
|
||||
.label b = 2
|
||||
lda b
|
||||
lsr
|
||||
lsr
|
||||
@ -133,7 +138,7 @@ print_char: {
|
||||
}
|
||||
// Clear the screen. Also resets current line/char cursor.
|
||||
print_cls: {
|
||||
.label sc = 2
|
||||
.label sc = 3
|
||||
lda #<$400
|
||||
sta sc
|
||||
lda #>$400
|
||||
@ -156,16 +161,20 @@ print_cls: {
|
||||
}
|
||||
// sub(byte register(A) idx, byte register(X) s)
|
||||
sub: {
|
||||
.label _1 = 3
|
||||
asl
|
||||
tay
|
||||
txa
|
||||
sta _1
|
||||
lda #0
|
||||
sta _1+1
|
||||
lda words,y
|
||||
sec
|
||||
stx $ff
|
||||
tax
|
||||
lda words,x
|
||||
sbc $ff
|
||||
sta words,x
|
||||
bcs !+
|
||||
dec words+1,x
|
||||
!:
|
||||
sbc _1
|
||||
sta words,y
|
||||
lda words+1,y
|
||||
sbc _1+1
|
||||
sta words+1,y
|
||||
rts
|
||||
}
|
||||
print_hextab: .text "0123456789abcdef"
|
||||
|
@ -25,21 +25,22 @@
|
||||
.label yvel_22 = 6
|
||||
main: {
|
||||
jsr init
|
||||
lda #$64
|
||||
lda #<$64
|
||||
sta yvel_init
|
||||
lda #0
|
||||
lda #>$64
|
||||
sta yvel_init+1
|
||||
lda #$c8
|
||||
lda #<$c8
|
||||
sta xvel
|
||||
lda #0
|
||||
lda #>$c8
|
||||
sta xvel+1
|
||||
lda #<0
|
||||
sta ypos
|
||||
sta ypos+1
|
||||
sta xpos
|
||||
sta xpos+1
|
||||
lda #$64
|
||||
lda #<$64
|
||||
sta yvel_12
|
||||
lda #0
|
||||
lda #>$64
|
||||
sta yvel_12+1
|
||||
b1:
|
||||
lda #$ff
|
||||
@ -64,13 +65,20 @@ anim: {
|
||||
eor #$ff
|
||||
adc #0
|
||||
sta xvel+1
|
||||
lda #$a
|
||||
sta $fe
|
||||
ora #$7f
|
||||
bmi !+
|
||||
lda #0
|
||||
!:
|
||||
sta $ff
|
||||
sec
|
||||
lda yvel_init
|
||||
sbc #$a
|
||||
sbc $fe
|
||||
sta yvel_init
|
||||
bcs !+
|
||||
dec yvel_init+1
|
||||
!:
|
||||
lda yvel_init+1
|
||||
sbc $ff
|
||||
sta yvel_init+1
|
||||
lda yvel_init
|
||||
cmp #<-$c8
|
||||
lda yvel_init+1
|
||||
@ -79,16 +87,16 @@ anim: {
|
||||
eor #$80
|
||||
!:
|
||||
bpl b3
|
||||
lda #$c8
|
||||
lda #<$c8
|
||||
sta yvel
|
||||
lda #0
|
||||
lda #>$c8
|
||||
sta yvel+1
|
||||
b3:
|
||||
lda yvel
|
||||
sta yvel_22
|
||||
lda yvel+1
|
||||
sta yvel_22+1
|
||||
lda #0
|
||||
lda #<0
|
||||
sta ypos
|
||||
sta ypos+1
|
||||
sta xpos
|
||||
@ -182,7 +190,7 @@ init: {
|
||||
sta SPRITES_YPOS
|
||||
lda #WHITE
|
||||
sta SPRITES_COLS
|
||||
lda #$ff&SPRITE/$40
|
||||
lda #SPRITE/$40
|
||||
sta SPRITES_PTR
|
||||
lda #<SCREEN
|
||||
sta sc
|
||||
|
@ -46,9 +46,9 @@ main: {
|
||||
lda #>f_i
|
||||
sta setMEMtoFAC.mem+1
|
||||
jsr setMEMtoFAC
|
||||
lda #$19
|
||||
lda #<$19
|
||||
sta setFAC.w
|
||||
lda #0
|
||||
lda #>$19
|
||||
sta setFAC.w+1
|
||||
jsr setFAC
|
||||
jsr divMEMbyFAC
|
||||
|
@ -112,11 +112,13 @@ print_sword: {
|
||||
rts
|
||||
}
|
||||
// Print a word as HEX
|
||||
// print_word(word zeropage(6) w)
|
||||
print_word: {
|
||||
lda print_sword.w+1
|
||||
.label w = 6
|
||||
lda w+1
|
||||
tax
|
||||
jsr print_byte
|
||||
lda print_sword.w
|
||||
lda w
|
||||
tax
|
||||
jsr print_byte
|
||||
rts
|
||||
@ -178,22 +180,24 @@ print_cls: {
|
||||
// sin16s_gen(signed word* zeropage(2) sintab)
|
||||
sin16s_gen: {
|
||||
.label _1 = 6
|
||||
.label step = $1b
|
||||
.label step = $19
|
||||
.label sintab = 2
|
||||
.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:
|
||||
@ -252,16 +256,17 @@ sin16s_gen: {
|
||||
// sin16s(dword zeropage($f) x)
|
||||
sin16s: {
|
||||
.label _4 = $f
|
||||
.label _20 = 6
|
||||
.label x = $f
|
||||
.label return = 6
|
||||
.label x1 = $1f
|
||||
.label x2 = 8
|
||||
.label x3 = 8
|
||||
.label x3_6 = $13
|
||||
.label usinx = 6
|
||||
.label x4 = 8
|
||||
.label x5 = $13
|
||||
.label x5_128 = $13
|
||||
.label x1 = $1d
|
||||
.label x2 = 6
|
||||
.label x3 = 6
|
||||
.label x3_6 = 8
|
||||
.label usinx = $1f
|
||||
.label x4 = 6
|
||||
.label x5 = 8
|
||||
.label x5_128 = 8
|
||||
.label sinx = 6
|
||||
.label isUpper = $e
|
||||
lda x+3
|
||||
@ -408,9 +413,17 @@ sin16s: {
|
||||
lda usinx+1
|
||||
adc x5_128+1
|
||||
sta usinx+1
|
||||
lda usinx
|
||||
sta sinx
|
||||
lda usinx+1
|
||||
sta sinx+1
|
||||
lda isUpper
|
||||
cmp #0
|
||||
beq b3
|
||||
lda usinx
|
||||
sta _20
|
||||
lda usinx+1
|
||||
sta _20+1
|
||||
sec
|
||||
lda sinx
|
||||
eor #$ff
|
||||
@ -425,15 +438,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(8) v1, word zeropage($13) v2, byte register(X) select)
|
||||
// mulu16_sel(word zeropage(6) v1, word zeropage(8) v2, byte register(X) select)
|
||||
mulu16_sel: {
|
||||
.label _0 = $f
|
||||
.label _1 = $f
|
||||
.label v1 = 8
|
||||
.label v2 = $13
|
||||
.label return = $13
|
||||
.label return_1 = 8
|
||||
.label return_10 = 8
|
||||
.label v1 = 6
|
||||
.label v2 = 8
|
||||
.label return = 8
|
||||
.label return_1 = 6
|
||||
.label return_10 = 6
|
||||
lda v1
|
||||
sta mul16u.a
|
||||
lda v1+1
|
||||
@ -456,12 +469,12 @@ mulu16_sel: {
|
||||
rts
|
||||
}
|
||||
// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word
|
||||
// mul16u(word zeropage($15) a, word zeropage($13) b)
|
||||
// mul16u(word zeropage($13) a, word zeropage(8) b)
|
||||
mul16u: {
|
||||
.label mb = $17
|
||||
.label a = $15
|
||||
.label a = $13
|
||||
.label mb = $15
|
||||
.label res = $f
|
||||
.label b = $13
|
||||
.label b = 8
|
||||
.label return = $f
|
||||
lda b
|
||||
sta mb
|
||||
@ -472,7 +485,9 @@ mul16u: {
|
||||
sta mb+3
|
||||
sta res
|
||||
sta res+1
|
||||
lda #<0>>$10
|
||||
sta res+2
|
||||
lda #>0>>$10
|
||||
sta res+3
|
||||
b1:
|
||||
lda a
|
||||
@ -513,12 +528,12 @@ mul16u: {
|
||||
div32u16u: {
|
||||
.label quotient_hi = 8
|
||||
.label quotient_lo = 6
|
||||
.label return = $1b
|
||||
.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
|
||||
|
@ -129,11 +129,13 @@ print_sword: {
|
||||
rts
|
||||
}
|
||||
// Print a word as HEX
|
||||
// print_word(word zeropage(8) w)
|
||||
print_word: {
|
||||
lda print_sword.w+1
|
||||
.label w = 8
|
||||
lda w+1
|
||||
sta print_byte.b
|
||||
jsr print_byte
|
||||
lda print_sword.w
|
||||
lda w
|
||||
sta print_byte.b
|
||||
jsr print_byte
|
||||
rts
|
||||
@ -196,23 +198,25 @@ print_cls: {
|
||||
// wavelength - the number of sinus points in a total sinus wavelength (the size of the table)
|
||||
// sin16s_genb(signed word* zeropage(2) sintab)
|
||||
sin16s_genb: {
|
||||
.label _2 = 8
|
||||
.label step = $1d
|
||||
.label _2 = 6
|
||||
.label step = $1b
|
||||
.label sintab = 2
|
||||
.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:
|
||||
@ -266,17 +270,18 @@ sin16s_genb: {
|
||||
// result: signed word sin(x) s[0.15] - using the full range -$7fff - $7fff
|
||||
// sin16sb(word zeropage(6) x)
|
||||
sin16sb: {
|
||||
.label _19 = 6
|
||||
.label x = 6
|
||||
.label return = 8
|
||||
.label return = 6
|
||||
.label x1 = 6
|
||||
.label x2 = $b
|
||||
.label x3 = $b
|
||||
.label x3_6 = $11
|
||||
.label usinx = 8
|
||||
.label x4 = $b
|
||||
.label x5 = $11
|
||||
.label x5_128 = $11
|
||||
.label sinx = 8
|
||||
.label x2 = 8
|
||||
.label x3 = 8
|
||||
.label x3_6 = $b
|
||||
.label usinx = $1f
|
||||
.label x4 = 8
|
||||
.label x5 = $b
|
||||
.label x5_128 = $b
|
||||
.label sinx = 6
|
||||
.label isUpper = $a
|
||||
lda x+1
|
||||
cmp #>PI_u4f12
|
||||
@ -388,9 +393,17 @@ sin16sb: {
|
||||
lda usinx+1
|
||||
adc x5_128+1
|
||||
sta usinx+1
|
||||
lda usinx
|
||||
sta sinx
|
||||
lda usinx+1
|
||||
sta sinx+1
|
||||
lda isUpper
|
||||
cmp #0
|
||||
beq b3
|
||||
lda usinx
|
||||
sta _19
|
||||
lda usinx+1
|
||||
sta _19+1
|
||||
sec
|
||||
lda sinx
|
||||
eor #$ff
|
||||
@ -405,19 +418,19 @@ sin16sb: {
|
||||
}
|
||||
// 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($b) v1, word zeropage($11) v2, byte register(X) select)
|
||||
// mulu16_sel(word zeropage(8) v1, word zeropage($b) v2, byte register(X) select)
|
||||
mulu16_sel: {
|
||||
.label _0 = $15
|
||||
.label _1 = $15
|
||||
.label v1 = $b
|
||||
.label v2 = $11
|
||||
.label return = $b
|
||||
.label return_11 = $11
|
||||
.label return_14 = $11
|
||||
.label return_16 = $11
|
||||
.label return_17 = $11
|
||||
.label return_18 = $11
|
||||
.label return_20 = $11
|
||||
.label _0 = $13
|
||||
.label _1 = $13
|
||||
.label v1 = 8
|
||||
.label v2 = $b
|
||||
.label return = 8
|
||||
.label return_11 = $b
|
||||
.label return_14 = $b
|
||||
.label return_16 = $b
|
||||
.label return_17 = $b
|
||||
.label return_18 = $b
|
||||
.label return_20 = $b
|
||||
lda v1
|
||||
sta mul16u.a
|
||||
lda v1+1
|
||||
@ -440,13 +453,13 @@ mulu16_sel: {
|
||||
rts
|
||||
}
|
||||
// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word
|
||||
// mul16u(word zeropage($13) a, word zeropage($11) b)
|
||||
// mul16u(word zeropage($11) a, word zeropage($b) b)
|
||||
mul16u: {
|
||||
.label mb = $19
|
||||
.label a = $13
|
||||
.label res = $15
|
||||
.label b = $11
|
||||
.label return = $15
|
||||
.label a = $11
|
||||
.label mb = $17
|
||||
.label res = $13
|
||||
.label b = $b
|
||||
.label return = $13
|
||||
lda b
|
||||
sta mb
|
||||
lda b+1
|
||||
@ -456,7 +469,9 @@ mul16u: {
|
||||
sta mb+3
|
||||
sta res
|
||||
sta res+1
|
||||
lda #<0>>$10
|
||||
sta res+2
|
||||
lda #>0>>$10
|
||||
sta res+3
|
||||
b1:
|
||||
lda a
|
||||
@ -497,12 +512,12 @@ mul16u: {
|
||||
div32u16u: {
|
||||
.label quotient_hi = 8
|
||||
.label quotient_lo = 6
|
||||
.label return = $1d
|
||||
.label return = $1b
|
||||
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
|
||||
@ -585,22 +600,24 @@ divr16u: {
|
||||
// sin16s_gen(signed word* zeropage(2) sintab)
|
||||
sin16s_gen: {
|
||||
.label _1 = 6
|
||||
.label step = $1d
|
||||
.label step = $1b
|
||||
.label sintab = 2
|
||||
.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:
|
||||
@ -656,19 +673,20 @@ sin16s_gen: {
|
||||
// Calculate signed word sinus sin(x)
|
||||
// x: unsigned dword input u[4.28] in the interval $00000000 - PI2_u4f28
|
||||
// result: signed word sin(x) s[0.15] - using the full range -$7fff - $7fff
|
||||
// sin16s(dword zeropage($15) x)
|
||||
// sin16s(dword zeropage($13) x)
|
||||
sin16s: {
|
||||
.label _4 = $15
|
||||
.label x = $15
|
||||
.label _4 = $13
|
||||
.label _20 = 6
|
||||
.label x = $13
|
||||
.label return = 6
|
||||
.label x1 = 8
|
||||
.label x2 = $b
|
||||
.label x3 = $b
|
||||
.label x3_6 = $11
|
||||
.label usinx = 6
|
||||
.label x4 = $b
|
||||
.label x5 = $11
|
||||
.label x5_128 = $11
|
||||
.label x1 = 6
|
||||
.label x2 = 8
|
||||
.label x3 = 8
|
||||
.label x3_6 = $b
|
||||
.label usinx = $1f
|
||||
.label x4 = 8
|
||||
.label x5 = $b
|
||||
.label x5_128 = $b
|
||||
.label sinx = 6
|
||||
.label isUpper = $a
|
||||
lda x+3
|
||||
@ -815,9 +833,17 @@ sin16s: {
|
||||
lda usinx+1
|
||||
adc x5_128+1
|
||||
sta usinx+1
|
||||
lda usinx
|
||||
sta sinx
|
||||
lda usinx+1
|
||||
sta sinx+1
|
||||
lda isUpper
|
||||
cmp #0
|
||||
beq b3
|
||||
lda usinx
|
||||
sta _20
|
||||
lda usinx+1
|
||||
sta _20+1
|
||||
sec
|
||||
lda sinx
|
||||
eor #$ff
|
||||
|
@ -11,6 +11,7 @@
|
||||
.label print_char_cursor = 5
|
||||
main: {
|
||||
.label wavelength = $c0
|
||||
.label _2 = 4
|
||||
.label sb = 4
|
||||
jsr sin8s_gen
|
||||
jsr print_cls
|
||||
@ -20,9 +21,11 @@ main: {
|
||||
sta print_char_cursor+1
|
||||
ldx #0
|
||||
b1:
|
||||
lda sintabref,x
|
||||
sta _2
|
||||
lda sintab2,x
|
||||
sec
|
||||
sbc sintabref,x
|
||||
sbc sb
|
||||
sta sb
|
||||
bmi b2
|
||||
lda #<str1
|
||||
@ -104,8 +107,10 @@ print_char: {
|
||||
rts
|
||||
}
|
||||
// Print a byte as HEX
|
||||
// print_byte(byte zeropage(4) b)
|
||||
print_byte: {
|
||||
lda print_sbyte.b
|
||||
.label b = 4
|
||||
lda b
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
@ -114,7 +119,7 @@ print_byte: {
|
||||
lda print_hextab,y
|
||||
jsr print_char
|
||||
lda #$f
|
||||
and print_sbyte.b
|
||||
and b
|
||||
tay
|
||||
lda print_hextab,y
|
||||
jsr print_char
|
||||
@ -153,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]
|
||||
@ -170,6 +175,7 @@ sin8s_gen: {
|
||||
lda x+1
|
||||
sta sin8s.x+1
|
||||
jsr sin8s
|
||||
tya
|
||||
ldy #0
|
||||
sta (sintab),y
|
||||
inc sintab
|
||||
@ -297,16 +303,17 @@ sin8s: {
|
||||
bcc b3
|
||||
dex
|
||||
b3:
|
||||
txa
|
||||
tay
|
||||
lda isUpper
|
||||
cmp #0
|
||||
beq b14
|
||||
beq b4
|
||||
txa
|
||||
eor #$ff
|
||||
clc
|
||||
adc #1
|
||||
rts
|
||||
b14:
|
||||
txa
|
||||
tay
|
||||
b4:
|
||||
rts
|
||||
}
|
||||
// Calculate val*val for two unsigned byte values - the result is 8 selected bits of the 16-bit result.
|
||||
|
@ -129,8 +129,10 @@ print_char: {
|
||||
rts
|
||||
}
|
||||
// Print a byte as HEX
|
||||
// print_byte(byte zeropage(4) b)
|
||||
print_byte: {
|
||||
lda print_sbyte.b
|
||||
.label b = 4
|
||||
lda b
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
@ -139,7 +141,7 @@ print_byte: {
|
||||
lda print_hextab,y
|
||||
jsr print_char
|
||||
lda #$f
|
||||
and print_sbyte.b
|
||||
and b
|
||||
tay
|
||||
lda print_hextab,y
|
||||
jsr print_char
|
||||
@ -179,17 +181,19 @@ 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:
|
||||
@ -248,16 +252,17 @@ sin16s_gen: {
|
||||
// sin16s(dword zeropage($b) x)
|
||||
sin16s: {
|
||||
.label _4 = $b
|
||||
.label _20 = $f
|
||||
.label x = $b
|
||||
.label return = $f
|
||||
.label x1 = $20
|
||||
.label x2 = $11
|
||||
.label x3 = $11
|
||||
.label x3_6 = $13
|
||||
.label usinx = $f
|
||||
.label x4 = $11
|
||||
.label x5 = $13
|
||||
.label x5_128 = $13
|
||||
.label x1 = $1a
|
||||
.label x2 = $f
|
||||
.label x3 = $f
|
||||
.label x3_6 = $11
|
||||
.label usinx = $20
|
||||
.label x4 = $f
|
||||
.label x5 = $11
|
||||
.label x5_128 = $11
|
||||
.label sinx = $f
|
||||
.label isUpper = 4
|
||||
lda x+3
|
||||
@ -404,9 +409,17 @@ sin16s: {
|
||||
lda usinx+1
|
||||
adc x5_128+1
|
||||
sta usinx+1
|
||||
lda usinx
|
||||
sta sinx
|
||||
lda usinx+1
|
||||
sta sinx+1
|
||||
lda isUpper
|
||||
cmp #0
|
||||
beq b3
|
||||
lda usinx
|
||||
sta _20
|
||||
lda usinx+1
|
||||
sta _20+1
|
||||
sec
|
||||
lda sinx
|
||||
eor #$ff
|
||||
@ -421,15 +434,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($11) v1, word zeropage($13) v2, byte register(X) select)
|
||||
// mulu16_sel(word zeropage($f) v1, word zeropage($11) v2, byte register(X) select)
|
||||
mulu16_sel: {
|
||||
.label _0 = $b
|
||||
.label _1 = $b
|
||||
.label v1 = $11
|
||||
.label v2 = $13
|
||||
.label return = $13
|
||||
.label return_1 = $11
|
||||
.label return_10 = $11
|
||||
.label v1 = $f
|
||||
.label v2 = $11
|
||||
.label return = $11
|
||||
.label return_1 = $f
|
||||
.label return_10 = $f
|
||||
lda v1
|
||||
sta mul16u.a
|
||||
lda v1+1
|
||||
@ -452,12 +465,12 @@ mulu16_sel: {
|
||||
rts
|
||||
}
|
||||
// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word
|
||||
// mul16u(word zeropage($15) a, word zeropage($13) b)
|
||||
// mul16u(word zeropage($13) a, word zeropage($11) b)
|
||||
mul16u: {
|
||||
.label mb = $17
|
||||
.label a = $15
|
||||
.label a = $13
|
||||
.label mb = $15
|
||||
.label res = $b
|
||||
.label b = $13
|
||||
.label b = $11
|
||||
.label return = $b
|
||||
lda b
|
||||
sta mb
|
||||
@ -468,7 +481,9 @@ mul16u: {
|
||||
sta mb+3
|
||||
sta res
|
||||
sta res+1
|
||||
lda #<0>>$10
|
||||
sta res+2
|
||||
lda #>0>>$10
|
||||
sta res+3
|
||||
b1:
|
||||
lda a
|
||||
@ -514,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
|
||||
@ -601,14 +616,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]
|
||||
@ -618,6 +633,7 @@ sin8s_gen: {
|
||||
lda x+1
|
||||
sta sin8s.x+1
|
||||
jsr sin8s
|
||||
tya
|
||||
ldy #0
|
||||
sta (sintab),y
|
||||
inc sintab
|
||||
@ -745,25 +761,26 @@ sin8s: {
|
||||
bcc b3
|
||||
dex
|
||||
b3:
|
||||
txa
|
||||
tay
|
||||
lda isUpper
|
||||
cmp #0
|
||||
beq b14
|
||||
beq b4
|
||||
txa
|
||||
eor #$ff
|
||||
clc
|
||||
adc #1
|
||||
rts
|
||||
b14:
|
||||
txa
|
||||
tay
|
||||
b4:
|
||||
rts
|
||||
}
|
||||
// Calculate val*val for two unsigned byte values - the result is 8 selected bits of the 16-bit result.
|
||||
// The select parameter indicates how many of the highest bits of the 16-bit result to skip
|
||||
// mulu8_sel(byte register(X) v1, byte register(Y) v2, byte zeropage($1b) select)
|
||||
// mulu8_sel(byte register(X) v1, byte register(Y) v2, byte zeropage($19) select)
|
||||
mulu8_sel: {
|
||||
.label _0 = $13
|
||||
.label _1 = $13
|
||||
.label select = $1b
|
||||
.label select = $19
|
||||
tya
|
||||
jsr mul8u
|
||||
ldy select
|
||||
@ -780,7 +797,7 @@ mulu8_sel: {
|
||||
// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word
|
||||
// mul8u(byte register(X) a, byte register(A) b)
|
||||
mul8u: {
|
||||
.label mb = $15
|
||||
.label mb = $1a
|
||||
.label res = $13
|
||||
.label return = $13
|
||||
sta mb
|
||||
@ -822,7 +839,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
|
||||
|
@ -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]
|
||||
@ -103,8 +103,7 @@ sin8u_table: {
|
||||
lda x+1
|
||||
sta sin8s.x+1
|
||||
jsr sin8s
|
||||
sta sinx
|
||||
tay
|
||||
sty sinx
|
||||
jsr mul8su
|
||||
lda sinx_sc+1
|
||||
tax
|
||||
@ -327,7 +326,10 @@ mul8su: {
|
||||
.label return = $f
|
||||
tya
|
||||
tax
|
||||
lda #b
|
||||
lda #<b
|
||||
sta mul8u.mb
|
||||
lda #>b
|
||||
sta mul8u.mb+1
|
||||
jsr mul8u
|
||||
cpy #0
|
||||
bpl b1
|
||||
@ -344,9 +346,7 @@ mul8u: {
|
||||
.label mb = $b
|
||||
.label res = $f
|
||||
.label return = $f
|
||||
sta mb
|
||||
lda #0
|
||||
sta mb+1
|
||||
lda #<0
|
||||
sta res
|
||||
sta res+1
|
||||
b1:
|
||||
@ -473,16 +473,17 @@ sin8s: {
|
||||
bcc b3
|
||||
dex
|
||||
b3:
|
||||
txa
|
||||
tay
|
||||
lda isUpper
|
||||
cmp #0
|
||||
beq b14
|
||||
beq b4
|
||||
txa
|
||||
eor #$ff
|
||||
clc
|
||||
adc #1
|
||||
rts
|
||||
b14:
|
||||
txa
|
||||
tay
|
||||
b4:
|
||||
rts
|
||||
}
|
||||
// Calculate val*val for two unsigned byte values - the result is 8 selected bits of the 16-bit result.
|
||||
@ -493,6 +494,9 @@ mulu8_sel: {
|
||||
.label _1 = $f
|
||||
.label select = $11
|
||||
tya
|
||||
sta mul8u.mb
|
||||
lda #0
|
||||
sta mul8u.mb+1
|
||||
jsr mul8u
|
||||
ldy select
|
||||
beq !e+
|
||||
|
@ -6,6 +6,7 @@
|
||||
.const SIZEOF_BYTE = 1
|
||||
.const SIZEOF_WORD = 2
|
||||
.const SIZEOF_POINTER = 2
|
||||
.const SIZEOF_NUMBER = $ff
|
||||
main: {
|
||||
.const sz = $f
|
||||
.label b = 2
|
||||
@ -15,13 +16,16 @@ main: {
|
||||
sta b
|
||||
sta w
|
||||
sta w+1
|
||||
lda #'0'+SIZEOF_BYTE
|
||||
//byte[] sb = { 'a', 'b', 'c', 0};
|
||||
lda #'0'+SIZEOF_NUMBER
|
||||
sta SCREEN
|
||||
lda #'0'+SIZEOF_BYTE
|
||||
sta SCREEN+1
|
||||
sta SCREEN+2
|
||||
sta SCREEN+3
|
||||
lda #'0'+SIZEOF_WORD
|
||||
lda #'0'+SIZEOF_NUMBER
|
||||
sta SCREEN+5
|
||||
lda #'0'+SIZEOF_WORD
|
||||
sta SCREEN+6
|
||||
lda #'0'+SIZEOF_POINTER
|
||||
sta SCREEN+8
|
||||
@ -36,7 +40,5 @@ main: {
|
||||
sta SCREEN+$e
|
||||
lda #'0'+8*SIZEOF_BYTE
|
||||
sta SCREEN+$f
|
||||
lda #'0'+$c*SIZEOF_BYTE
|
||||
sta SCREEN+$10
|
||||
rts
|
||||
}
|
||||
|
@ -323,11 +323,13 @@ print_sword: {
|
||||
rts
|
||||
}
|
||||
// Print a word as HEX
|
||||
// print_word(word zeropage($a) w)
|
||||
print_word: {
|
||||
lda print_sword.w+1
|
||||
.label w = $a
|
||||
lda w+1
|
||||
sta print_byte.b
|
||||
jsr print_byte
|
||||
lda print_sword.w
|
||||
lda w
|
||||
sta print_byte.b
|
||||
jsr print_byte
|
||||
rts
|
||||
|
@ -4,8 +4,8 @@
|
||||
.pc = $80d "Program"
|
||||
.label print_char_cursor = 8
|
||||
.label print_line_cursor = 3
|
||||
.label rem16u = $a
|
||||
.label rem16s = $a
|
||||
.label rem16u = $e
|
||||
.label rem16s = $e
|
||||
main: {
|
||||
jsr print_cls
|
||||
jsr test_8u
|
||||
@ -17,7 +17,7 @@ main: {
|
||||
test_16s: {
|
||||
.label dividend = 5
|
||||
.label divisor = $13
|
||||
.label res = $e
|
||||
.label res = $c
|
||||
.label i = 2
|
||||
lda #0
|
||||
sta i
|
||||
@ -198,7 +198,7 @@ print_str: {
|
||||
// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5
|
||||
// div16s(signed word zeropage(5) dividend, signed word zeropage($13) divisor)
|
||||
div16s: {
|
||||
.label return = $e
|
||||
.label return = $c
|
||||
.label dividend = 5
|
||||
.label divisor = $13
|
||||
lda dividend
|
||||
@ -217,25 +217,21 @@ div16s: {
|
||||
// Implemented using simple binary division
|
||||
// Follows the C99 standard by truncating toward zero on negative results.
|
||||
// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5
|
||||
// divr16s(signed word zeropage(8) dividend, signed word zeropage($c) divisor)
|
||||
// divr16s(signed word zeropage(8) dividend, signed word zeropage($a) divisor)
|
||||
divr16s: {
|
||||
.const rem = 0
|
||||
.label _8 = 8
|
||||
.label _13 = $c
|
||||
.label resultu = $e
|
||||
.label return = $e
|
||||
.label dividend = 8
|
||||
.label divisor = $c
|
||||
.label _13 = $a
|
||||
.label _16 = $e
|
||||
.label _18 = $c
|
||||
.label dividendu = 8
|
||||
.label divisoru = $c
|
||||
.label remu = $a
|
||||
.label divisoru = $a
|
||||
.label resultu = $c
|
||||
.label return = $c
|
||||
.label dividend = 8
|
||||
.label divisor = $a
|
||||
lda dividend+1
|
||||
bmi b1
|
||||
lda #rem
|
||||
sta remu
|
||||
lda #0
|
||||
sta remu+1
|
||||
tay
|
||||
ldy #0
|
||||
b2:
|
||||
lda divisor+1
|
||||
bmi b3
|
||||
@ -287,10 +283,6 @@ divr16s: {
|
||||
eor #$ff
|
||||
adc #0
|
||||
sta _8+1
|
||||
lda #-rem
|
||||
sta remu
|
||||
lda #0
|
||||
sta remu+1
|
||||
ldy #1
|
||||
jmp b2
|
||||
}
|
||||
@ -298,17 +290,19 @@ divr16s: {
|
||||
// Returns the quotient dividend/divisor.
|
||||
// The final remainder will be set into the global variable rem16u
|
||||
// Implemented using simple binary division
|
||||
// divr16u(word zeropage(8) dividend, word zeropage($c) divisor, word zeropage($a) rem)
|
||||
// divr16u(word zeropage(8) dividend, word zeropage($a) divisor, word zeropage($e) rem)
|
||||
divr16u: {
|
||||
.label rem = $a
|
||||
.label rem = $e
|
||||
.label dividend = 8
|
||||
.label quotient = $e
|
||||
.label return = $e
|
||||
.label divisor = $c
|
||||
.label quotient = $c
|
||||
.label return = $c
|
||||
.label divisor = $a
|
||||
ldx #0
|
||||
txa
|
||||
sta quotient
|
||||
sta quotient+1
|
||||
sta rem
|
||||
sta rem+1
|
||||
b1:
|
||||
asl rem
|
||||
rol rem+1
|
||||
@ -446,7 +440,7 @@ div8s: {
|
||||
tay
|
||||
lda neg
|
||||
cmp #0
|
||||
beq b9
|
||||
beq b5
|
||||
txa
|
||||
eor #$ff
|
||||
clc
|
||||
@ -457,7 +451,7 @@ div8s: {
|
||||
clc
|
||||
adc #1
|
||||
rts
|
||||
b9:
|
||||
b5:
|
||||
tya
|
||||
rts
|
||||
b3:
|
||||
@ -537,8 +531,8 @@ divr8u: {
|
||||
}
|
||||
test_16u: {
|
||||
.label dividend = 5
|
||||
.label divisor = $c
|
||||
.label res = $e
|
||||
.label divisor = $a
|
||||
.label res = $c
|
||||
.label i = 2
|
||||
lda #0
|
||||
sta i
|
||||
@ -606,18 +600,15 @@ test_16u: {
|
||||
// Returns the quotient dividend/divisor.
|
||||
// The remainder will be set into the global variable rem16u
|
||||
// Implemented using simple binary division
|
||||
// div16u(word zeropage(5) dividend, word zeropage($c) divisor)
|
||||
// div16u(word zeropage(5) dividend, word zeropage($a) divisor)
|
||||
div16u: {
|
||||
.label return = $e
|
||||
.label return = $c
|
||||
.label dividend = 5
|
||||
.label divisor = $c
|
||||
.label divisor = $a
|
||||
lda dividend
|
||||
sta divr16u.dividend
|
||||
lda dividend+1
|
||||
sta divr16u.dividend+1
|
||||
lda #0
|
||||
sta divr16u.rem
|
||||
sta divr16u.rem+1
|
||||
jsr divr16u
|
||||
rts
|
||||
}
|
||||
|
@ -340,7 +340,9 @@ print_sword: {
|
||||
// mulf16s(signed word zeropage(3) a, signed word zeropage(5) b)
|
||||
mulf16s: {
|
||||
.label _9 = 9
|
||||
.label _10 = $15
|
||||
.label _13 = 9
|
||||
.label _14 = $15
|
||||
.label _16 = 9
|
||||
.label _17 = 9
|
||||
.label m = $11
|
||||
@ -362,12 +364,16 @@ mulf16s: {
|
||||
sta _9
|
||||
lda m+3
|
||||
sta _9+1
|
||||
lda b
|
||||
sta _10
|
||||
lda b+1
|
||||
sta _10+1
|
||||
lda _16
|
||||
sec
|
||||
sbc b
|
||||
sbc _10
|
||||
sta _16
|
||||
lda _16+1
|
||||
sbc b+1
|
||||
sbc _10+1
|
||||
sta _16+1
|
||||
lda _16
|
||||
sta m+2
|
||||
@ -380,12 +386,16 @@ mulf16s: {
|
||||
sta _13
|
||||
lda m+3
|
||||
sta _13+1
|
||||
lda a
|
||||
sta _14
|
||||
lda a+1
|
||||
sta _14+1
|
||||
lda _17
|
||||
sec
|
||||
sbc a
|
||||
sbc _14
|
||||
sta _17
|
||||
lda _17+1
|
||||
sbc a+1
|
||||
sbc _14+1
|
||||
sta _17+1
|
||||
lda _17
|
||||
sta m+2
|
||||
@ -519,21 +529,30 @@ mulf16u: {
|
||||
// mul16s(signed word zeropage(3) a, signed word zeropage(5) b)
|
||||
mul16s: {
|
||||
.label _9 = 9
|
||||
.label _10 = $15
|
||||
.label _13 = 9
|
||||
.label _14 = $15
|
||||
.label _16 = 9
|
||||
.label _17 = 9
|
||||
.label m = $19
|
||||
.label return = $19
|
||||
.label a = 3
|
||||
.label b = 5
|
||||
lda b
|
||||
sta mul16u.b
|
||||
lda b+1
|
||||
sta mul16u.b+1
|
||||
lda a
|
||||
sta mul16u.a
|
||||
lda a+1
|
||||
sta mul16u.a+1
|
||||
lda b
|
||||
sta mul16u.b
|
||||
lda b+1
|
||||
sta mul16u.b+1
|
||||
lda mul16u.b
|
||||
sta mul16u.mb
|
||||
lda mul16u.b+1
|
||||
sta mul16u.mb+1
|
||||
lda #0
|
||||
sta mul16u.mb+2
|
||||
sta mul16u.mb+3
|
||||
jsr mul16u
|
||||
lda a+1
|
||||
bpl b1
|
||||
@ -541,12 +560,16 @@ mul16s: {
|
||||
sta _9
|
||||
lda m+3
|
||||
sta _9+1
|
||||
lda b
|
||||
sta _10
|
||||
lda b+1
|
||||
sta _10+1
|
||||
lda _16
|
||||
sec
|
||||
sbc b
|
||||
sbc _10
|
||||
sta _16
|
||||
lda _16+1
|
||||
sbc b+1
|
||||
sbc _10+1
|
||||
sta _16+1
|
||||
lda _16
|
||||
sta m+2
|
||||
@ -559,12 +582,16 @@ mul16s: {
|
||||
sta _13
|
||||
lda m+3
|
||||
sta _13+1
|
||||
lda a
|
||||
sta _14
|
||||
lda a+1
|
||||
sta _14+1
|
||||
lda _17
|
||||
sec
|
||||
sbc a
|
||||
sbc _14
|
||||
sta _17
|
||||
lda _17+1
|
||||
sbc a+1
|
||||
sbc _14+1
|
||||
sta _17+1
|
||||
lda _17
|
||||
sta m+2
|
||||
@ -574,23 +601,20 @@ 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($17) b)
|
||||
// mul16u(word zeropage(9) a, word zeropage($15) b)
|
||||
mul16u: {
|
||||
.label mb = $11
|
||||
.label a = 9
|
||||
.label res = $19
|
||||
.label b = $15
|
||||
.label return = $19
|
||||
.label b = $17
|
||||
lda b
|
||||
sta mb
|
||||
lda b+1
|
||||
sta mb+1
|
||||
lda #0
|
||||
sta mb+2
|
||||
sta mb+3
|
||||
.label b_1 = $17
|
||||
lda #<0
|
||||
sta res
|
||||
sta res+1
|
||||
lda #<0>>$10
|
||||
sta res+2
|
||||
lda #>0>>$10
|
||||
sta res+3
|
||||
b1:
|
||||
lda a
|
||||
@ -643,12 +667,14 @@ 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
|
||||
@ -682,19 +708,23 @@ 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
|
||||
@ -774,6 +804,13 @@ mul16u_compare: {
|
||||
sta mul16u.a
|
||||
lda a+1
|
||||
sta mul16u.a+1
|
||||
lda mul16u.b_1
|
||||
sta mul16u.mb
|
||||
lda mul16u.b_1+1
|
||||
sta mul16u.mb+1
|
||||
lda #0
|
||||
sta mul16u.mb+2
|
||||
sta mul16u.mb+3
|
||||
jsr mul16u
|
||||
jsr mulf16u
|
||||
lda ms
|
||||
@ -822,7 +859,9 @@ mul16u_compare: {
|
||||
b5:
|
||||
iny
|
||||
cpy #$10
|
||||
bne b2
|
||||
beq !b2+
|
||||
jmp b2
|
||||
!b2:
|
||||
inc i
|
||||
lda #$10
|
||||
cmp i
|
||||
@ -926,12 +965,14 @@ 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
|
||||
@ -959,10 +1000,12 @@ 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
|
||||
}
|
||||
@ -985,7 +1028,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
|
||||
|
@ -267,26 +267,36 @@ print_sbyte: {
|
||||
// Fixes offsets introduced by using unsigned multiplication
|
||||
// mul8s(signed byte zeropage(2) a, signed byte register(Y) b)
|
||||
mul8s: {
|
||||
.label _9 = $10
|
||||
.label _13 = $10
|
||||
.label m = $c
|
||||
.label a = 2
|
||||
.label return = $c
|
||||
tya
|
||||
.label a = 2
|
||||
ldx a
|
||||
tya
|
||||
sta mul8u.mb
|
||||
lda #0
|
||||
sta mul8u.mb+1
|
||||
jsr mul8u
|
||||
lda a
|
||||
cmp #0
|
||||
bpl b1
|
||||
lda m+1
|
||||
sty $ff
|
||||
sta _9
|
||||
tya
|
||||
eor #$ff
|
||||
sec
|
||||
sbc $ff
|
||||
adc _9
|
||||
sta m+1
|
||||
b1:
|
||||
cpy #0
|
||||
bpl b2
|
||||
lda m+1
|
||||
sta _13
|
||||
lda a
|
||||
eor #$ff
|
||||
sec
|
||||
sbc a
|
||||
adc _13
|
||||
sta m+1
|
||||
b2:
|
||||
rts
|
||||
@ -297,9 +307,7 @@ mul8u: {
|
||||
.label mb = 6
|
||||
.label res = $c
|
||||
.label return = $c
|
||||
sta mb
|
||||
lda #0
|
||||
sta mb+1
|
||||
lda #<0
|
||||
sta res
|
||||
sta res+1
|
||||
b1:
|
||||
@ -331,34 +339,42 @@ mul8u: {
|
||||
mulf8s: {
|
||||
.label return = $e
|
||||
jsr mulf8u_prepare
|
||||
stx mulf8s_prepared.b
|
||||
txa
|
||||
tay
|
||||
jsr mulf8s_prepared
|
||||
rts
|
||||
}
|
||||
// Calculate fast multiply with a prepared unsigned byte to a word result
|
||||
// The prepared number is set by calling mulf8s_prepare(byte a)
|
||||
// mulf8s_prepared(signed byte zeropage(3) b)
|
||||
// mulf8s_prepared(signed byte register(Y) b)
|
||||
mulf8s_prepared: {
|
||||
.label memA = $fd
|
||||
.label _8 = $10
|
||||
.label _12 = $10
|
||||
.label m = $e
|
||||
.label b = 3
|
||||
.label return = $e
|
||||
ldx b
|
||||
tya
|
||||
tax
|
||||
jsr mulf8u_prepared
|
||||
lda memA
|
||||
cmp #0
|
||||
bpl b1
|
||||
lda m+1
|
||||
sta _8
|
||||
tya
|
||||
eor #$ff
|
||||
sec
|
||||
sbc b
|
||||
adc _8
|
||||
sta m+1
|
||||
b1:
|
||||
lda b
|
||||
cmp #0
|
||||
cpy #0
|
||||
bpl b2
|
||||
lda m+1
|
||||
sta _12
|
||||
lda memA
|
||||
eor #$ff
|
||||
sec
|
||||
sbc memA
|
||||
adc _12
|
||||
sta m+1
|
||||
b2:
|
||||
rts
|
||||
@ -411,8 +427,8 @@ muls8s: {
|
||||
bmi b6
|
||||
cmp #1
|
||||
bmi b5
|
||||
lda #0
|
||||
tay
|
||||
ldy #0
|
||||
tya
|
||||
sta m
|
||||
sta m+1
|
||||
b3:
|
||||
@ -435,13 +451,13 @@ muls8s: {
|
||||
bne b3
|
||||
rts
|
||||
b5:
|
||||
lda #0
|
||||
lda #<0
|
||||
sta return
|
||||
sta return+1
|
||||
rts
|
||||
b6:
|
||||
lda #0
|
||||
tay
|
||||
ldy #0
|
||||
tya
|
||||
sta m
|
||||
sta m+1
|
||||
b4:
|
||||
@ -484,6 +500,9 @@ mul8u_compare: {
|
||||
jsr mulf8u
|
||||
ldx a
|
||||
lda b
|
||||
sta mul8u.mb
|
||||
lda #0
|
||||
sta mul8u.mb+1
|
||||
jsr mul8u
|
||||
lda ms
|
||||
cmp mf
|
||||
@ -615,7 +634,7 @@ muls8u: {
|
||||
bne b2
|
||||
rts
|
||||
b3:
|
||||
lda #0
|
||||
lda #<0
|
||||
sta return
|
||||
sta return+1
|
||||
rts
|
||||
@ -777,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
|
||||
|
@ -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:
|
||||
|
@ -22,19 +22,33 @@ main: {
|
||||
lda #>$4d2
|
||||
sta w1+1
|
||||
b1:
|
||||
lda #$5b
|
||||
sta $fe
|
||||
ora #$7f
|
||||
bmi !+
|
||||
lda #0
|
||||
!:
|
||||
sta $ff
|
||||
sec
|
||||
lda w1
|
||||
sbc #$5b
|
||||
sbc $fe
|
||||
sta w2
|
||||
lda w1+1
|
||||
sbc #0
|
||||
sbc $ff
|
||||
sta w2+1
|
||||
lda #$29
|
||||
sta $fe
|
||||
ora #$7f
|
||||
bmi !+
|
||||
lda #0
|
||||
!:
|
||||
sta $ff
|
||||
sec
|
||||
lda w2
|
||||
sbc #$29
|
||||
sbc $fe
|
||||
sta w1
|
||||
lda w2+1
|
||||
sbc #0
|
||||
sbc $ff
|
||||
sta w1+1
|
||||
lda w1
|
||||
sta print_sword.w
|
||||
@ -102,11 +116,13 @@ print_sword: {
|
||||
rts
|
||||
}
|
||||
// Print a word as HEX
|
||||
// print_word(word zeropage(6) w)
|
||||
print_word: {
|
||||
lda print_sword.w+1
|
||||
.label w = 6
|
||||
lda w+1
|
||||
sta print_byte.b
|
||||
jsr print_byte
|
||||
lda print_sword.w
|
||||
lda w
|
||||
sta print_byte.b
|
||||
jsr print_byte
|
||||
rts
|
||||
|
@ -10,7 +10,7 @@ main: {
|
||||
.label _8 = 6
|
||||
.label _9 = 4
|
||||
.label _10 = 4
|
||||
lda #0
|
||||
lda #<0
|
||||
sta line
|
||||
sta line+1
|
||||
b1:
|
||||
|
@ -8,10 +8,12 @@ main: {
|
||||
.label pos = $501
|
||||
.label bgcol = $d021
|
||||
.const w = b*$100
|
||||
.const w2 = 1*$100+1+w+0
|
||||
.const w2 = 1*$100+1+w
|
||||
// constant inline words inside expression
|
||||
.label sc = w2
|
||||
// implicit cast to (byte*)
|
||||
lda bs+1
|
||||
sta w2
|
||||
sta sc
|
||||
lda #'m'
|
||||
cmp pos
|
||||
beq b1
|
||||
|
23
src/test/ref/type-inference.asm
Normal file
23
src/test/ref/type-inference.asm
Normal file
@ -0,0 +1,23 @@
|
||||
// Test inference of integer types in expressions
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
.label screen = $400
|
||||
.label b = 2
|
||||
lda #0
|
||||
sta b
|
||||
b1:
|
||||
lax b
|
||||
axs #-[-$30]
|
||||
lda b
|
||||
asl
|
||||
tay
|
||||
txa
|
||||
sta screen,y
|
||||
inc b
|
||||
lda #$15
|
||||
cmp b
|
||||
bne b1
|
||||
rts
|
||||
}
|
@ -10,13 +10,20 @@ main: {
|
||||
sta w
|
||||
sta w+1
|
||||
b1:
|
||||
lda #$c
|
||||
sta $fe
|
||||
ora #$7f
|
||||
bmi !+
|
||||
lda #0
|
||||
!:
|
||||
sta $ff
|
||||
sec
|
||||
lda w
|
||||
sbc #$c
|
||||
sbc $fe
|
||||
sta w
|
||||
bcs !+
|
||||
dec w+1
|
||||
!:
|
||||
lda w+1
|
||||
sbc $ff
|
||||
sta w+1
|
||||
lda w
|
||||
sta SCREEN,x
|
||||
inx
|
||||
|
@ -5,36 +5,125 @@
|
||||
.const TYPEID_BYTE = 1
|
||||
.const TYPEID_SIGNED_BYTE = 2
|
||||
.label SCREEN = $400
|
||||
.label SSCREEN = $400
|
||||
main: {
|
||||
jsr testUnsigned
|
||||
jsr testUnsignedVals
|
||||
jsr testSigned
|
||||
jsr testSignedVals
|
||||
rts
|
||||
}
|
||||
testSignedVals: {
|
||||
.const sbc1 = -$78
|
||||
.label sbv1 = 5
|
||||
lda #-$78
|
||||
sta sbv1
|
||||
sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28
|
||||
lda #sbc1
|
||||
sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1
|
||||
lda sbv1
|
||||
sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1
|
||||
lda #-$46+-$32
|
||||
sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1
|
||||
lda #sbc1+-$78
|
||||
sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1
|
||||
lda #-$78+sbc1
|
||||
sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1
|
||||
lda #-$78
|
||||
clc
|
||||
adc sbv1
|
||||
sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1
|
||||
lda #-$78
|
||||
clc
|
||||
adc sbv1
|
||||
sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1
|
||||
lda #sbc1
|
||||
clc
|
||||
adc sbv1
|
||||
sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1
|
||||
lda #sbc1
|
||||
clc
|
||||
adc sbv1
|
||||
sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1
|
||||
lda sbv1
|
||||
asl
|
||||
sta SSCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1
|
||||
rts
|
||||
}
|
||||
testSigned: {
|
||||
.label sbv1 = 3
|
||||
lda #$13
|
||||
.label sbv1 = 4
|
||||
lda #-$78
|
||||
sta sbv1
|
||||
lda #0
|
||||
sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28
|
||||
lda #TYPEID_SIGNED_BYTE
|
||||
sta SCREEN+$28
|
||||
sta SCREEN+$29
|
||||
sta SCREEN+$2a
|
||||
sta SCREEN+$2b
|
||||
sta SCREEN+$2c
|
||||
sta SCREEN+$2d
|
||||
sta SCREEN+$2e
|
||||
sta SCREEN+$2f
|
||||
sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1
|
||||
sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1
|
||||
lda #0
|
||||
sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1
|
||||
lda #TYPEID_SIGNED_BYTE
|
||||
sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1
|
||||
sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1
|
||||
sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1
|
||||
sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1
|
||||
sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1+1+$28+1+1+1+1+1+1+1+1+1+1
|
||||
rts
|
||||
}
|
||||
testUnsignedVals: {
|
||||
.const ubc1 = $fa
|
||||
.label ubv1 = 3
|
||||
lda #$fa
|
||||
sta ubv1
|
||||
sta SCREEN+$b+$28
|
||||
lda #ubc1
|
||||
sta SCREEN+$b+$28+1
|
||||
lda ubv1
|
||||
sta SCREEN+$b+$28+1+1
|
||||
lda #$78+$82
|
||||
sta SCREEN+$b+$28+1+1+1
|
||||
lda #ubc1+$fa
|
||||
sta SCREEN+$b+$28+1+1+1+1
|
||||
lda #$fa+ubc1
|
||||
sta SCREEN+$b+$28+1+1+1+1+1
|
||||
lax ubv1
|
||||
axs #-[$fa]
|
||||
stx SCREEN+$b+$28+1+1+1+1+1+1
|
||||
lax ubv1
|
||||
axs #-[$fa]
|
||||
stx SCREEN+$b+$28+1+1+1+1+1+1+1
|
||||
lda #ubc1
|
||||
clc
|
||||
adc ubv1
|
||||
sta SCREEN+$b+$28+1+1+1+1+1+1+1+1
|
||||
lda #ubc1
|
||||
clc
|
||||
adc ubv1
|
||||
sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1
|
||||
lda ubv1
|
||||
asl
|
||||
sta SCREEN+$b+$28+1+1+1+1+1+1+1+1+1+1
|
||||
rts
|
||||
}
|
||||
testUnsigned: {
|
||||
.label ubv1 = 2
|
||||
lda #$5b
|
||||
lda #$fa
|
||||
sta ubv1
|
||||
lda #TYPEID_BYTE
|
||||
lda #0
|
||||
sta SCREEN
|
||||
lda #TYPEID_BYTE
|
||||
sta SCREEN+1
|
||||
sta SCREEN+2
|
||||
lda #0
|
||||
sta SCREEN+3
|
||||
lda #TYPEID_BYTE
|
||||
sta SCREEN+4
|
||||
sta SCREEN+5
|
||||
sta SCREEN+6
|
||||
sta SCREEN+7
|
||||
sta SCREEN+8
|
||||
sta SCREEN+9
|
||||
sta SCREEN+$a
|
||||
rts
|
||||
}
|
||||
|
@ -3,19 +3,14 @@
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const b = 0
|
||||
.const w = 0
|
||||
.label ptr = 0
|
||||
.label SCREEN = $400
|
||||
main: {
|
||||
lda #b
|
||||
sta SCREEN
|
||||
lda #<w
|
||||
lda #0
|
||||
sta SCREEN+2
|
||||
lda #>w
|
||||
sta SCREEN+3
|
||||
lda #<ptr
|
||||
sta SCREEN+5
|
||||
lda #>ptr
|
||||
sta SCREEN+5
|
||||
rts
|
||||
}
|
||||
|
10
src/test/ref/valuelist-error.asm
Normal file
10
src/test/ref/valuelist-error.asm
Normal file
@ -0,0 +1,10 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
.label screen = $400
|
||||
.const w = -1*$100+-1
|
||||
lda #<w
|
||||
sta screen
|
||||
rts
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user