1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

Fixed negative numbers, zero-addition, zero inlining.

This commit is contained in:
jespergravgaard 2019-05-18 21:37:34 +02:00
parent fe41c2ba42
commit 9cec38d075
94 changed files with 1441 additions and 677 deletions

View File

@ -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);

View File

@ -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());
}

View File

@ -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);
}

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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)) {

View File

@ -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)) {

View File

@ -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)) {

View File

@ -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) {

View File

@ -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<>();

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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

View File

@ -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
View File

@ -0,0 +1,8 @@
// Test minimization of constants
import "c64"
void main() {
const byte* PLAYFIELD_CHARSET = $2800;
vicSelectGfxBank(PLAYFIELD_CHARSET);
}

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -2,7 +2,6 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.const SIZEOF_SIGNED_WORD = 2
main: {
.label screen = $400
ldx #0

View File

@ -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

View File

@ -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

View 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
}

View 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
}

View 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
}

View File

@ -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) }

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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 !+

View File

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

View File

@ -219,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

View File

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

View File

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

View File

@ -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

View File

@ -68,7 +68,7 @@ loop: {
.label _1 = 9
.label _5 = 9
.label xpos = 9
lda #0
lda #<0
sta xsin_idx
sta xsin_idx+1
b1:
@ -109,7 +109,7 @@ loop: {
lda xsin_idx
cmp #<XSIN_SIZE
bne b4
lda #0
lda #<0
sta xsin_idx
sta xsin_idx+1
b4:
@ -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

View File

@ -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

View File

@ -228,9 +228,9 @@ gen_sintab: {
lda #>f_amp
sta setMEMtoFAC.mem+1
jsr setMEMtoFAC
lda #2
lda #<2
sta setFAC.w
lda #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

View File

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

View File

@ -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
View 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
}

View File

@ -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

View File

@ -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

View File

@ -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

View 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
}

View 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
}

View 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
}

View File

@ -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"

View 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
}

View 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
}

View 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
}

View File

@ -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

View File

@ -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
}

View File

@ -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:

View File

@ -38,7 +38,7 @@ main: {
sta lin16u_gen.lintab
lda #>lintab3
sta lin16u_gen.lintab+1
lda #0
lda #<0
sta lin16u_gen.min
sta lin16u_gen.min+1
lda #<$6488
@ -76,7 +76,7 @@ main: {
lda #>str1
sta print_str.str+1
jsr print_str
lda #0
lda #<0
sta print_word.w
sta print_word.w+1
jsr print_word
@ -309,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:

View File

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

View File

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

View File

@ -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
}

View 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
}

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -86,14 +86,14 @@ sin8u_table: {
lda #>$400
sta print_line_cursor+1
jsr print_ln
lda #0
lda #<0
sta i
sta i+1
lda #<main.sintab
sta sintab
lda #>main.sintab
sta sintab+1
lda #0
lda #<0
sta x
sta x+1
// u[4.12]
@ -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+

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

@ -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

View 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
}

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View 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
}