diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index d5892af01..c801074f0 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -64,7 +64,8 @@ public class Compiler { throw new CompileError("Error parsing file " + fileStream.getSourceName() + "\n - Line: " + line + "\n - Message: " + msg); } }); - KickCParser parser = new KickCParser(new CommonTokenStream(lexer)); + CommonTokenStream tokenStream = new CommonTokenStream(lexer); + KickCParser parser = new KickCParser(tokenStream); parser.setBuildParseTree(true); parser.addErrorListener(new BaseErrorListener() { @Override @@ -78,7 +79,7 @@ public class Compiler { throw new CompileError("Error parsing file " + fileStream.getSourceName() + "\n - Line: " + line + "\n - Message: " + msg); } }); - Pass0GenerateStatementSequence pass0GenerateStatementSequence = new Pass0GenerateStatementSequence(file, parser.file(), program); + Pass0GenerateStatementSequence pass0GenerateStatementSequence = new Pass0GenerateStatementSequence(file, tokenStream, parser.file(), program); pass0GenerateStatementSequence.generate(); } catch(IOException e) { throw new CompileError("Error loading file " + fileName, e); diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmComment.java b/src/main/java/dk/camelot64/kickc/asm/AsmComment.java index 3897f5f12..f777eedd3 100644 --- a/src/main/java/dk/camelot64/kickc/asm/AsmComment.java +++ b/src/main/java/dk/camelot64/kickc/asm/AsmComment.java @@ -45,5 +45,14 @@ public class AsmComment implements AsmLine { return getAsm(); } + /** + * Get the number of lines the comment has + * @return The number of lines + */ + public long getLineCount() { + return comment.chars().filter(x -> x == '\n').count() + 1; + } + + } diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmSegment.java b/src/main/java/dk/camelot64/kickc/asm/AsmSegment.java index d0c1fdbf3..31cb80083 100644 --- a/src/main/java/dk/camelot64/kickc/asm/AsmSegment.java +++ b/src/main/java/dk/camelot64/kickc/asm/AsmSegment.java @@ -200,11 +200,6 @@ public class AsmSegment { out.append("\n"); } for(AsmLine line : lines) { - if(line instanceof AsmComment && !printState.isComments()) { - if(!((AsmComment) line).getComment().contains("Fragment")) { - continue; - } - } if(line instanceof AsmScopeEnd) { printState.decIndent(); } @@ -212,7 +207,7 @@ public class AsmSegment { out.append("["+line.getIndex()+"]"); } out.append(printState.getIndent()); - if(line instanceof AsmComment || line instanceof AsmInstruction || line instanceof AsmLabelDecl || line instanceof AsmConstant || line instanceof AsmDataNumeric || line instanceof AsmDataFill || line instanceof AsmDataString || line instanceof AsmDataAlignment || line instanceof AsmInlineKickAsm) { + if(line instanceof AsmInstruction || line instanceof AsmLabelDecl || line instanceof AsmConstant || line instanceof AsmDataNumeric || line instanceof AsmDataFill || line instanceof AsmDataString || line instanceof AsmDataAlignment || line instanceof AsmInlineKickAsm) { out.append(" "); } out.append(line.getAsm() + "\n"); diff --git a/src/main/java/dk/camelot64/kickc/model/Comment.java b/src/main/java/dk/camelot64/kickc/model/Comment.java new file mode 100644 index 000000000..4700a25b3 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/Comment.java @@ -0,0 +1,20 @@ +package dk.camelot64.kickc.model; + +/** + * A comment in the source code. + * Comments are attached to symbols and statements and + * can be output in the generated assembler code. + **/ +public class Comment { + + private String comment; + + public Comment(String comment) { + this.comment = comment; + } + + public String getComment() { + return comment; + } + +} diff --git a/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java b/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java index e1e7c5c30..063d2af7b 100644 --- a/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java +++ b/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java @@ -76,6 +76,9 @@ public class LiveRangeVariablesEffective { /** Cached alive combinations. */ Map statementAliveCombinations = new LinkedHashMap<>(); + /** Special procedure reference used to represent the ROOT scope during live range analysis.*/ + static final ProcedureRef ROOT_PROCEDURE = new ProcedureRef(""); + /** * Get all combinations of variables alive at a statement. * If the statement is inside a method the different combinations in the result arises from different calls of the method @@ -101,7 +104,7 @@ public class LiveRangeVariablesEffective { callPaths = procedureCallPaths.get(procedure.getRef()); referencedInProcedure = referenceInfo.getReferencedVars(procedure.getRef().getLabelRef()); } else { - callPaths = new CallPaths(Procedure.ROOT); + callPaths = new CallPaths(ROOT_PROCEDURE); referencedInProcedure = new ArrayList<>(); } Pass2AliasElimination.Aliases callAliases = null; diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java b/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java index ec9b6d930..47320156f 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java @@ -1,5 +1,6 @@ package dk.camelot64.kickc.model.symbols; +import dk.camelot64.kickc.model.Comment; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypeProcedure; @@ -11,19 +12,23 @@ import java.util.List; /** Symbol describing a procedure/function */ public class Procedure extends Scope { - public static final ProcedureRef ROOT = new ProcedureRef(""); + /** The return type. {@link SymbolType#VOID} if the procedure does not return a value. */ private final SymbolType returnType; + /** The names of the parameters of the procedure. */ private List parameterNames; + /** true if the procedure is declared inline. */ private boolean declaredInline; - /** The type of interrupt that the procedure serves. Null for all procedures not serving an interrupt. */ private InterruptType interruptType; + /** Comments preceeding the procedure in the source code. */ + private List comments; public Procedure(String name, SymbolType returnType, Scope parentScope) { super(name, parentScope); this.returnType = returnType; this.declaredInline = false; this.interruptType = null; + this.comments = new ArrayList<>(); } public List getParameterNames() { @@ -54,6 +59,15 @@ public class Procedure extends Scope { } } + + public List getComments() { + return comments; + } + + public void setComments(List comments) { + this.comments = comments; + } + @Override public String getFullName() { return super.getFullName(); diff --git a/src/main/java/dk/camelot64/kickc/parser/KickC.g4 b/src/main/java/dk/camelot64/kickc/parser/KickC.g4 index bcdb49bcb..f49f1ddb5 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickC.g4 +++ b/src/main/java/dk/camelot64/kickc/parser/KickC.g4 @@ -213,5 +213,5 @@ fragment NAME_CHAR : [a-zA-Z0-9_]; ASMREL: '!' NAME_CHAR* [+-]+ ; WS : [ \t\r\n\u00a0]+ -> skip ; -COMMENT_LINE : '//' ~[\r\n]* -> skip ; -COMMENT_BLOCK : '/*' .*? '*/' -> skip; \ No newline at end of file +COMMENT_LINE : '//' ~[\r\n]* -> channel(HIDDEN); +COMMENT_BLOCK : '/*' .*? '*/' -> channel(HIDDEN); \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/parser/KickCLexer.java b/src/main/java/dk/camelot64/kickc/parser/KickCLexer.java index dfdb4d8cd..f986c3a1c 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickCLexer.java +++ b/src/main/java/dk/camelot64/kickc/parser/KickCLexer.java @@ -452,14 +452,14 @@ public class KickCLexer extends Lexer { "\2\2\u036e\u036f\7\61\2\2\u036f\u0370\7\61\2\2\u0370\u0374\3\2\2\2\u0371"+ "\u0373\n\f\2\2\u0372\u0371\3\2\2\2\u0373\u0376\3\2\2\2\u0374\u0372\3\2"+ "\2\2\u0374\u0375\3\2\2\2\u0375\u0377\3\2\2\2\u0376\u0374\3\2\2\2\u0377"+ - "\u0378\b^\2\2\u0378\u00bc\3\2\2\2\u0379\u037a\7\61\2\2\u037a\u037b\7,"+ + "\u0378\b^\3\2\u0378\u00bc\3\2\2\2\u0379\u037a\7\61\2\2\u037a\u037b\7,"+ "\2\2\u037b\u037f\3\2\2\2\u037c\u037e\13\2\2\2\u037d\u037c\3\2\2\2\u037e"+ "\u0381\3\2\2\2\u037f\u0380\3\2\2\2\u037f\u037d\3\2\2\2\u0380\u0382\3\2"+ "\2\2\u0381\u037f\3\2\2\2\u0382\u0383\7,\2\2\u0383\u0384\7\61\2\2\u0384"+ - "\u0385\3\2\2\2\u0385\u0386\b_\2\2\u0386\u00be\3\2\2\2!\2\u02a7\u02af\u02ca"+ + "\u0385\3\2\2\2\u0385\u0386\b_\3\2\u0386\u00be\3\2\2\2!\2\u02a7\u02af\u02ca"+ "\u02d0\u02d2\u02db\u02e8\u02ec\u02f1\u02f8\u02fd\u0304\u0309\u0310\u0317"+ "\u031c\u0323\u0328\u032f\u0335\u0337\u033c\u0343\u0348\u0354\u035f\u0365"+ - "\u036a\u0374\u037f\3\b\2\2"; + "\u036a\u0374\u037f\4\b\2\2\2\3\2"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java index 44109429f..482552d04 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java @@ -2,10 +2,7 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.Compiler; import dk.camelot64.kickc.NumberParser; -import dk.camelot64.kickc.model.CompileError; -import dk.camelot64.kickc.model.Program; -import dk.camelot64.kickc.model.Registers; -import dk.camelot64.kickc.model.StatementSequence; +import dk.camelot64.kickc.model.*; import dk.camelot64.kickc.model.operators.Operator; import dk.camelot64.kickc.model.operators.Operators; import dk.camelot64.kickc.model.statements.*; @@ -17,7 +14,9 @@ import dk.camelot64.kickc.model.types.SymbolTypeProcedure; import dk.camelot64.kickc.model.values.*; import dk.camelot64.kickc.parser.KickCBaseVisitor; import dk.camelot64.kickc.parser.KickCParser; +import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.TerminalNode; import java.io.File; @@ -37,6 +36,8 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { private File file; /** The source ANTLR parse tree of the source file. */ private KickCParser.FileContext fileCtx; + /** The source ANTLR Token Stream (used for finding comments in the lexer input.) */ + private CommonTokenStream tokenStream; /** The program containing all compile structures. */ private Program program; @@ -45,8 +46,9 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { /** Used to build the scopes of the source file. */ private Stack scopeStack; - public Pass0GenerateStatementSequence(File file, KickCParser.FileContext fileCtx, Program program) { + public Pass0GenerateStatementSequence(File file, CommonTokenStream tokenStream, KickCParser.FileContext fileCtx, Program program) { this.file = file; + this.tokenStream = tokenStream; this.fileCtx = fileCtx; this.program = program; this.sequence = program.getStatementSequence(); @@ -112,6 +114,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { String name = ctx.NAME().getText(); Procedure procedure = getCurrentSymbols().addProcedure(name, type); addDirectives(procedure, ctx.directive()); + addComments(procedure, ctx); scopeStack.push(procedure); Label procExit = procedure.addLabel(SymbolRef.PROCEXIT_BLOCK_NAME); VariableUnversioned returnVar = null; @@ -141,6 +144,27 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { return null; } + /** + * Find comments preceding the passed context + * @param procedure + * @param ctx + */ + private void addComments(Procedure procedure, ParserRuleContext ctx) { + List comments = new ArrayList<>(); + List hiddenTokensToLeft = tokenStream.getHiddenTokensToLeft(ctx.start.getTokenIndex()); + if(hiddenTokensToLeft!=null) { + for(Token hiddenToken : hiddenTokensToLeft) { + String text = hiddenToken.getText(); + if(text.startsWith("//")) { + text = text.substring(2); + } + Comment comment = new Comment(text); + comments.add(comment); + } + } + procedure.setComments(comments); + } + @Override public List visitParameterListDecl(KickCParser.ParameterListDeclContext ctx) { ArrayList parameterDecls = new ArrayList<>(); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java index 0a657e3e6..ab659cf66 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java @@ -56,12 +56,22 @@ public class Pass4CodeGeneration { addZpLabels(asm, currentScope); for(ControlFlowBlock block : getGraph().getAllBlocks()) { if(!block.getScope().equals(currentScope)) { + // The current block is in a different scope. End the old scope. if(!ScopeRef.ROOT.equals(currentScope)) { addData(asm, currentScope); asm.addScopeEnd(); } currentScope = block.getScope(); asm.startSegment(currentScope, null, block.getLabel().getFullName()); + // Add any procedure comments + if(block.isProcedureEntry(program)) { + Procedure procedure = block.getProcedure(program); + List comments = procedure.getComments(); + for(Comment comment : comments) { + asm.addComment(comment.getComment()); + } + } + // Start the new scope asm.addScopeBegin(block.getLabel().getFullName().replace('@', 'b').replace(':', '_')); // Add all ZP labels for the scope addConstants(asm, currentScope); @@ -421,7 +431,7 @@ public class Pass4CodeGeneration { VariableRef lValueRef = (VariableRef) lValue; Registers.Register lValRegister = program.getSymbolInfos().getVariable(lValueRef).getAllocation(); if(lValRegister.getType().equals(Registers.RegisterType.REG_ALU)) { - asm.addComment(statement + " // ALU"); + //asm.addComment(statement + " // ALU"); StatementAssignment assignmentAlu = assignment; aluState.setAluAssignment(assignmentAlu); isAlu = true; @@ -429,7 +439,7 @@ public class Pass4CodeGeneration { } if(!isAlu) { if(assignment.getOperator() == null && assignment.getrValue1() == null && isRegisterCopy(lValue, assignment.getrValue2())) { - asm.addComment(lValue.toString(program) + " = " + assignment.getrValue2().toString(program) + " // register copy " + getRegister(lValue)); + //asm.addComment(lValue.toString(program) + " = " + assignment.getrValue2().toString(program) + " // register copy " + getRegister(lValue)); } else { AsmFragmentInstanceSpec asmFragmentInstanceSpec = new AsmFragmentInstanceSpec(assignment, program); AsmFragmentInstance asmFragmentInstance = AsmFragmentTemplateSynthesizer.getFragmentInstance(asmFragmentInstanceSpec, program.getLog()); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass5FixLongBranches.java b/src/main/java/dk/camelot64/kickc/passes/Pass5FixLongBranches.java index b83a87eee..82b6d83f5 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass5FixLongBranches.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass5FixLongBranches.java @@ -104,7 +104,7 @@ public class Pass5FixLongBranches extends Pass5AsmOptimization { return true; } } - getLog().append("Warning! Failed to fix long branch at " + contextLine); + throw new CompileError("Error! Failed to fix long branch at " + contextLine); } } } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass5ReindexAsmLines.java b/src/main/java/dk/camelot64/kickc/passes/Pass5ReindexAsmLines.java index cedb0f719..1c625143e 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass5ReindexAsmLines.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass5ReindexAsmLines.java @@ -20,7 +20,8 @@ public class Pass5ReindexAsmLines extends Pass5AsmOptimization { for(AsmSegment asmSegment : getAsmProgram().getSegments()) { for(AsmLine asmLine : asmSegment.getLines()) { if((asmLine instanceof AsmComment)) { - asmLine.setIndex(-1); + asmLine.setIndex(nextIndex); + nextIndex += ((AsmComment) asmLine).getLineCount(); } else if(asmLine instanceof AsmInlineKickAsm) { asmLine.setIndex(nextIndex); AsmInlineKickAsm inlineKickAsm = (AsmInlineKickAsm) asmLine; diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 73c15f4f6..3cac0dd5c 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -44,6 +44,11 @@ public class TestPrograms { AsmFragmentTemplateUsages.logUsages(log, false, false, false, false, false, false); } + @Test + public void testBgBlack() throws IOException, URISyntaxException { + compileAndCompare("bgblack"); + } + @Test public void testNoRecursionHeavy() throws IOException, URISyntaxException { compileAndCompare("no-recursion-heavy"); @@ -76,7 +81,7 @@ public class TestPrograms { //@Test //public void testRobozzle64() throws IOException, URISyntaxException { - // compileAndCompare("complex/robozzle_c64/robozzle64"); + // compileAndCompare("complex/robozzle64/robozzle64"); //} @Test @@ -251,6 +256,10 @@ public class TestPrograms { compileAndCompare("irq-kernel"); } + @Test + public void testIrqKernelMinimal() throws IOException, URISyntaxException { + compileAndCompare("irq-kernel-minimal"); + } @Test public void testIrqHyperscreen() throws IOException, URISyntaxException { diff --git a/src/test/kc/bgblack.kc b/src/test/kc/bgblack.kc new file mode 100644 index 000000000..28a9d0ce4 --- /dev/null +++ b/src/test/kc/bgblack.kc @@ -0,0 +1,4 @@ +import "c64" +void main() { + *BGCOL = BLACK; +} diff --git a/src/test/kc/irq-kernel-minimal.kc b/src/test/kc/irq-kernel-minimal.kc new file mode 100644 index 000000000..57e5f9b4b --- /dev/null +++ b/src/test/kc/irq-kernel-minimal.kc @@ -0,0 +1,16 @@ +// A minimal working IRQ + +import "c64" + +// Setup the IRQ routine +void main() { + asm { sei } + *KERNEL_IRQ = &irq; + asm { cli } +} + +// The Interrupt Handler +interrupt(kernel_keyboard) void irq() { + *BGCOL = WHITE; + *BGCOL = BLACK; +} \ No newline at end of file diff --git a/src/test/ref/array-length-symbolic-min.asm b/src/test/ref/array-length-symbolic-min.asm index d7bf5d16c..03484ba0d 100644 --- a/src/test/ref/array-length-symbolic-min.asm +++ b/src/test/ref/array-length-symbolic-min.asm @@ -2,6 +2,7 @@ :BasicUpstart(main) .pc = $80d "Program" .const SZ = $f +// Fills the array item by item with $is, where i is the item# and s is the sub# main: { ldx #0 b1: diff --git a/src/test/ref/array-length-symbolic-min.log b/src/test/ref/array-length-symbolic-min.log index 7b3d1ece8..63ec6d94d 100644 --- a/src/test/ref/array-length-symbolic-min.log +++ b/src/test/ref/array-length-symbolic-min.log @@ -159,6 +159,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Fills the array item by item with $is, where i is the item# and s is the sub# main: { .label sub = 2 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] @@ -225,6 +226,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Fills the array item by item with $is, where i is the item# and s is the sub# main: { //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] b1_from_main: @@ -314,6 +316,7 @@ Score: 161 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Fills the array item by item with $is, where i is the item# and s is the sub# main: { //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] //SEG11 [5] phi (byte) main::sub#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 diff --git a/src/test/ref/array-length-symbolic.asm b/src/test/ref/array-length-symbolic.asm index 713abe2fc..ae79e6ec2 100644 --- a/src/test/ref/array-length-symbolic.asm +++ b/src/test/ref/array-length-symbolic.asm @@ -3,6 +3,7 @@ .pc = $80d "Program" .const ITEM_COUNT = 3 .const ITEM_SIZE = 5 +// Fills the array item by item with $is, where i is the item# and s is the sub# main: { .label cur_item = 2 lda #main::@1] @@ -550,6 +552,7 @@ Score: 3416 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Fills the array item by item with $is, where i is the item# and s is the sub# main: { .label cur_item = 2 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] diff --git a/src/test/ref/assignment-chained.asm b/src/test/ref/assignment-chained.asm index 997bbe971..88c0f5380 100644 --- a/src/test/ref/assignment-chained.asm +++ b/src/test/ref/assignment-chained.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Tests that chained assignments work as intended main: { .label screen = $400 lda #'c' diff --git a/src/test/ref/assignment-chained.log b/src/test/ref/assignment-chained.log index a024eb48d..dd412eeb5 100644 --- a/src/test/ref/assignment-chained.log +++ b/src/test/ref/assignment-chained.log @@ -132,6 +132,7 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Tests that chained assignments work as intended main: { .label screen = $400 .label a = 2 @@ -199,6 +200,7 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Tests that chained assignments work as intended main: { .label screen = $400 //SEG9 [4] *((const byte*) main::screen#0) ← (byte) 'c' -- _deref_pbuc1=vbuc2 @@ -277,6 +279,7 @@ Score: 38 //SEG6 [3] phi from @1 to @end [phi:@1->@end] //SEG7 @end //SEG8 main +// Tests that chained assignments work as intended main: { .label screen = $400 //SEG9 [4] *((const byte*) main::screen#0) ← (byte) 'c' -- _deref_pbuc1=vbuc2 diff --git a/src/test/ref/bgblack.asm b/src/test/ref/bgblack.asm new file mode 100644 index 000000000..d7262d1e5 --- /dev/null +++ b/src/test/ref/bgblack.asm @@ -0,0 +1,10 @@ +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label BGCOL = $d021 + .const BLACK = 0 +main: { + lda #BLACK + sta BGCOL + rts +} diff --git a/src/test/ref/bgblack.cfg b/src/test/ref/bgblack.cfg new file mode 100644 index 000000000..c43e128d8 --- /dev/null +++ b/src/test/ref/bgblack.cfg @@ -0,0 +1,15 @@ +@begin: scope:[] from + [0] phi() + to:@5 +@5: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @5 + [3] phi() +main: scope:[main] from @5 + [4] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 + to:main::@return +main::@return: scope:[main] from main + [5] return + to:@return diff --git a/src/test/ref/bgblack.log b/src/test/ref/bgblack.log new file mode 100644 index 000000000..5f9f1d228 --- /dev/null +++ b/src/test/ref/bgblack.log @@ -0,0 +1,673 @@ +Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (byte*) PROCPORT_DDR#0 ← ((byte*)) (byte/signed byte/word/signed word/dword/signed dword) 0 + (byte) PROCPORT_DDR_MEMORY_MASK#0 ← (byte/signed byte/word/signed word/dword/signed dword) 7 + (byte*) PROCPORT#0 ← ((byte*)) (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) PROCPORT_RAM_ALL#0 ← (byte/signed byte/word/signed word/dword/signed dword) 48 + (byte) PROCPORT_RAM_IO#0 ← (byte/signed byte/word/signed word/dword/signed dword) 53 + (byte) PROCPORT_RAM_CHARROM#0 ← (byte/signed byte/word/signed word/dword/signed dword) 49 + (byte) PROCPORT_KERNEL_IO#0 ← (byte/signed byte/word/signed word/dword/signed dword) 54 + (byte) PROCPORT_BASIC_KERNEL_IO#0 ← (byte/signed byte/word/signed word/dword/signed dword) 55 + (byte*) CHARGEN#0 ← ((byte*)) (word/dword/signed dword) 53248 + (word) SPRITE_PTRS#0 ← (word/signed word/dword/signed dword) 1016 + (byte*) SPRITES_XPOS#0 ← ((byte*)) (word/dword/signed dword) 53248 + (byte*) SPRITES_YPOS#0 ← ((byte*)) (word/dword/signed dword) 53249 + (byte*) SPRITES_XMSB#0 ← ((byte*)) (word/dword/signed dword) 53264 + (byte*) RASTER#0 ← ((byte*)) (word/dword/signed dword) 53266 + (byte*) SPRITES_ENABLE#0 ← ((byte*)) (word/dword/signed dword) 53269 + (byte*) SPRITES_EXPAND_Y#0 ← ((byte*)) (word/dword/signed dword) 53271 + (byte*) SPRITES_PRIORITY#0 ← ((byte*)) (word/dword/signed dword) 53275 + (byte*) SPRITES_MC#0 ← ((byte*)) (word/dword/signed dword) 53276 + (byte*) SPRITES_EXPAND_X#0 ← ((byte*)) (word/dword/signed dword) 53277 + (byte*) BORDERCOL#0 ← ((byte*)) (word/dword/signed dword) 53280 + (byte*) BGCOL#0 ← ((byte*)) (word/dword/signed dword) 53281 + (byte*) BGCOL1#0 ← ((byte*)) (word/dword/signed dword) 53281 + (byte*) BGCOL2#0 ← ((byte*)) (word/dword/signed dword) 53282 + (byte*) BGCOL3#0 ← ((byte*)) (word/dword/signed dword) 53283 + (byte*) BGCOL4#0 ← ((byte*)) (word/dword/signed dword) 53284 + (byte*) SPRITES_MC1#0 ← ((byte*)) (word/dword/signed dword) 53285 + (byte*) SPRITES_MC2#0 ← ((byte*)) (word/dword/signed dword) 53286 + (byte*) SPRITES_COLS#0 ← ((byte*)) (word/dword/signed dword) 53287 + (byte*) VIC_CONTROL#0 ← ((byte*)) (word/dword/signed dword) 53265 + (byte*) D011#0 ← ((byte*)) (word/dword/signed dword) 53265 + (byte) VIC_RST8#0 ← (byte/word/signed word/dword/signed dword) 128 + (byte) VIC_ECM#0 ← (byte/signed byte/word/signed word/dword/signed dword) 64 + (byte) VIC_BMM#0 ← (byte/signed byte/word/signed word/dword/signed dword) 32 + (byte) VIC_DEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 16 + (byte) VIC_RSEL#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 + (byte*) VIC_CONTROL2#0 ← ((byte*)) (word/dword/signed dword) 53270 + (byte*) D016#0 ← ((byte*)) (word/dword/signed dword) 53270 + (byte) VIC_MCM#0 ← (byte/signed byte/word/signed word/dword/signed dword) 16 + (byte) VIC_CSEL#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 + (byte*) D018#0 ← ((byte*)) (word/dword/signed dword) 53272 + (byte*) VIC_MEMORY#0 ← ((byte*)) (word/dword/signed dword) 53272 + (byte*) LIGHTPEN_X#0 ← ((byte*)) (word/dword/signed dword) 53267 + (byte*) LIGHTPEN_Y#0 ← ((byte*)) (word/dword/signed dword) 53268 + (byte*) IRQ_STATUS#0 ← ((byte*)) (word/dword/signed dword) 53273 + (byte*) IRQ_ENABLE#0 ← ((byte*)) (word/dword/signed dword) 53274 + (byte) IRQ_RASTER#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) IRQ_COLLISION_BG#0 ← (byte/signed byte/word/signed word/dword/signed dword) 2 + (byte) IRQ_COLLISION_SPRITE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 4 + (byte) IRQ_LIGHTPEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 + (byte*) COLS#0 ← ((byte*)) (word/dword/signed dword) 55296 + (byte*) CIA1_PORT_A#0 ← ((byte*)) (word/dword/signed dword) 56320 + (byte*) CIA1_PORT_B#0 ← ((byte*)) (word/dword/signed dword) 56321 + (byte*) CIA1_PORT_A_DDR#0 ← ((byte*)) (word/dword/signed dword) 56322 + (byte*) CIA1_PORT_B_DDR#0 ← ((byte*)) (word/dword/signed dword) 56323 + (byte*) CIA1_INTERRUPT#0 ← ((byte*)) (word/dword/signed dword) 56333 + (byte) CIA_INTERRUPT_CLEAR#0 ← (byte/signed byte/word/signed word/dword/signed dword) 127 + (byte*) CIA2_PORT_A#0 ← ((byte*)) (word/dword/signed dword) 56576 + (byte*) CIA2_PORT_B#0 ← ((byte*)) (word/dword/signed dword) 56577 + (byte*) CIA2_PORT_A_DDR#0 ← ((byte*)) (word/dword/signed dword) 56578 + (byte*) CIA2_PORT_B_DDR#0 ← ((byte*)) (word/dword/signed dword) 56579 + (byte*) CIA2_INTERRUPT#0 ← ((byte*)) (word/dword/signed dword) 56589 + (void()**) KERNEL_IRQ#0 ← ((void()**)) (word/signed word/dword/signed dword) 788 + (void()**) HARDWARE_IRQ#0 ← ((void()**)) (word/dword/signed dword) 65534 + (byte) BLACK#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + (byte) WHITE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) RED#0 ← (byte/signed byte/word/signed word/dword/signed dword) 2 + (byte) CYAN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 3 + (byte) PURPLE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 4 + (byte) GREEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 5 + (byte) BLUE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 6 + (byte) YELLOW#0 ← (byte/signed byte/word/signed word/dword/signed dword) 7 + (byte) ORANGE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 + (byte) BROWN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 9 + (byte) PINK#0 ← (byte/signed byte/word/signed word/dword/signed dword) 10 + (byte) DARK_GREY#0 ← (byte/signed byte/word/signed word/dword/signed dword) 11 + (byte) GREY#0 ← (byte/signed byte/word/signed word/dword/signed dword) 12 + (byte) LIGHT_GREEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 13 + (byte) LIGHT_BLUE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 14 + (byte) LIGHT_GREY#0 ← (byte/signed byte/word/signed word/dword/signed dword) 15 + to:@5 +main: scope:[main] from @5 + *((byte*) BGCOL#0) ← (byte) BLACK#0 + to:main::@return +main::@return: scope:[main] from main + return + to:@return +@5: scope:[] from @begin + call main + to:@6 +@6: scope:[] from @5 + to:@end +@end: scope:[] from @6 + +SYMBOL TABLE SSA +(label) @5 +(label) @6 +(label) @begin +(label) @end +(byte*) BGCOL +(byte*) BGCOL#0 +(byte*) BGCOL1 +(byte*) BGCOL1#0 +(byte*) BGCOL2 +(byte*) BGCOL2#0 +(byte*) BGCOL3 +(byte*) BGCOL3#0 +(byte*) BGCOL4 +(byte*) BGCOL4#0 +(byte) BLACK +(byte) BLACK#0 +(byte) BLUE +(byte) BLUE#0 +(byte*) BORDERCOL +(byte*) BORDERCOL#0 +(byte) BROWN +(byte) BROWN#0 +(byte*) CHARGEN +(byte*) CHARGEN#0 +(byte*) CIA1_INTERRUPT +(byte*) CIA1_INTERRUPT#0 +(byte*) CIA1_PORT_A +(byte*) CIA1_PORT_A#0 +(byte*) CIA1_PORT_A_DDR +(byte*) CIA1_PORT_A_DDR#0 +(byte*) CIA1_PORT_B +(byte*) CIA1_PORT_B#0 +(byte*) CIA1_PORT_B_DDR +(byte*) CIA1_PORT_B_DDR#0 +(byte*) CIA2_INTERRUPT +(byte*) CIA2_INTERRUPT#0 +(byte*) CIA2_PORT_A +(byte*) CIA2_PORT_A#0 +(byte*) CIA2_PORT_A_DDR +(byte*) CIA2_PORT_A_DDR#0 +(byte*) CIA2_PORT_B +(byte*) CIA2_PORT_B#0 +(byte*) CIA2_PORT_B_DDR +(byte*) CIA2_PORT_B_DDR#0 +(byte) CIA_INTERRUPT_CLEAR +(byte) CIA_INTERRUPT_CLEAR#0 +(byte*) COLS +(byte*) COLS#0 +(byte) CYAN +(byte) CYAN#0 +(byte*) D011 +(byte*) D011#0 +(byte*) D016 +(byte*) D016#0 +(byte*) D018 +(byte*) D018#0 +(byte) DARK_GREY +(byte) DARK_GREY#0 +(byte) GREEN +(byte) GREEN#0 +(byte) GREY +(byte) GREY#0 +(void()**) HARDWARE_IRQ +(void()**) HARDWARE_IRQ#0 +(byte) IRQ_COLLISION_BG +(byte) IRQ_COLLISION_BG#0 +(byte) IRQ_COLLISION_SPRITE +(byte) IRQ_COLLISION_SPRITE#0 +(byte*) IRQ_ENABLE +(byte*) IRQ_ENABLE#0 +(byte) IRQ_LIGHTPEN +(byte) IRQ_LIGHTPEN#0 +(byte) IRQ_RASTER +(byte) IRQ_RASTER#0 +(byte*) IRQ_STATUS +(byte*) IRQ_STATUS#0 +(void()**) KERNEL_IRQ +(void()**) KERNEL_IRQ#0 +(byte*) LIGHTPEN_X +(byte*) LIGHTPEN_X#0 +(byte*) LIGHTPEN_Y +(byte*) LIGHTPEN_Y#0 +(byte) LIGHT_BLUE +(byte) LIGHT_BLUE#0 +(byte) LIGHT_GREEN +(byte) LIGHT_GREEN#0 +(byte) LIGHT_GREY +(byte) LIGHT_GREY#0 +(byte) ORANGE +(byte) ORANGE#0 +(byte) PINK +(byte) PINK#0 +(byte*) PROCPORT +(byte*) PROCPORT#0 +(byte) PROCPORT_BASIC_KERNEL_IO +(byte) PROCPORT_BASIC_KERNEL_IO#0 +(byte*) PROCPORT_DDR +(byte*) PROCPORT_DDR#0 +(byte) PROCPORT_DDR_MEMORY_MASK +(byte) PROCPORT_DDR_MEMORY_MASK#0 +(byte) PROCPORT_KERNEL_IO +(byte) PROCPORT_KERNEL_IO#0 +(byte) PROCPORT_RAM_ALL +(byte) PROCPORT_RAM_ALL#0 +(byte) PROCPORT_RAM_CHARROM +(byte) PROCPORT_RAM_CHARROM#0 +(byte) PROCPORT_RAM_IO +(byte) PROCPORT_RAM_IO#0 +(byte) PURPLE +(byte) PURPLE#0 +(byte*) RASTER +(byte*) RASTER#0 +(byte) RED +(byte) RED#0 +(byte*) SPRITES_COLS +(byte*) SPRITES_COLS#0 +(byte*) SPRITES_ENABLE +(byte*) SPRITES_ENABLE#0 +(byte*) SPRITES_EXPAND_X +(byte*) SPRITES_EXPAND_X#0 +(byte*) SPRITES_EXPAND_Y +(byte*) SPRITES_EXPAND_Y#0 +(byte*) SPRITES_MC +(byte*) SPRITES_MC#0 +(byte*) SPRITES_MC1 +(byte*) SPRITES_MC1#0 +(byte*) SPRITES_MC2 +(byte*) SPRITES_MC2#0 +(byte*) SPRITES_PRIORITY +(byte*) SPRITES_PRIORITY#0 +(byte*) SPRITES_XMSB +(byte*) SPRITES_XMSB#0 +(byte*) SPRITES_XPOS +(byte*) SPRITES_XPOS#0 +(byte*) SPRITES_YPOS +(byte*) SPRITES_YPOS#0 +(word) SPRITE_PTRS +(word) SPRITE_PTRS#0 +(byte) VIC_BMM +(byte) VIC_BMM#0 +(byte*) VIC_CONTROL +(byte*) VIC_CONTROL#0 +(byte*) VIC_CONTROL2 +(byte*) VIC_CONTROL2#0 +(byte) VIC_CSEL +(byte) VIC_CSEL#0 +(byte) VIC_DEN +(byte) VIC_DEN#0 +(byte) VIC_ECM +(byte) VIC_ECM#0 +(byte) VIC_MCM +(byte) VIC_MCM#0 +(byte*) VIC_MEMORY +(byte*) VIC_MEMORY#0 +(byte) VIC_RSEL +(byte) VIC_RSEL#0 +(byte) VIC_RST8 +(byte) VIC_RST8#0 +(byte) WHITE +(byte) WHITE#0 +(byte) YELLOW +(byte) YELLOW#0 +(void()) main() +(label) main::@return + +Culled Empty Block (label) @6 +Successful SSA optimization Pass2CullEmptyBlocks +Constant (const byte*) PROCPORT_DDR#0 = ((byte*))0 +Constant (const byte) PROCPORT_DDR_MEMORY_MASK#0 = 7 +Constant (const byte*) PROCPORT#0 = ((byte*))1 +Constant (const byte) PROCPORT_RAM_ALL#0 = 48 +Constant (const byte) PROCPORT_RAM_IO#0 = 53 +Constant (const byte) PROCPORT_RAM_CHARROM#0 = 49 +Constant (const byte) PROCPORT_KERNEL_IO#0 = 54 +Constant (const byte) PROCPORT_BASIC_KERNEL_IO#0 = 55 +Constant (const byte*) CHARGEN#0 = ((byte*))53248 +Constant (const word) SPRITE_PTRS#0 = 1016 +Constant (const byte*) SPRITES_XPOS#0 = ((byte*))53248 +Constant (const byte*) SPRITES_YPOS#0 = ((byte*))53249 +Constant (const byte*) SPRITES_XMSB#0 = ((byte*))53264 +Constant (const byte*) RASTER#0 = ((byte*))53266 +Constant (const byte*) SPRITES_ENABLE#0 = ((byte*))53269 +Constant (const byte*) SPRITES_EXPAND_Y#0 = ((byte*))53271 +Constant (const byte*) SPRITES_PRIORITY#0 = ((byte*))53275 +Constant (const byte*) SPRITES_MC#0 = ((byte*))53276 +Constant (const byte*) SPRITES_EXPAND_X#0 = ((byte*))53277 +Constant (const byte*) BORDERCOL#0 = ((byte*))53280 +Constant (const byte*) BGCOL#0 = ((byte*))53281 +Constant (const byte*) BGCOL1#0 = ((byte*))53281 +Constant (const byte*) BGCOL2#0 = ((byte*))53282 +Constant (const byte*) BGCOL3#0 = ((byte*))53283 +Constant (const byte*) BGCOL4#0 = ((byte*))53284 +Constant (const byte*) SPRITES_MC1#0 = ((byte*))53285 +Constant (const byte*) SPRITES_MC2#0 = ((byte*))53286 +Constant (const byte*) SPRITES_COLS#0 = ((byte*))53287 +Constant (const byte*) VIC_CONTROL#0 = ((byte*))53265 +Constant (const byte*) D011#0 = ((byte*))53265 +Constant (const byte) VIC_RST8#0 = 128 +Constant (const byte) VIC_ECM#0 = 64 +Constant (const byte) VIC_BMM#0 = 32 +Constant (const byte) VIC_DEN#0 = 16 +Constant (const byte) VIC_RSEL#0 = 8 +Constant (const byte*) VIC_CONTROL2#0 = ((byte*))53270 +Constant (const byte*) D016#0 = ((byte*))53270 +Constant (const byte) VIC_MCM#0 = 16 +Constant (const byte) VIC_CSEL#0 = 8 +Constant (const byte*) D018#0 = ((byte*))53272 +Constant (const byte*) VIC_MEMORY#0 = ((byte*))53272 +Constant (const byte*) LIGHTPEN_X#0 = ((byte*))53267 +Constant (const byte*) LIGHTPEN_Y#0 = ((byte*))53268 +Constant (const byte*) IRQ_STATUS#0 = ((byte*))53273 +Constant (const byte*) IRQ_ENABLE#0 = ((byte*))53274 +Constant (const byte) IRQ_RASTER#0 = 1 +Constant (const byte) IRQ_COLLISION_BG#0 = 2 +Constant (const byte) IRQ_COLLISION_SPRITE#0 = 4 +Constant (const byte) IRQ_LIGHTPEN#0 = 8 +Constant (const byte*) COLS#0 = ((byte*))55296 +Constant (const byte*) CIA1_PORT_A#0 = ((byte*))56320 +Constant (const byte*) CIA1_PORT_B#0 = ((byte*))56321 +Constant (const byte*) CIA1_PORT_A_DDR#0 = ((byte*))56322 +Constant (const byte*) CIA1_PORT_B_DDR#0 = ((byte*))56323 +Constant (const byte*) CIA1_INTERRUPT#0 = ((byte*))56333 +Constant (const byte) CIA_INTERRUPT_CLEAR#0 = 127 +Constant (const byte*) CIA2_PORT_A#0 = ((byte*))56576 +Constant (const byte*) CIA2_PORT_B#0 = ((byte*))56577 +Constant (const byte*) CIA2_PORT_A_DDR#0 = ((byte*))56578 +Constant (const byte*) CIA2_PORT_B_DDR#0 = ((byte*))56579 +Constant (const byte*) CIA2_INTERRUPT#0 = ((byte*))56589 +Constant (const void()**) KERNEL_IRQ#0 = ((void()**))788 +Constant (const void()**) HARDWARE_IRQ#0 = ((void()**))65534 +Constant (const byte) BLACK#0 = 0 +Constant (const byte) WHITE#0 = 1 +Constant (const byte) RED#0 = 2 +Constant (const byte) CYAN#0 = 3 +Constant (const byte) PURPLE#0 = 4 +Constant (const byte) GREEN#0 = 5 +Constant (const byte) BLUE#0 = 6 +Constant (const byte) YELLOW#0 = 7 +Constant (const byte) ORANGE#0 = 8 +Constant (const byte) BROWN#0 = 9 +Constant (const byte) PINK#0 = 10 +Constant (const byte) DARK_GREY#0 = 11 +Constant (const byte) GREY#0 = 12 +Constant (const byte) LIGHT_GREEN#0 = 13 +Constant (const byte) LIGHT_BLUE#0 = 14 +Constant (const byte) LIGHT_GREY#0 = 15 +Successful SSA optimization Pass2ConstantIdentification +Successful SSA optimization PassNEliminateUnusedVars +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @5 +Adding NOP phi() at start of @end +CALL GRAPH +Calls in [] to main:2 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @5 +Adding NOP phi() at start of @end + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] phi() + to:@5 +@5: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @5 + [3] phi() +main: scope:[main] from @5 + [4] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 + to:main::@return +main::@return: scope:[main] from main + [5] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(byte*) BGCOL +(byte*) BGCOL1 +(byte*) BGCOL2 +(byte*) BGCOL3 +(byte*) BGCOL4 +(byte) BLACK +(byte) BLUE +(byte*) BORDERCOL +(byte) BROWN +(byte*) CHARGEN +(byte*) CIA1_INTERRUPT +(byte*) CIA1_PORT_A +(byte*) CIA1_PORT_A_DDR +(byte*) CIA1_PORT_B +(byte*) CIA1_PORT_B_DDR +(byte*) CIA2_INTERRUPT +(byte*) CIA2_PORT_A +(byte*) CIA2_PORT_A_DDR +(byte*) CIA2_PORT_B +(byte*) CIA2_PORT_B_DDR +(byte) CIA_INTERRUPT_CLEAR +(byte*) COLS +(byte) CYAN +(byte*) D011 +(byte*) D016 +(byte*) D018 +(byte) DARK_GREY +(byte) GREEN +(byte) GREY +(void()**) HARDWARE_IRQ +(byte) IRQ_COLLISION_BG +(byte) IRQ_COLLISION_SPRITE +(byte*) IRQ_ENABLE +(byte) IRQ_LIGHTPEN +(byte) IRQ_RASTER +(byte*) IRQ_STATUS +(void()**) KERNEL_IRQ +(byte*) LIGHTPEN_X +(byte*) LIGHTPEN_Y +(byte) LIGHT_BLUE +(byte) LIGHT_GREEN +(byte) LIGHT_GREY +(byte) ORANGE +(byte) PINK +(byte*) PROCPORT +(byte) PROCPORT_BASIC_KERNEL_IO +(byte*) PROCPORT_DDR +(byte) PROCPORT_DDR_MEMORY_MASK +(byte) PROCPORT_KERNEL_IO +(byte) PROCPORT_RAM_ALL +(byte) PROCPORT_RAM_CHARROM +(byte) PROCPORT_RAM_IO +(byte) PURPLE +(byte*) RASTER +(byte) RED +(byte*) SPRITES_COLS +(byte*) SPRITES_ENABLE +(byte*) SPRITES_EXPAND_X +(byte*) SPRITES_EXPAND_Y +(byte*) SPRITES_MC +(byte*) SPRITES_MC1 +(byte*) SPRITES_MC2 +(byte*) SPRITES_PRIORITY +(byte*) SPRITES_XMSB +(byte*) SPRITES_XPOS +(byte*) SPRITES_YPOS +(word) SPRITE_PTRS +(byte) VIC_BMM +(byte*) VIC_CONTROL +(byte*) VIC_CONTROL2 +(byte) VIC_CSEL +(byte) VIC_DEN +(byte) VIC_ECM +(byte) VIC_MCM +(byte*) VIC_MEMORY +(byte) VIC_RSEL +(byte) VIC_RST8 +(byte) WHITE +(byte) YELLOW +(void()) main() + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label BGCOL = $d021 + .const BLACK = 0 +//SEG2 @begin +bbegin: +//SEG3 [1] phi from @begin to @5 [phi:@begin->@5] +b5_from_bbegin: + jmp b5 +//SEG4 @5 +b5: +//SEG5 [2] call main + jsr main +//SEG6 [3] phi from @5 to @end [phi:@5->@end] +bend_from_b5: + jmp bend +//SEG7 @end +bend: +//SEG8 main +main: { + //SEG9 [4] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 + lda #BLACK + sta BGCOL + jmp breturn + //SEG10 main::@return + breturn: + //SEG11 [5] return + rts +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( main:2 [ ] ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [] + +Uplifting [main] best 27 combination +Uplifting [] best 27 combination + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label BGCOL = $d021 + .const BLACK = 0 +//SEG2 @begin +bbegin: +//SEG3 [1] phi from @begin to @5 [phi:@begin->@5] +b5_from_bbegin: + jmp b5 +//SEG4 @5 +b5: +//SEG5 [2] call main + jsr main +//SEG6 [3] phi from @5 to @end [phi:@5->@end] +bend_from_b5: + jmp bend +//SEG7 @end +bend: +//SEG8 main +main: { + //SEG9 [4] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 + lda #BLACK + sta BGCOL + jmp breturn + //SEG10 main::@return + breturn: + //SEG11 [5] return + rts +} + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b5 +Removing instruction jmp bend +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction b5_from_bbegin: +Removing instruction b5: +Removing instruction bend_from_b5: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bend: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction bbegin: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(label) @5 +(label) @begin +(label) @end +(byte*) BGCOL +(const byte*) BGCOL#0 BGCOL = ((byte*))(word/dword/signed dword) 53281 +(byte*) BGCOL1 +(byte*) BGCOL2 +(byte*) BGCOL3 +(byte*) BGCOL4 +(byte) BLACK +(const byte) BLACK#0 BLACK = (byte/signed byte/word/signed word/dword/signed dword) 0 +(byte) BLUE +(byte*) BORDERCOL +(byte) BROWN +(byte*) CHARGEN +(byte*) CIA1_INTERRUPT +(byte*) CIA1_PORT_A +(byte*) CIA1_PORT_A_DDR +(byte*) CIA1_PORT_B +(byte*) CIA1_PORT_B_DDR +(byte*) CIA2_INTERRUPT +(byte*) CIA2_PORT_A +(byte*) CIA2_PORT_A_DDR +(byte*) CIA2_PORT_B +(byte*) CIA2_PORT_B_DDR +(byte) CIA_INTERRUPT_CLEAR +(byte*) COLS +(byte) CYAN +(byte*) D011 +(byte*) D016 +(byte*) D018 +(byte) DARK_GREY +(byte) GREEN +(byte) GREY +(void()**) HARDWARE_IRQ +(byte) IRQ_COLLISION_BG +(byte) IRQ_COLLISION_SPRITE +(byte*) IRQ_ENABLE +(byte) IRQ_LIGHTPEN +(byte) IRQ_RASTER +(byte*) IRQ_STATUS +(void()**) KERNEL_IRQ +(byte*) LIGHTPEN_X +(byte*) LIGHTPEN_Y +(byte) LIGHT_BLUE +(byte) LIGHT_GREEN +(byte) LIGHT_GREY +(byte) ORANGE +(byte) PINK +(byte*) PROCPORT +(byte) PROCPORT_BASIC_KERNEL_IO +(byte*) PROCPORT_DDR +(byte) PROCPORT_DDR_MEMORY_MASK +(byte) PROCPORT_KERNEL_IO +(byte) PROCPORT_RAM_ALL +(byte) PROCPORT_RAM_CHARROM +(byte) PROCPORT_RAM_IO +(byte) PURPLE +(byte*) RASTER +(byte) RED +(byte*) SPRITES_COLS +(byte*) SPRITES_ENABLE +(byte*) SPRITES_EXPAND_X +(byte*) SPRITES_EXPAND_Y +(byte*) SPRITES_MC +(byte*) SPRITES_MC1 +(byte*) SPRITES_MC2 +(byte*) SPRITES_PRIORITY +(byte*) SPRITES_XMSB +(byte*) SPRITES_XPOS +(byte*) SPRITES_YPOS +(word) SPRITE_PTRS +(byte) VIC_BMM +(byte*) VIC_CONTROL +(byte*) VIC_CONTROL2 +(byte) VIC_CSEL +(byte) VIC_DEN +(byte) VIC_ECM +(byte) VIC_MCM +(byte*) VIC_MEMORY +(byte) VIC_RSEL +(byte) VIC_RST8 +(byte) WHITE +(byte) YELLOW +(void()) main() +(label) main::@return + + + +FINAL ASSEMBLER +Score: 12 + +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label BGCOL = $d021 + .const BLACK = 0 +//SEG2 @begin +//SEG3 [1] phi from @begin to @5 [phi:@begin->@5] +//SEG4 @5 +//SEG5 [2] call main +//SEG6 [3] phi from @5 to @end [phi:@5->@end] +//SEG7 @end +//SEG8 main +main: { + //SEG9 [4] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 + lda #BLACK + sta BGCOL + //SEG10 main::@return + //SEG11 [5] return + rts +} + diff --git a/src/test/ref/bgblack.sym b/src/test/ref/bgblack.sym new file mode 100644 index 000000000..ef8f64796 --- /dev/null +++ b/src/test/ref/bgblack.sym @@ -0,0 +1,87 @@ +(label) @5 +(label) @begin +(label) @end +(byte*) BGCOL +(const byte*) BGCOL#0 BGCOL = ((byte*))(word/dword/signed dword) 53281 +(byte*) BGCOL1 +(byte*) BGCOL2 +(byte*) BGCOL3 +(byte*) BGCOL4 +(byte) BLACK +(const byte) BLACK#0 BLACK = (byte/signed byte/word/signed word/dword/signed dword) 0 +(byte) BLUE +(byte*) BORDERCOL +(byte) BROWN +(byte*) CHARGEN +(byte*) CIA1_INTERRUPT +(byte*) CIA1_PORT_A +(byte*) CIA1_PORT_A_DDR +(byte*) CIA1_PORT_B +(byte*) CIA1_PORT_B_DDR +(byte*) CIA2_INTERRUPT +(byte*) CIA2_PORT_A +(byte*) CIA2_PORT_A_DDR +(byte*) CIA2_PORT_B +(byte*) CIA2_PORT_B_DDR +(byte) CIA_INTERRUPT_CLEAR +(byte*) COLS +(byte) CYAN +(byte*) D011 +(byte*) D016 +(byte*) D018 +(byte) DARK_GREY +(byte) GREEN +(byte) GREY +(void()**) HARDWARE_IRQ +(byte) IRQ_COLLISION_BG +(byte) IRQ_COLLISION_SPRITE +(byte*) IRQ_ENABLE +(byte) IRQ_LIGHTPEN +(byte) IRQ_RASTER +(byte*) IRQ_STATUS +(void()**) KERNEL_IRQ +(byte*) LIGHTPEN_X +(byte*) LIGHTPEN_Y +(byte) LIGHT_BLUE +(byte) LIGHT_GREEN +(byte) LIGHT_GREY +(byte) ORANGE +(byte) PINK +(byte*) PROCPORT +(byte) PROCPORT_BASIC_KERNEL_IO +(byte*) PROCPORT_DDR +(byte) PROCPORT_DDR_MEMORY_MASK +(byte) PROCPORT_KERNEL_IO +(byte) PROCPORT_RAM_ALL +(byte) PROCPORT_RAM_CHARROM +(byte) PROCPORT_RAM_IO +(byte) PURPLE +(byte*) RASTER +(byte) RED +(byte*) SPRITES_COLS +(byte*) SPRITES_ENABLE +(byte*) SPRITES_EXPAND_X +(byte*) SPRITES_EXPAND_Y +(byte*) SPRITES_MC +(byte*) SPRITES_MC1 +(byte*) SPRITES_MC2 +(byte*) SPRITES_PRIORITY +(byte*) SPRITES_XMSB +(byte*) SPRITES_XPOS +(byte*) SPRITES_YPOS +(word) SPRITE_PTRS +(byte) VIC_BMM +(byte*) VIC_CONTROL +(byte*) VIC_CONTROL2 +(byte) VIC_CSEL +(byte) VIC_DEN +(byte) VIC_ECM +(byte) VIC_MCM +(byte*) VIC_MEMORY +(byte) VIC_RSEL +(byte) VIC_RST8 +(byte) WHITE +(byte) YELLOW +(void()) main() +(label) main::@return + diff --git a/src/test/ref/bool-const.asm b/src/test/ref/bool-const.asm index 3d14a3e53..06ffcdcde 100644 --- a/src/test/ref/bool-const.asm +++ b/src/test/ref/bool-const.asm @@ -8,16 +8,19 @@ main: { jsr bool_const_inline rts } +// A constant boolean inside an if() bool_const_inline: { lda #'t' sta SCREEN+2 rts } +// A bunch of constant boolean vars (used in an if) bool_const_vars: { lda #'f' sta SCREEN+1 rts } +// A constant boolean inside an if() bool_const_if: { lda #'t' sta SCREEN diff --git a/src/test/ref/bool-const.log b/src/test/ref/bool-const.log index 2229f5fe6..62e825081 100644 --- a/src/test/ref/bool-const.log +++ b/src/test/ref/bool-const.log @@ -367,6 +367,7 @@ main: { rts } //SEG22 bool_const_inline +// A constant boolean inside an if() bool_const_inline: { jmp b1 //SEG23 bool_const_inline::@1 @@ -381,6 +382,7 @@ bool_const_inline: { rts } //SEG27 bool_const_vars +// A bunch of constant boolean vars (used in an if) bool_const_vars: { jmp b3 //SEG28 bool_const_vars::@3 @@ -395,6 +397,7 @@ bool_const_vars: { rts } //SEG32 bool_const_if +// A constant boolean inside an if() bool_const_if: { jmp b1 //SEG33 bool_const_if::@1 @@ -481,6 +484,7 @@ main: { rts } //SEG22 bool_const_inline +// A constant boolean inside an if() bool_const_inline: { jmp b1 //SEG23 bool_const_inline::@1 @@ -495,6 +499,7 @@ bool_const_inline: { rts } //SEG27 bool_const_vars +// A bunch of constant boolean vars (used in an if) bool_const_vars: { jmp b3 //SEG28 bool_const_vars::@3 @@ -509,6 +514,7 @@ bool_const_vars: { rts } //SEG32 bool_const_if +// A constant boolean inside an if() bool_const_if: { jmp b1 //SEG33 bool_const_if::@1 @@ -627,6 +633,7 @@ main: { rts } //SEG22 bool_const_inline +// A constant boolean inside an if() bool_const_inline: { //SEG23 bool_const_inline::@1 //SEG24 [12] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte) 't' -- _deref_pbuc1=vbuc2 @@ -637,6 +644,7 @@ bool_const_inline: { rts } //SEG27 bool_const_vars +// A bunch of constant boolean vars (used in an if) bool_const_vars: { //SEG28 bool_const_vars::@3 //SEG29 [15] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) 'f' -- _deref_pbuc1=vbuc2 @@ -647,6 +655,7 @@ bool_const_vars: { rts } //SEG32 bool_const_if +// A constant boolean inside an if() bool_const_if: { //SEG33 bool_const_if::@1 //SEG34 [18] *((const byte*) SCREEN#0) ← (byte) 't' -- _deref_pbuc1=vbuc2 diff --git a/src/test/ref/bool-function.asm b/src/test/ref/bool-function.asm index 270c09c18..1f7bee232 100644 --- a/src/test/ref/bool-function.asm +++ b/src/test/ref/bool-function.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Test a function taking boolean parameter and returning boolean result main: { .label screen = $400 ldx #0 @@ -28,6 +29,8 @@ main: { sta screen,x jmp b3 } +// Determine whether to set a char to '*. +// Returns true if i&8!=0 or b=true isSet: { .label b = 2 txa diff --git a/src/test/ref/bool-function.log b/src/test/ref/bool-function.log index 8dffb42b7..16cade402 100644 --- a/src/test/ref/bool-function.log +++ b/src/test/ref/bool-function.log @@ -277,6 +277,7 @@ bend_from_b2: //SEG8 @end bend: //SEG9 main +// Test a function taking boolean parameter and returning boolean result main: { .label screen = $400 .label _0 = 3 @@ -354,6 +355,8 @@ main: { jmp b3 } //SEG32 isSet +// Determine whether to set a char to '*. +// Returns true if i&8!=0 or b=true isSet: { .label _0 = 8 .label _1 = 9 @@ -444,6 +447,7 @@ bend_from_b2: //SEG8 @end bend: //SEG9 main +// Test a function taking boolean parameter and returning boolean result main: { .label screen = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] @@ -468,16 +472,13 @@ main: { eor #1 sta isSet.b //SEG17 [8] (byte) isSet::i#0 ← (byte) main::i#2 - // (byte) isSet::i#0 = (byte) main::i#2 // register copy reg byte x //SEG18 [9] call isSet jsr isSet //SEG19 [10] (bool) isSet::return#0 ← (bool) isSet::return#1 - // (bool) isSet::return#0 = (bool) isSet::return#1 // register copy reg byte a jmp b7 //SEG20 main::@7 b7: //SEG21 [11] (bool~) main::$2 ← (bool) isSet::return#0 - // (bool~) main::$2 = (bool) isSet::return#0 // register copy reg byte a //SEG22 [12] if((bool~) main::$2) goto main::@2 -- vboaa_then_la1 cmp #0 bne b2 @@ -508,6 +509,8 @@ main: { jmp b3 } //SEG32 isSet +// Determine whether to set a char to '*. +// Returns true if i&8!=0 or b=true isSet: { .label b = 2 //SEG33 [18] (byte~) isSet::$0 ← (byte) isSet::i#0 & (byte/signed byte/word/signed word/dword/signed dword) 8 -- vbuaa=vbuxx_band_vbuc1 @@ -616,6 +619,7 @@ Score: 540 //SEG7 [3] phi from @2 to @end [phi:@2->@end] //SEG8 @end //SEG9 main +// Test a function taking boolean parameter and returning boolean result main: { .label screen = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] @@ -636,14 +640,11 @@ main: { eor #1 sta isSet.b //SEG17 [8] (byte) isSet::i#0 ← (byte) main::i#2 - // (byte) isSet::i#0 = (byte) main::i#2 // register copy reg byte x //SEG18 [9] call isSet jsr isSet //SEG19 [10] (bool) isSet::return#0 ← (bool) isSet::return#1 - // (bool) isSet::return#0 = (bool) isSet::return#1 // register copy reg byte a //SEG20 main::@7 //SEG21 [11] (bool~) main::$2 ← (bool) isSet::return#0 - // (bool~) main::$2 = (bool) isSet::return#0 // register copy reg byte a //SEG22 [12] if((bool~) main::$2) goto main::@2 -- vboaa_then_la1 cmp #0 bne b2 @@ -669,6 +670,8 @@ main: { jmp b3 } //SEG32 isSet +// Determine whether to set a char to '*. +// Returns true if i&8!=0 or b=true isSet: { .label b = 2 //SEG33 [18] (byte~) isSet::$0 ← (byte) isSet::i#0 & (byte/signed byte/word/signed word/dword/signed dword) 8 -- vbuaa=vbuxx_band_vbuc1 diff --git a/src/test/ref/bool-ifs.asm b/src/test/ref/bool-ifs.asm index b2cb02792..1aad61f56 100644 --- a/src/test/ref/bool-ifs.asm +++ b/src/test/ref/bool-ifs.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// A test of boolean conditions using && || and ! main: { jsr bool_and jsr bool_or diff --git a/src/test/ref/bool-ifs.log b/src/test/ref/bool-ifs.log index b9e15e850..f7b39c7e9 100644 --- a/src/test/ref/bool-ifs.log +++ b/src/test/ref/bool-ifs.log @@ -575,6 +575,7 @@ bend_from_b5: //SEG8 @end bend: //SEG9 main +// A test of boolean conditions using && || and ! main: { //SEG10 [5] call bool_and //SEG11 [46] phi from main to bool_and [phi:main->bool_and] @@ -957,6 +958,7 @@ bend_from_b5: //SEG8 @end bend: //SEG9 main +// A test of boolean conditions using && || and ! main: { //SEG10 [5] call bool_and //SEG11 [46] phi from main to bool_and [phi:main->bool_and] @@ -1390,6 +1392,7 @@ Score: 1804 //SEG7 [3] phi from @5 to @end [phi:@5->@end] //SEG8 @end //SEG9 main +// A test of boolean conditions using && || and ! main: { //SEG10 [5] call bool_and //SEG11 [46] phi from main to bool_and [phi:main->bool_and] diff --git a/src/test/ref/bool-pointer.asm b/src/test/ref/bool-pointer.asm index 970cf6afd..a84cd0538 100644 --- a/src/test/ref/bool-pointer.asm +++ b/src/test/ref/bool-pointer.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Tests a pointer to a boolean main: { lda #1 sta $400 diff --git a/src/test/ref/bool-pointer.log b/src/test/ref/bool-pointer.log index d5329ab82..ea3bd5cc9 100644 --- a/src/test/ref/bool-pointer.log +++ b/src/test/ref/bool-pointer.log @@ -134,6 +134,7 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Tests a pointer to a boolean main: { //SEG9 [4] *(((bool*))(word/signed word/dword/signed dword) 1024) ← true -- _deref_pboc1=vboc2 lda #1 @@ -196,6 +197,7 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Tests a pointer to a boolean main: { //SEG9 [4] *(((bool*))(word/signed word/dword/signed dword) 1024) ← true -- _deref_pboc1=vboc2 lda #1 @@ -268,6 +270,7 @@ Score: 37 //SEG6 [3] phi from @1 to @end [phi:@1->@end] //SEG7 @end //SEG8 main +// Tests a pointer to a boolean main: { //SEG9 [4] *(((bool*))(word/signed word/dword/signed dword) 1024) ← true -- _deref_pboc1=vboc2 lda #1 diff --git a/src/test/ref/bool-vars.asm b/src/test/ref/bool-vars.asm index d4e70cf96..1ed3db54b 100644 --- a/src/test/ref/bool-vars.asm +++ b/src/test/ref/bool-vars.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// A test of boolean conditions using && || and ! main: { jsr bool_and jsr bool_or diff --git a/src/test/ref/bool-vars.log b/src/test/ref/bool-vars.log index 58c97b9cd..be0f6f9bb 100644 --- a/src/test/ref/bool-vars.log +++ b/src/test/ref/bool-vars.log @@ -640,6 +640,7 @@ bend_from_b5: //SEG8 @end bend: //SEG9 main +// A test of boolean conditions using && || and ! main: { //SEG10 [5] call bool_and //SEG11 [47] phi from main to bool_and [phi:main->bool_and] @@ -1048,6 +1049,7 @@ bend_from_b5: //SEG8 @end bend: //SEG9 main +// A test of boolean conditions using && || and ! main: { //SEG10 [5] call bool_and //SEG11 [47] phi from main to bool_and [phi:main->bool_and] @@ -1512,6 +1514,7 @@ Score: 2089 //SEG7 [3] phi from @5 to @end [phi:@5->@end] //SEG8 @end //SEG9 main +// A test of boolean conditions using && || and ! main: { //SEG10 [5] call bool_and //SEG11 [47] phi from main to bool_and [phi:main->bool_and] diff --git a/src/test/ref/c64dtv-8bppcharstretch.asm b/src/test/ref/c64dtv-8bppcharstretch.asm index 228e5e8c1..e5cb1b263 100644 --- a/src/test/ref/c64dtv-8bppcharstretch.asm +++ b/src/test/ref/c64dtv-8bppcharstretch.asm @@ -183,11 +183,13 @@ main: { bne b8 jmp b3 } +// Initialize the different graphics in the memory gfx_init: { jsr gfx_init_screen0 jsr gfx_init_plane_charset8 rts } +// Initialize Plane with 8bpp charset gfx_init_plane_charset8: { .const gfxbCpuBank = $ff&CHARSET8/$4000 .label bits = 6 @@ -258,6 +260,9 @@ gfx_init_plane_charset8: { jsr dtvSetCpuBankSegment1 rts } +// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) +// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff +// The actual memory addressed will be $4000*cpuSegmentIdx dtvSetCpuBankSegment1: { .label cpuBank = $ff sta cpuBank @@ -266,6 +271,7 @@ dtvSetCpuBankSegment1: { .byte $32, $00 rts } +// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos) gfx_init_screen0: { .label _1 = 5 .label ch = 3 diff --git a/src/test/ref/c64dtv-8bppcharstretch.log b/src/test/ref/c64dtv-8bppcharstretch.log index 88aae9fc5..af35339e6 100644 --- a/src/test/ref/c64dtv-8bppcharstretch.log +++ b/src/test/ref/c64dtv-8bppcharstretch.log @@ -2199,6 +2199,7 @@ main: { jmp b3 } //SEG59 gfx_init +// Initialize the different graphics in the memory gfx_init: { //SEG60 [45] call gfx_init_screen0 //SEG61 [78] phi from gfx_init to gfx_init_screen0 [phi:gfx_init->gfx_init_screen0] @@ -2220,6 +2221,7 @@ gfx_init: { rts } //SEG68 gfx_init_plane_charset8 +// Initialize Plane with 8bpp charset gfx_init_plane_charset8: { .const gfxbCpuBank = $ff&CHARSET8/$4000 .label _7 = $16 @@ -2400,6 +2402,9 @@ gfx_init_plane_charset8: { rts } //SEG137 dtvSetCpuBankSegment1 +// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) +// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff +// The actual memory addressed will be $4000*cpuSegmentIdx dtvSetCpuBankSegment1: { .label cpuBank = $ff .label cpuBankIdx = $d @@ -2417,6 +2422,7 @@ dtvSetCpuBankSegment1: { rts } //SEG142 gfx_init_screen0 +// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos) gfx_init_screen0: { .label _0 = $17 .label _1 = $18 @@ -2934,6 +2940,7 @@ main: { jmp b3 } //SEG59 gfx_init +// Initialize the different graphics in the memory gfx_init: { //SEG60 [45] call gfx_init_screen0 //SEG61 [78] phi from gfx_init to gfx_init_screen0 [phi:gfx_init->gfx_init_screen0] @@ -2955,6 +2962,7 @@ gfx_init: { rts } //SEG68 gfx_init_plane_charset8 +// Initialize Plane with 8bpp charset gfx_init_plane_charset8: { .const gfxbCpuBank = $ff&CHARSET8/$4000 .label bits = 6 @@ -3123,6 +3131,9 @@ gfx_init_plane_charset8: { rts } //SEG137 dtvSetCpuBankSegment1 +// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) +// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff +// The actual memory addressed will be $4000*cpuSegmentIdx dtvSetCpuBankSegment1: { .label cpuBank = $ff //SEG138 [75] *((const byte*) dtvSetCpuBankSegment1::cpuBank#0) ← (byte) dtvSetCpuBankSegment1::cpuBankIdx#2 -- _deref_pbuc1=vbuaa @@ -3138,6 +3149,7 @@ dtvSetCpuBankSegment1: { rts } //SEG142 gfx_init_screen0 +// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos) gfx_init_screen0: { .label _1 = 5 .label ch = 3 @@ -3885,6 +3897,7 @@ main: { jmp b3 } //SEG59 gfx_init +// Initialize the different graphics in the memory gfx_init: { //SEG60 [45] call gfx_init_screen0 //SEG61 [78] phi from gfx_init to gfx_init_screen0 [phi:gfx_init->gfx_init_screen0] @@ -3899,6 +3912,7 @@ gfx_init: { rts } //SEG68 gfx_init_plane_charset8 +// Initialize Plane with 8bpp charset gfx_init_plane_charset8: { .const gfxbCpuBank = $ff&CHARSET8/$4000 .label bits = 6 @@ -4038,6 +4052,9 @@ gfx_init_plane_charset8: { rts } //SEG137 dtvSetCpuBankSegment1 +// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) +// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff +// The actual memory addressed will be $4000*cpuSegmentIdx dtvSetCpuBankSegment1: { .label cpuBank = $ff //SEG138 [75] *((const byte*) dtvSetCpuBankSegment1::cpuBank#0) ← (byte) dtvSetCpuBankSegment1::cpuBankIdx#2 -- _deref_pbuc1=vbuaa @@ -4051,6 +4068,7 @@ dtvSetCpuBankSegment1: { rts } //SEG142 gfx_init_screen0 +// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos) gfx_init_screen0: { .label _1 = 5 .label ch = 3 diff --git a/src/test/ref/c64dtv-8bppchunkystretch.asm b/src/test/ref/c64dtv-8bppchunkystretch.asm index c5606ac48..1903ad883 100644 --- a/src/test/ref/c64dtv-8bppchunkystretch.asm +++ b/src/test/ref/c64dtv-8bppchunkystretch.asm @@ -166,6 +166,7 @@ main: { bne b8 jmp b3 } +// Initialize Plane with 8bpp chunky gfx_init_chunky: { .label _6 = 7 .label gfxb = 5 @@ -231,6 +232,9 @@ gfx_init_chunky: { jsr dtvSetCpuBankSegment1 rts } +// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) +// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff +// The actual memory addressed will be $4000*cpuSegmentIdx dtvSetCpuBankSegment1: { .label cpuBank = $ff sta cpuBank diff --git a/src/test/ref/c64dtv-8bppchunkystretch.log b/src/test/ref/c64dtv-8bppchunkystretch.log index afc6da789..24fd4c028 100644 --- a/src/test/ref/c64dtv-8bppchunkystretch.log +++ b/src/test/ref/c64dtv-8bppchunkystretch.log @@ -1824,6 +1824,7 @@ main: { jmp b3 } //SEG53 gfx_init_chunky +// Initialize Plane with 8bpp chunky gfx_init_chunky: { .label _6 = $e .label c = $10 @@ -1977,6 +1978,9 @@ gfx_init_chunky: { rts } //SEG106 dtvSetCpuBankSegment1 +// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) +// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff +// The actual memory addressed will be $4000*cpuSegmentIdx dtvSetCpuBankSegment1: { .label cpuBank = $ff .label cpuBankIdx = 9 @@ -2333,6 +2337,7 @@ main: { jmp b3 } //SEG53 gfx_init_chunky +// Initialize Plane with 8bpp chunky gfx_init_chunky: { .label _6 = 7 .label gfxb = 5 @@ -2478,6 +2483,9 @@ gfx_init_chunky: { rts } //SEG106 dtvSetCpuBankSegment1 +// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) +// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff +// The actual memory addressed will be $4000*cpuSegmentIdx dtvSetCpuBankSegment1: { .label cpuBank = $ff //SEG107 [59] *((const byte*) dtvSetCpuBankSegment1::cpuBank#0) ← (byte) dtvSetCpuBankSegment1::cpuBankIdx#3 -- _deref_pbuc1=vbuaa @@ -3060,6 +3068,7 @@ main: { jmp b3 } //SEG53 gfx_init_chunky +// Initialize Plane with 8bpp chunky gfx_init_chunky: { .label _6 = 7 .label gfxb = 5 @@ -3178,6 +3187,9 @@ gfx_init_chunky: { rts } //SEG106 dtvSetCpuBankSegment1 +// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) +// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff +// The actual memory addressed will be $4000*cpuSegmentIdx dtvSetCpuBankSegment1: { .label cpuBank = $ff //SEG107 [59] *((const byte*) dtvSetCpuBankSegment1::cpuBank#0) ← (byte) dtvSetCpuBankSegment1::cpuBankIdx#3 -- _deref_pbuc1=vbuaa diff --git a/src/test/ref/c64dtv-gfxexplorer.asm b/src/test/ref/c64dtv-gfxexplorer.asm index 84ba661b7..1628e9915 100644 --- a/src/test/ref/c64dtv-gfxexplorer.asm +++ b/src/test/ref/c64dtv-gfxexplorer.asm @@ -147,6 +147,7 @@ main: { jsr gfx_mode jmp b2 } +// Change graphics mode to show the selected graphics mode gfx_mode: { .label _31 = $a .label _33 = 3 @@ -469,6 +470,9 @@ gfx_mode: { bne b15 jmp b19 } +// Get the next event from the keyboard event buffer. +// Returns $ff if there is no event waiting. As all events are <$7f it is enough to examine bit 7 when determining if there is any event to process. +// The buffer is filled by keyboard_event_scan() keyboard_event_get: { lda keyboard_events_size cmp #0 @@ -482,6 +486,10 @@ keyboard_event_get: { breturn: rts } +// Scans the entire matrix to determine which keys have been pressed/depressed. +// Generates keyboard events into the event buffer. Events can be read using keyboard_event_get(). +// Handles debounce and only generates events when the status of a key changes. +// Also stores current status of modifiers in keyboard_modifiers. keyboard_event_scan: { .label row_scan = $12 .label keycode = 8 @@ -586,6 +594,8 @@ keyboard_event_scan: { inc keyboard_events_size jmp b5 } +// Determine if a specific key is currently pressed based on the last keyboard_event_scan() +// Returns 0 is not pressed and non-0 if pressed keyboard_event_pressed: { .label row_bits = 8 .label keycode = 7 @@ -603,6 +613,11 @@ keyboard_event_pressed: { and row_bits rts } +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { tay lda keyboard_matrix_row_bitmask,y @@ -611,6 +626,7 @@ keyboard_matrix_read: { eor #$ff rts } +// Get the VIC screen address from the screen index get_vic_screen: { .label return = 3 cmp #0 @@ -654,6 +670,7 @@ get_vic_screen: { breturn: rts } +// Get the VIC charset/bitmap address from the index get_vic_charset: { .label return = 3 cmp #0 @@ -673,6 +690,7 @@ get_vic_charset: { breturn: rts } +// Get plane address from a plane index (from the form) get_plane: { .label return = $a cmp #0 @@ -866,6 +884,7 @@ get_plane: { breturn: rts } +// Show the form - and let the user change values form_mode: { .label preset_current = $f lda #print_ln::@1] b1_from_print_ln: @@ -16855,6 +16889,7 @@ print_ln: { rts } //SEG878 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label _0 = $122 .label sc = $38 @@ -16901,6 +16936,7 @@ print_cls: { rts } //SEG889 print_set_screen +// Set the screen to print on. Also resets current line/char cursor. print_set_screen: { .label screen = $36 jmp breturn @@ -16910,6 +16946,7 @@ print_set_screen: { rts } //SEG892 gfx_init +// Initialize the different graphics in the memory gfx_init: { //SEG893 [450] call gfx_init_screen0 //SEG894 [848] phi from gfx_init to gfx_init_screen0 [phi:gfx_init->gfx_init_screen0] @@ -17046,6 +17083,7 @@ gfx_init: { rts } //SEG952 gfx_init_plane_full +// Initialize Plane with all pixels gfx_init_plane_full: { //SEG953 [481] call gfx_init_plane_fill //SEG954 [483] phi from gfx_init_plane_full to gfx_init_plane_fill [phi:gfx_init_plane_full->gfx_init_plane_fill] @@ -17070,6 +17108,7 @@ gfx_init_plane_full: { rts } //SEG959 gfx_init_plane_fill +// Initialize 320*200 1bpp pixel ($2000) plane with identical bytes gfx_init_plane_fill: { .label _0 = $124 .label _1 = $128 @@ -17219,6 +17258,9 @@ gfx_init_plane_fill: { rts } //SEG1001 dtvSetCpuBankSegment1 +// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) +// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff +// The actual memory addressed will be $4000*cpuSegmentIdx dtvSetCpuBankSegment1: { .label cpuBank = $ff .label cpuBankIdx = $43 @@ -17236,6 +17278,7 @@ dtvSetCpuBankSegment1: { rts } //SEG1006 gfx_init_plane_blank +// Initialize Plane with blank pixels gfx_init_plane_blank: { //SEG1007 [510] call gfx_init_plane_fill //SEG1008 [483] phi from gfx_init_plane_blank to gfx_init_plane_fill [phi:gfx_init_plane_blank->gfx_init_plane_fill] @@ -17260,6 +17303,7 @@ gfx_init_plane_blank: { rts } //SEG1013 gfx_init_plane_vertical2 +// Initialize Plane with Vertical Stripes every 2 pixels gfx_init_plane_vertical2: { //SEG1014 [513] call gfx_init_plane_fill //SEG1015 [483] phi from gfx_init_plane_vertical2 to gfx_init_plane_fill [phi:gfx_init_plane_vertical2->gfx_init_plane_fill] @@ -17284,6 +17328,7 @@ gfx_init_plane_vertical2: { rts } //SEG1020 gfx_init_plane_horisontal2 +// Initialize Plane with Horizontal Stripes every 2 pixels gfx_init_plane_horisontal2: { .const gfxbCpuBank = PLANE_HORISONTAL2/$4000 .label _5 = $132 @@ -17383,6 +17428,7 @@ gfx_init_plane_horisontal2: { row_bitmask: .byte 0, $55, $aa, $ff } //SEG1054 gfx_init_plane_vertical +// Initialize Plane with Vertical Stripes gfx_init_plane_vertical: { .const gfxbCpuBank = PLANE_VERTICAL/$4000 .label gfxb = $49 @@ -17470,6 +17516,7 @@ gfx_init_plane_vertical: { rts } //SEG1086 gfx_init_plane_horisontal +// Initialize Plane with Horizontal Stripes gfx_init_plane_horisontal: { .const gfxbCpuBank = PLANE_HORISONTAL/$4000 .label _5 = $134 @@ -17588,6 +17635,7 @@ gfx_init_plane_horisontal: { jmp b4_from_b3 } //SEG1127 gfx_init_plane_charset8 +// Initialize Plane with 8bpp charset gfx_init_plane_charset8: { .const gfxbCpuBank = PLANE_CHARSET8/$4000 .label _5 = $135 @@ -17768,6 +17816,7 @@ gfx_init_plane_charset8: { rts } //SEG1196 gfx_init_plane_8bppchunky +// Initialize 8BPP Chunky Bitmap (contains 8bpp pixels) gfx_init_plane_8bppchunky: { .label _6 = $136 .label c = $138 @@ -17921,6 +17970,7 @@ gfx_init_plane_8bppchunky: { rts } //SEG1249 gfx_init_vic_bitmap +// Initialize VIC bitmap gfx_init_vic_bitmap: { .const lines_cnt = 9 .label l = $60 @@ -17983,6 +18033,7 @@ gfx_init_vic_bitmap: { lines_y: .byte 0, 0, $c7, $c7, 0, 0, $64, $c7, $64, 0 } //SEG1270 bitmap_line +// Draw a line on the bitmap bitmap_line: { .label xd = $140 .label xd_1 = $13d @@ -18657,6 +18708,7 @@ bitmap_line_ydxd: { rts } //SEG1516 bitmap_clear +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = $7c .label x = $7e @@ -18731,6 +18783,7 @@ bitmap_clear: { rts } //SEG1542 bitmap_init +// Initialize the bitmap plotter tables for a specific bitmap bitmap_init: { .label _0 = $150 .label _6 = $151 @@ -18973,6 +19026,7 @@ gfx_init_charset: { rts } //SEG1621 gfx_init_screen4 +// Initialize VIC screen 4 - all chars are 00 gfx_init_screen4: { .label ch = $8b .label cx = $8d @@ -19040,6 +19094,7 @@ gfx_init_screen4: { rts } //SEG1645 gfx_init_screen3 +// Initialize VIC screen 3 ( value is %00xx00yy where xx is xpos and yy is ypos gfx_init_screen3: { .label _0 = $156 .label _1 = $157 @@ -19130,6 +19185,7 @@ gfx_init_screen3: { rts } //SEG1673 gfx_init_screen2 +// Initialize VIC screen 2 ( value is %ccccrrrr where cccc is (x+y mod $f) and rrrr is %1111-%cccc) gfx_init_screen2: { .label _0 = $15a .label _3 = $15d @@ -19227,6 +19283,7 @@ gfx_init_screen2: { rts } //SEG1702 gfx_init_screen1 +// Initialize VIC screen 1 ( value is %0000cccc where cccc is (x+y mod $f)) gfx_init_screen1: { .label _0 = $15f .label _1 = $160 @@ -19305,6 +19362,7 @@ gfx_init_screen1: { rts } //SEG1728 gfx_init_screen0 +// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos) gfx_init_screen0: { .label _0 = $161 .label _1 = $162 @@ -19395,6 +19453,7 @@ gfx_init_screen0: { rts } //SEG1756 keyboard_init +// Initialize keyboard reading by setting CIA#$ Data Direction Registers keyboard_init: { //SEG1757 [862] *((const byte*) CIA1_PORT_A_DDR#0) ← (byte/word/signed word/dword/signed dword) 255 -- _deref_pbuc1=vbuc2 lda #$ff @@ -21076,6 +21135,7 @@ main: { jmp b1 } //SEG34 gfx_mode +// Change graphics mode to show the selected graphics mode gfx_mode: { .label _31 = $a .label _33 = 3 @@ -21291,12 +21351,10 @@ gfx_mode: { //SEG103 [236] phi (byte) get_plane::idx#10 = (byte) get_plane::idx#0 [phi:gfx_mode::@9->get_plane#0] -- register_copy jsr get_plane //SEG104 [50] (dword) get_plane::return#16 ← (dword) get_plane::return#14 - // (dword) get_plane::return#16 = (dword) get_plane::return#14 // register copy zp ZP_DWORD:10 jmp b46 //SEG105 gfx_mode::@46 b46: //SEG106 [51] (dword~) gfx_mode::$31 ← (dword) get_plane::return#16 - // (dword~) gfx_mode::$31 = (dword) get_plane::return#16 // register copy zp ZP_DWORD:10 //SEG107 [52] (dword) gfx_mode::plane_a#0 ← (dword~) gfx_mode::$31 + (byte) gfx_mode::plane_a_offs#0 -- vduz1=vduz1_plus_vbuyy tya clc @@ -21378,12 +21436,10 @@ gfx_mode: { //SEG129 [236] phi (byte) get_plane::idx#10 = (byte) get_plane::idx#1 [phi:gfx_mode::@46->get_plane#0] -- register_copy jsr get_plane //SEG130 [73] (dword) get_plane::return#17 ← (dword) get_plane::return#14 - // (dword) get_plane::return#17 = (dword) get_plane::return#14 // register copy zp ZP_DWORD:10 jmp b47 //SEG131 gfx_mode::@47 b47: //SEG132 [74] (dword~) gfx_mode::$45 ← (dword) get_plane::return#17 - // (dword~) gfx_mode::$45 = (dword) get_plane::return#17 // register copy zp ZP_DWORD:10 //SEG133 [75] (dword) gfx_mode::plane_b#0 ← (dword~) gfx_mode::$45 + (byte) gfx_mode::plane_b_offs#0 -- vduz1=vduz1_plus_vbuyy tya clc @@ -21462,12 +21518,10 @@ gfx_mode: { //SEG155 [222] phi (byte) get_vic_screen::idx#2 = (byte) get_vic_screen::idx#0 [phi:gfx_mode::@47->get_vic_screen#0] -- register_copy jsr get_vic_screen //SEG156 [96] (byte*) get_vic_screen::return#10 ← (byte*) get_vic_screen::return#5 - // (byte*) get_vic_screen::return#10 = (byte*) get_vic_screen::return#5 // register copy zp ZP_WORD:3 jmp b48 //SEG157 gfx_mode::@48 b48: //SEG158 [97] (byte*~) gfx_mode::$61 ← (byte*) get_vic_screen::return#10 - // (byte*~) gfx_mode::$61 = (byte*) get_vic_screen::return#10 // register copy zp ZP_WORD:3 //SEG159 [98] (word~) gfx_mode::$63 ← (word)(byte*~) gfx_mode::$61 & (word/signed word/dword/signed dword) 16383 -- vwuz1=vwuz1_band_vwuc1 lda _63 and #<$3fff @@ -21490,12 +21544,10 @@ gfx_mode: { //SEG163 [102] call get_vic_charset jsr get_vic_charset //SEG164 [103] (byte*) get_vic_charset::return#4 ← (byte*) get_vic_charset::return#2 - // (byte*) get_vic_charset::return#4 = (byte*) get_vic_charset::return#2 // register copy zp ZP_WORD:3 jmp b49 //SEG165 gfx_mode::@49 b49: //SEG166 [104] (byte*~) gfx_mode::$66 ← (byte*) get_vic_charset::return#4 - // (byte*~) gfx_mode::$66 = (byte*) get_vic_charset::return#4 // register copy zp ZP_WORD:3 //SEG167 [105] (word~) gfx_mode::$68 ← (word)(byte*~) gfx_mode::$66 & (word/signed word/dword/signed dword) 16383 -- vwuz1=vwuz1_band_vwuc1 lda _68 and #<$3fff @@ -21520,12 +21572,10 @@ gfx_mode: { //SEG175 [222] phi (byte) get_vic_screen::idx#2 = (byte) get_vic_screen::idx#1 [phi:gfx_mode::@49->get_vic_screen#0] -- register_copy jsr get_vic_screen //SEG176 [112] (byte*) get_vic_screen::return#11 ← (byte*) get_vic_screen::return#5 - // (byte*) get_vic_screen::return#11 = (byte*) get_vic_screen::return#5 // register copy zp ZP_WORD:3 jmp b50 //SEG177 gfx_mode::@50 b50: //SEG178 [113] (byte*) gfx_mode::vic_colors#0 ← (byte*) get_vic_screen::return#11 - // (byte*) gfx_mode::vic_colors#0 = (byte*) get_vic_screen::return#11 // register copy zp ZP_WORD:3 //SEG179 [114] phi from gfx_mode::@50 to gfx_mode::@10 [phi:gfx_mode::@50->gfx_mode::@10] b10_from_b50: //SEG180 [114] phi (byte) gfx_mode::cy#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:gfx_mode::@50->gfx_mode::@10#0] -- vbuz1=vbuc1 @@ -21686,12 +21736,10 @@ gfx_mode: { //SEG237 [145] call keyboard_event_get jsr keyboard_event_get //SEG238 [146] (byte) keyboard_event_get::return#3 ← (byte) keyboard_event_get::return#2 - // (byte) keyboard_event_get::return#3 = (byte) keyboard_event_get::return#2 // register copy reg byte a jmp b52 //SEG239 gfx_mode::@52 b52: //SEG240 [147] (byte) gfx_mode::keyboard_event#0 ← (byte) keyboard_event_get::return#3 - // (byte) gfx_mode::keyboard_event#0 = (byte) keyboard_event_get::return#3 // register copy reg byte a //SEG241 [148] if((byte) gfx_mode::keyboard_event#0!=(const byte) KEY_SPACE#0) goto gfx_mode::@19 -- vbuaa_neq_vbuc1_then_la1 cmp #KEY_SPACE bne b19 @@ -21722,6 +21770,9 @@ gfx_mode: { jmp b19 } //SEG252 keyboard_event_get +// Get the next event from the keyboard event buffer. +// Returns $ff if there is no event waiting. As all events are <$7f it is enough to examine bit 7 when determining if there is any event to process. +// The buffer is filled by keyboard_event_scan() keyboard_event_get: { //SEG253 [154] if((byte) keyboard_events_size#100==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_get::@return -- vbuz1_eq_0_then_la1 lda keyboard_events_size @@ -21752,6 +21803,10 @@ keyboard_event_get: { rts } //SEG265 keyboard_event_scan +// Scans the entire matrix to determine which keys have been pressed/depressed. +// Generates keyboard events into the event buffer. Events can be read using keyboard_event_get(). +// Handles debounce and only generates events when the status of a key changes. +// Also stores current status of modifiers in keyboard_modifiers. keyboard_event_scan: { .label row_scan = $12 .label keycode = 8 @@ -21780,7 +21835,6 @@ keyboard_event_scan: { //SEG276 [162] call keyboard_matrix_read jsr keyboard_matrix_read //SEG277 [163] (byte) keyboard_matrix_read::return#2 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#2 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a jmp b25 //SEG278 keyboard_event_scan::@25 b25: @@ -21826,12 +21880,10 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG294 [172] (byte) keyboard_event_pressed::return#0 ← (byte) keyboard_event_pressed::return#10 - // (byte) keyboard_event_pressed::return#0 = (byte) keyboard_event_pressed::return#10 // register copy reg byte a jmp b26 //SEG295 keyboard_event_scan::@26 b26: //SEG296 [173] (byte~) keyboard_event_scan::$14 ← (byte) keyboard_event_pressed::return#0 - // (byte~) keyboard_event_scan::$14 = (byte) keyboard_event_pressed::return#0 // register copy reg byte a //SEG297 [174] if((byte~) keyboard_event_scan::$14==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@9 -- vbuaa_eq_0_then_la1 cmp #0 beq b9_from_b26 @@ -21862,12 +21914,10 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG308 [178] (byte) keyboard_event_pressed::return#1 ← (byte) keyboard_event_pressed::return#10 - // (byte) keyboard_event_pressed::return#1 = (byte) keyboard_event_pressed::return#10 // register copy reg byte a jmp b27 //SEG309 keyboard_event_scan::@27 b27: //SEG310 [179] (byte~) keyboard_event_scan::$18 ← (byte) keyboard_event_pressed::return#1 - // (byte~) keyboard_event_scan::$18 = (byte) keyboard_event_pressed::return#1 // register copy reg byte a //SEG311 [180] if((byte~) keyboard_event_scan::$18==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@10 -- vbuaa_eq_0_then_la1 cmp #0 beq b10_from_b27 @@ -21893,12 +21943,10 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG320 [184] (byte) keyboard_event_pressed::return#2 ← (byte) keyboard_event_pressed::return#10 - // (byte) keyboard_event_pressed::return#2 = (byte) keyboard_event_pressed::return#10 // register copy reg byte a jmp b28 //SEG321 keyboard_event_scan::@28 b28: //SEG322 [185] (byte~) keyboard_event_scan::$22 ← (byte) keyboard_event_pressed::return#2 - // (byte~) keyboard_event_scan::$22 = (byte) keyboard_event_pressed::return#2 // register copy reg byte a //SEG323 [186] if((byte~) keyboard_event_scan::$22==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@11 -- vbuaa_eq_0_then_la1 cmp #0 beq b11_from_b28 @@ -21924,12 +21972,10 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG332 [190] (byte) keyboard_event_pressed::return#3 ← (byte) keyboard_event_pressed::return#10 - // (byte) keyboard_event_pressed::return#3 = (byte) keyboard_event_pressed::return#10 // register copy reg byte a jmp b29 //SEG333 keyboard_event_scan::@29 b29: //SEG334 [191] (byte~) keyboard_event_scan::$26 ← (byte) keyboard_event_pressed::return#3 - // (byte~) keyboard_event_scan::$26 = (byte) keyboard_event_pressed::return#3 // register copy reg byte a //SEG335 [192] if((byte~) keyboard_event_scan::$26==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@return -- vbuaa_eq_0_then_la1 cmp #0 beq breturn_from_b29 @@ -22039,6 +22085,8 @@ keyboard_event_scan: { jmp b5_from_b7 } //SEG374 keyboard_event_pressed +// Determine if a specific key is currently pressed based on the last keyboard_event_scan() +// Returns 0 is not pressed and non-0 if pressed keyboard_event_pressed: { .label row_bits = 8 .label keycode = 7 @@ -22065,6 +22113,11 @@ keyboard_event_pressed: { rts } //SEG381 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { //SEG382 [219] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0 + (byte) keyboard_matrix_read::rowid#0) -- _deref_pbuc1=pbuc2_derefidx_vbuaa tay @@ -22080,6 +22133,7 @@ keyboard_matrix_read: { rts } //SEG386 get_vic_screen +// Get the VIC screen address from the screen index get_vic_screen: { .label return = 3 //SEG387 [223] if((byte) get_vic_screen::idx#2==(byte/signed byte/word/signed word/dword/signed dword) 0) goto get_vic_screen::@return -- vbuaa_eq_0_then_la1 @@ -22162,6 +22216,7 @@ get_vic_screen: { jmp breturn_from_b9 } //SEG410 get_vic_charset +// Get the VIC charset/bitmap address from the index get_vic_charset: { .label return = 3 //SEG411 [231] if((byte) get_vic_charset::idx#0==(byte/signed byte/word/signed word/dword/signed dword) 0) goto get_vic_charset::@return -- vbuaa_eq_0_then_la1 @@ -22202,6 +22257,7 @@ get_vic_charset: { jmp breturn_from_b3 } //SEG422 get_plane +// Get plane address from a plane index (from the form) get_plane: { .label return = $a //SEG423 [237] if((byte) get_plane::idx#10==(byte/signed byte/word/signed word/dword/signed dword) 0) goto get_plane::@return -- vbuaa_eq_0_then_la1 @@ -22466,6 +22522,7 @@ get_plane: { jmp breturn_from_b27 } //SEG482 form_mode +// Show the form - and let the user change values form_mode: { .label preset_current = $f //SEG483 [255] call print_set_screen @@ -22667,7 +22724,6 @@ form_mode: { //SEG561 form_mode::@30 b30: //SEG562 [296] (byte~) form_mode::$36 ← (byte) form_control::return#0 - // (byte~) form_mode::$36 = (byte) form_control::return#0 // register copy reg byte a //SEG563 [297] if((byte~) form_mode::$36==(byte/signed byte/word/signed word/dword/signed dword) 0) goto form_mode::@8 -- vbuaa_eq_0_then_la1 cmp #0 beq b8 @@ -22712,6 +22768,8 @@ form_mode: { jmp b2_from_b32 } //SEG580 render_preset_name +// Render form preset name in the form +// idx is the ID of the preset render_preset_name: { .label name = 3 //SEG581 [307] if((byte) render_preset_name::idx#10==(byte/signed byte/word/signed word/dword/signed dword) 0) goto render_preset_name::@22 -- vbuaa_eq_0_then_la1 @@ -22881,7 +22939,6 @@ render_preset_name: { //SEG628 render_preset_name::@22 b22: //SEG629 [320] (byte*) print_str_at::str#1 ← (byte*) render_preset_name::name#12 - // (byte*) print_str_at::str#1 = (byte*) render_preset_name::name#12 // register copy zp ZP_WORD:3 //SEG630 [321] call print_str_at //SEG631 [323] phi from render_preset_name::@22 to print_str_at [phi:render_preset_name::@22->print_str_at] print_str_at_from_b22: @@ -22905,6 +22962,7 @@ render_preset_name: { name_11: .text "Standard Charset @" } //SEG634 print_str_at +// Print a string at a specific screen position print_str_at: { .label at = 5 .label str = 3 @@ -22953,6 +23011,7 @@ print_str_at: { jmp b1 } //SEG649 form_render_values +// Render all form values from the form_fields_val array form_render_values: { .label field = 3 .label idx = 2 @@ -22969,19 +23028,16 @@ form_render_values: { //SEG654 form_render_values::@1 b1: //SEG655 [332] (byte) form_field_ptr::field_idx#0 ← (byte) form_render_values::idx#2 - // (byte) form_field_ptr::field_idx#0 = (byte) form_render_values::idx#2 // register copy zp ZP_BYTE:2 //SEG656 [333] call form_field_ptr //SEG657 [340] phi from form_render_values::@1 to form_field_ptr [phi:form_render_values::@1->form_field_ptr] form_field_ptr_from_b1: //SEG658 [340] phi (byte) form_field_ptr::field_idx#2 = (byte) form_field_ptr::field_idx#0 [phi:form_render_values::@1->form_field_ptr#0] -- register_copy jsr form_field_ptr //SEG659 [334] (byte*) form_field_ptr::return#2 ← (byte*) form_field_ptr::return#0 - // (byte*) form_field_ptr::return#2 = (byte*) form_field_ptr::return#0 // register copy zp ZP_WORD:3 jmp b3 //SEG660 form_render_values::@3 b3: //SEG661 [335] (byte*) form_render_values::field#0 ← (byte*) form_field_ptr::return#2 - // (byte*) form_render_values::field#0 = (byte*) form_field_ptr::return#2 // register copy zp ZP_WORD:3 //SEG662 [336] *((byte*) form_render_values::field#0) ← *((const byte[]) print_hextab#0 + *((const byte[]) form_fields_val#0 + (byte) form_render_values::idx#2)) -- _deref_pbuz1=pbuc1_derefidx_pbuc2_derefidx_vbuz2 ldy idx lda form_fields_val,y @@ -23002,6 +23058,8 @@ form_render_values: { rts } //SEG667 form_field_ptr +// Get the screen address of a form field +// field_idx is the index of the field to get the screen address for form_field_ptr: { .label return = 3 .label field_idx = 2 @@ -23032,6 +23090,8 @@ form_field_ptr: { rts } //SEG674 apply_preset +// Apply a form value preset to the form values +// idx is the ID of the preset apply_preset: { .label preset = 3 //SEG675 [346] if((byte) apply_preset::idx#0==(byte/signed byte/word/signed word/dword/signed dword) 0) goto apply_preset::@22 -- vbuaa_eq_0_then_la1 @@ -23219,6 +23279,8 @@ apply_preset: { rts } //SEG731 form_control +// Reads keyboard and allows the user to navigate and change the fields of the form +// Returns 0 if space is not pressed, non-0 if space is pressed form_control: { .label field = 3 //SEG732 [364] (byte) form_field_ptr::field_idx#1 ← (byte) form_field_idx#28 -- vbuz1=vbuxx @@ -23229,12 +23291,10 @@ form_control: { //SEG735 [340] phi (byte) form_field_ptr::field_idx#2 = (byte) form_field_ptr::field_idx#1 [phi:form_control->form_field_ptr#0] -- register_copy jsr form_field_ptr //SEG736 [366] (byte*) form_field_ptr::return#3 ← (byte*) form_field_ptr::return#0 - // (byte*) form_field_ptr::return#3 = (byte*) form_field_ptr::return#0 // register copy zp ZP_WORD:3 jmp b33 //SEG737 form_control::@33 b33: //SEG738 [367] (byte*) form_control::field#0 ← (byte*) form_field_ptr::return#3 - // (byte*) form_control::field#0 = (byte*) form_field_ptr::return#3 // register copy zp ZP_WORD:3 //SEG739 [368] (signed byte) form_cursor_count#5 ← -- (signed byte) form_cursor_count#21 -- vbsz1=_dec_vbsz1 dec form_cursor_count //SEG740 [369] if((signed byte) form_cursor_count#5>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto form_control::@36 -- vbsz1_ge_0_then_la1 @@ -23286,12 +23346,10 @@ form_control: { //SEG755 [377] call keyboard_event_get jsr keyboard_event_get //SEG756 [378] (byte) keyboard_event_get::return#4 ← (byte) keyboard_event_get::return#2 - // (byte) keyboard_event_get::return#4 = (byte) keyboard_event_get::return#2 // register copy reg byte a jmp b35 //SEG757 form_control::@35 b35: //SEG758 [379] (byte) form_control::key_event#0 ← (byte) keyboard_event_get::return#4 - // (byte) form_control::key_event#0 = (byte) keyboard_event_get::return#4 // register copy reg byte a //SEG759 [380] if((byte) form_control::key_event#0!=(const byte) KEY_CRSR_DOWN#0) goto form_control::@4 -- vbuaa_neq_vbuc1_then_la1 cmp #KEY_CRSR_DOWN bne b4 @@ -23470,6 +23528,8 @@ form_control: { jmp b1 } //SEG824 form_set_screen +// Set the screen to use for the form. +// screen is the start address of the screen to use form_set_screen: { .label line = 3 //SEG825 [410] phi from form_set_screen to form_set_screen::@1 [phi:form_set_screen->form_set_screen::@1] @@ -23517,6 +23577,8 @@ form_set_screen: { rts } //SEG841 print_str_lines +// Print a number of zero-terminated strings, each followed by a newline. +// The sequence of lines is terminated by another zero. print_str_lines: { .label str = 3 //SEG842 [420] (byte*~) print_char_cursor#77 ← (byte*) print_set_screen::screen#2 -- pbuz1=pbuz2 @@ -23600,6 +23662,7 @@ print_str_lines: { jmp b1_from_b9 } //SEG870 print_ln +// Print a newline print_ln: { //SEG871 [436] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -23632,6 +23695,7 @@ print_ln: { rts } //SEG878 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label _0 = 5 .label sc = 3 @@ -23678,6 +23742,7 @@ print_cls: { rts } //SEG889 print_set_screen +// Set the screen to print on. Also resets current line/char cursor. print_set_screen: { .label screen = $10 jmp breturn @@ -23687,6 +23752,7 @@ print_set_screen: { rts } //SEG892 gfx_init +// Initialize the different graphics in the memory gfx_init: { //SEG893 [450] call gfx_init_screen0 //SEG894 [848] phi from gfx_init to gfx_init_screen0 [phi:gfx_init->gfx_init_screen0] @@ -23823,6 +23889,7 @@ gfx_init: { rts } //SEG952 gfx_init_plane_full +// Initialize Plane with all pixels gfx_init_plane_full: { //SEG953 [481] call gfx_init_plane_fill //SEG954 [483] phi from gfx_init_plane_full to gfx_init_plane_fill [phi:gfx_init_plane_full->gfx_init_plane_fill] @@ -23847,6 +23914,7 @@ gfx_init_plane_full: { rts } //SEG959 gfx_init_plane_fill +// Initialize 320*200 1bpp pixel ($2000) plane with identical bytes gfx_init_plane_fill: { .label _0 = $13 .label _1 = 3 @@ -23915,7 +23983,6 @@ gfx_init_plane_fill: { adc #>$4000 sta _6+1 //SEG972 [493] (byte*~) gfx_init_plane_fill::gfxb#6 ← (byte*)(word/signed dword/dword~) gfx_init_plane_fill::$6 - // (byte*~) gfx_init_plane_fill::gfxb#6 = (byte*)(word/signed dword/dword~) gfx_init_plane_fill::$6 // register copy zp ZP_WORD:3 //SEG973 [494] phi from gfx_init_plane_fill::@5 to gfx_init_plane_fill::@1 [phi:gfx_init_plane_fill::@5->gfx_init_plane_fill::@1] b1_from_b5: //SEG974 [494] phi (byte) gfx_init_plane_fill::by#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:gfx_init_plane_fill::@5->gfx_init_plane_fill::@1#0] -- vbuz1=vbuc1 @@ -23984,6 +24051,9 @@ gfx_init_plane_fill: { rts } //SEG1001 dtvSetCpuBankSegment1 +// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) +// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff +// The actual memory addressed will be $4000*cpuSegmentIdx dtvSetCpuBankSegment1: { .label cpuBank = $ff //SEG1002 [506] *((const byte*) dtvSetCpuBankSegment1::cpuBank#0) ← (byte) dtvSetCpuBankSegment1::cpuBankIdx#13 -- _deref_pbuc1=vbuaa @@ -23999,6 +24069,7 @@ dtvSetCpuBankSegment1: { rts } //SEG1006 gfx_init_plane_blank +// Initialize Plane with blank pixels gfx_init_plane_blank: { //SEG1007 [510] call gfx_init_plane_fill //SEG1008 [483] phi from gfx_init_plane_blank to gfx_init_plane_fill [phi:gfx_init_plane_blank->gfx_init_plane_fill] @@ -24023,6 +24094,7 @@ gfx_init_plane_blank: { rts } //SEG1013 gfx_init_plane_vertical2 +// Initialize Plane with Vertical Stripes every 2 pixels gfx_init_plane_vertical2: { //SEG1014 [513] call gfx_init_plane_fill //SEG1015 [483] phi from gfx_init_plane_vertical2 to gfx_init_plane_fill [phi:gfx_init_plane_vertical2->gfx_init_plane_fill] @@ -24047,6 +24119,7 @@ gfx_init_plane_vertical2: { rts } //SEG1020 gfx_init_plane_horisontal2 +// Initialize Plane with Horizontal Stripes every 2 pixels gfx_init_plane_horisontal2: { .const gfxbCpuBank = PLANE_HORISONTAL2/$4000 .label gfxa = 3 @@ -24136,6 +24209,7 @@ gfx_init_plane_horisontal2: { row_bitmask: .byte 0, $55, $aa, $ff } //SEG1054 gfx_init_plane_vertical +// Initialize Plane with Vertical Stripes gfx_init_plane_vertical: { .const gfxbCpuBank = PLANE_VERTICAL/$4000 .label gfxb = 3 @@ -24218,6 +24292,7 @@ gfx_init_plane_vertical: { rts } //SEG1086 gfx_init_plane_horisontal +// Initialize Plane with Horizontal Stripes gfx_init_plane_horisontal: { .const gfxbCpuBank = PLANE_HORISONTAL/$4000 .label gfxa = 3 @@ -24328,6 +24403,7 @@ gfx_init_plane_horisontal: { jmp b4_from_b3 } //SEG1127 gfx_init_plane_charset8 +// Initialize Plane with 8bpp charset gfx_init_plane_charset8: { .const gfxbCpuBank = PLANE_CHARSET8/$4000 .label bits = 8 @@ -24496,6 +24572,7 @@ gfx_init_plane_charset8: { rts } //SEG1196 gfx_init_plane_8bppchunky +// Initialize 8BPP Chunky Bitmap (contains 8bpp pixels) gfx_init_plane_8bppchunky: { .label _6 = $10 .label gfxb = 5 @@ -24641,6 +24718,7 @@ gfx_init_plane_8bppchunky: { rts } //SEG1249 gfx_init_vic_bitmap +// Initialize VIC bitmap gfx_init_vic_bitmap: { .const lines_cnt = 9 .label l = 2 @@ -24702,6 +24780,7 @@ gfx_init_vic_bitmap: { lines_y: .byte 0, 0, $c7, $c7, 0, 0, $64, $c7, $64, 0 } //SEG1270 bitmap_line +// Draw a line on the bitmap bitmap_line: { .label xd = 8 .label yd = 7 @@ -24747,11 +24826,8 @@ bitmap_line: { //SEG1280 [625] (byte) bitmap_line_ydxi::x#0 ← (byte) bitmap_line::x1#0 -- vbuxx=vbuz1 ldx x1 //SEG1281 [626] (byte) bitmap_line_ydxi::y1#0 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_ydxi::y1#0 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:15 //SEG1282 [627] (byte) bitmap_line_ydxi::yd#0 ← (byte) bitmap_line::yd#1 - // (byte) bitmap_line_ydxi::yd#0 = (byte) bitmap_line::yd#1 // register copy zp ZP_BYTE:7 //SEG1283 [628] (byte) bitmap_line_ydxi::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_ydxi::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1284 [629] call bitmap_line_ydxi //SEG1285 [703] phi from bitmap_line::@17 to bitmap_line_ydxi [phi:bitmap_line::@17->bitmap_line_ydxi] bitmap_line_ydxi_from_b17: @@ -24774,11 +24850,8 @@ bitmap_line: { //SEG1295 [632] (byte) bitmap_line_xdyi::y#0 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_xdyi.y //SEG1296 [633] (byte) bitmap_line_xdyi::x1#0 ← (byte) bitmap_line::x0#0 - // (byte) bitmap_line_xdyi::x1#0 = (byte) bitmap_line::x0#0 // register copy zp ZP_BYTE:9 //SEG1297 [634] (byte) bitmap_line_xdyi::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_xdyi::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1298 [635] (byte) bitmap_line_xdyi::yd#0 ← (byte) bitmap_line::yd#1 - // (byte) bitmap_line_xdyi::yd#0 = (byte) bitmap_line::yd#1 // register copy zp ZP_BYTE:7 //SEG1299 [636] call bitmap_line_xdyi //SEG1300 [681] phi from bitmap_line::@3 to bitmap_line_xdyi [phi:bitmap_line::@3->bitmap_line_xdyi] bitmap_line_xdyi_from_b3: @@ -24811,9 +24884,7 @@ bitmap_line: { //SEG1312 [641] (byte) bitmap_line_ydxd::y1#0 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_ydxd.y1 //SEG1313 [642] (byte) bitmap_line_ydxd::yd#0 ← (byte) bitmap_line::yd#0 - // (byte) bitmap_line_ydxd::yd#0 = (byte) bitmap_line::yd#0 // register copy zp ZP_BYTE:7 //SEG1314 [643] (byte) bitmap_line_ydxd::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_ydxd::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1315 [644] call bitmap_line_ydxd //SEG1316 [733] phi from bitmap_line::@20 to bitmap_line_ydxd [phi:bitmap_line::@20->bitmap_line_ydxd] bitmap_line_ydxd_from_b20: @@ -24835,9 +24906,7 @@ bitmap_line: { lda x0 sta bitmap_line_xdyd.x1 //SEG1326 [648] (byte) bitmap_line_xdyd::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_xdyd::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1327 [649] (byte) bitmap_line_xdyd::yd#0 ← (byte) bitmap_line::yd#0 - // (byte) bitmap_line_xdyd::yd#0 = (byte) bitmap_line::yd#0 // register copy zp ZP_BYTE:7 //SEG1328 [650] call bitmap_line_xdyd //SEG1329 [718] phi from bitmap_line::@6 to bitmap_line_xdyd [phi:bitmap_line::@6->bitmap_line_xdyd] bitmap_line_xdyd_from_b6: @@ -24882,11 +24951,8 @@ bitmap_line: { //SEG1343 [656] (byte) bitmap_line_ydxd::x#1 ← (byte) bitmap_line::x1#0 -- vbuxx=vbuz1 ldx x1 //SEG1344 [657] (byte) bitmap_line_ydxd::y1#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_ydxd::y1#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:15 //SEG1345 [658] (byte) bitmap_line_ydxd::yd#1 ← (byte) bitmap_line::yd#3 - // (byte) bitmap_line_ydxd::yd#1 = (byte) bitmap_line::yd#3 // register copy zp ZP_BYTE:7 //SEG1346 [659] (byte) bitmap_line_ydxd::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_ydxd::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1347 [660] call bitmap_line_ydxd //SEG1348 [733] phi from bitmap_line::@24 to bitmap_line_ydxd [phi:bitmap_line::@24->bitmap_line_ydxd] bitmap_line_ydxd_from_b24: @@ -24903,13 +24969,9 @@ bitmap_line: { lda x0 sta bitmap_line_xdyd.x //SEG1356 [662] (byte) bitmap_line_xdyd::y#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_xdyd::y#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:15 //SEG1357 [663] (byte) bitmap_line_xdyd::x1#1 ← (byte) bitmap_line::x1#0 - // (byte) bitmap_line_xdyd::x1#1 = (byte) bitmap_line::x1#0 // register copy zp ZP_BYTE:18 //SEG1358 [664] (byte) bitmap_line_xdyd::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_xdyd::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1359 [665] (byte) bitmap_line_xdyd::yd#1 ← (byte) bitmap_line::yd#3 - // (byte) bitmap_line_xdyd::yd#1 = (byte) bitmap_line::yd#3 // register copy zp ZP_BYTE:7 //SEG1360 [666] call bitmap_line_xdyd //SEG1361 [718] phi from bitmap_line::@10 to bitmap_line_xdyd [phi:bitmap_line::@10->bitmap_line_xdyd] bitmap_line_xdyd_from_b10: @@ -24942,9 +25004,7 @@ bitmap_line: { //SEG1373 [671] (byte) bitmap_line_ydxi::y1#1 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_ydxi.y1 //SEG1374 [672] (byte) bitmap_line_ydxi::yd#1 ← (byte) bitmap_line::yd#10 - // (byte) bitmap_line_ydxi::yd#1 = (byte) bitmap_line::yd#10 // register copy zp ZP_BYTE:7 //SEG1375 [673] (byte) bitmap_line_ydxi::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_ydxi::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1376 [674] call bitmap_line_ydxi //SEG1377 [703] phi from bitmap_line::@27 to bitmap_line_ydxi [phi:bitmap_line::@27->bitmap_line_ydxi] bitmap_line_ydxi_from_b27: @@ -24961,14 +25021,11 @@ bitmap_line: { lda x0 sta bitmap_line_xdyi.x //SEG1385 [676] (byte) bitmap_line_xdyi::y#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_xdyi::y#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:15 //SEG1386 [677] (byte) bitmap_line_xdyi::x1#1 ← (byte) bitmap_line::x1#0 -- vbuz1=vbuz2 lda x1 sta bitmap_line_xdyi.x1 //SEG1387 [678] (byte) bitmap_line_xdyi::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_xdyi::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1388 [679] (byte) bitmap_line_xdyi::yd#1 ← (byte) bitmap_line::yd#10 - // (byte) bitmap_line_xdyi::yd#1 = (byte) bitmap_line::yd#10 // register copy zp ZP_BYTE:7 //SEG1389 [680] call bitmap_line_xdyi //SEG1390 [681] phi from bitmap_line::@13 to bitmap_line_xdyi [phi:bitmap_line::@13->bitmap_line_xdyi] bitmap_line_xdyi_from_b13: @@ -25112,7 +25169,6 @@ bitmap_line_ydxi: { //SEG1438 bitmap_line_ydxi::@1 b1: //SEG1439 [706] (byte) bitmap_plot::x#2 ← (byte) bitmap_line_ydxi::x#3 - // (byte) bitmap_plot::x#2 = (byte) bitmap_line_ydxi::x#3 // register copy reg byte x //SEG1440 [707] (byte) bitmap_plot::y#2 ← (byte) bitmap_line_ydxi::y#3 -- vbuyy=vbuz1 ldy y //SEG1441 [708] call bitmap_plot @@ -25262,7 +25318,6 @@ bitmap_line_ydxd: { //SEG1494 bitmap_line_ydxd::@1 b1: //SEG1495 [736] (byte) bitmap_plot::x#3 ← (byte) bitmap_line_ydxd::x#3 - // (byte) bitmap_plot::x#3 = (byte) bitmap_line_ydxd::x#3 // register copy reg byte x //SEG1496 [737] (byte) bitmap_plot::y#3 ← (byte) bitmap_line_ydxd::y#2 -- vbuyy=vbuz1 ldy y //SEG1497 [738] call bitmap_plot @@ -25317,6 +25372,7 @@ bitmap_line_ydxd: { rts } //SEG1516 bitmap_clear +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = 3 .label y = 2 @@ -25327,7 +25383,6 @@ bitmap_clear: { lda bitmap_plot_xhi sta _3+1 //SEG1518 [749] (byte*~) bitmap_clear::bitmap#5 ← (byte*)(word~) bitmap_clear::$3 - // (byte*~) bitmap_clear::bitmap#5 = (byte*)(word~) bitmap_clear::$3 // register copy zp ZP_WORD:3 //SEG1519 [750] phi from bitmap_clear to bitmap_clear::@1 [phi:bitmap_clear->bitmap_clear::@1] b1_from_bitmap_clear: //SEG1520 [750] phi (byte) bitmap_clear::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:bitmap_clear->bitmap_clear::@1#0] -- vbuz1=vbuc1 @@ -25385,6 +25440,7 @@ bitmap_clear: { rts } //SEG1542 bitmap_init +// Initialize the bitmap plotter tables for a specific bitmap bitmap_init: { .label _6 = 2 .label yoffs = 3 @@ -25596,6 +25652,7 @@ gfx_init_charset: { rts } //SEG1621 gfx_init_screen4 +// Initialize VIC screen 4 - all chars are 00 gfx_init_screen4: { .label ch = 3 .label cy = 2 @@ -25660,6 +25717,7 @@ gfx_init_screen4: { rts } //SEG1645 gfx_init_screen3 +// Initialize VIC screen 3 ( value is %00xx00yy where xx is xpos and yy is ypos gfx_init_screen3: { .label _1 = 7 .label ch = 3 @@ -25738,6 +25796,7 @@ gfx_init_screen3: { rts } //SEG1673 gfx_init_screen2 +// Initialize VIC screen 2 ( value is %ccccrrrr where cccc is (x+y mod $f) and rrrr is %1111-%cccc) gfx_init_screen2: { .label col2 = 7 .label ch = 3 @@ -25823,6 +25882,7 @@ gfx_init_screen2: { rts } //SEG1702 gfx_init_screen1 +// Initialize VIC screen 1 ( value is %0000cccc where cccc is (x+y mod $f)) gfx_init_screen1: { .label ch = 3 .label cy = 2 @@ -25892,6 +25952,7 @@ gfx_init_screen1: { rts } //SEG1728 gfx_init_screen0 +// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos) gfx_init_screen0: { .label _1 = 7 .label ch = 3 @@ -25970,6 +26031,7 @@ gfx_init_screen0: { rts } //SEG1756 keyboard_init +// Initialize keyboard reading by setting CIA#$ Data Direction Registers keyboard_init: { //SEG1757 [862] *((const byte*) CIA1_PORT_A_DDR#0) ← (byte/word/signed word/dword/signed dword) 255 -- _deref_pbuc1=vbuc2 lda #$ff @@ -26466,6 +26528,7 @@ Removing instruction b8_from_b30: Removing instruction b8_from_b7: Removing instruction b31_from_b8: Removing instruction b9_from_b31: +Removing instruction b10_from_b50: Removing instruction b10_from_b32: Removing instruction b11_from_b10: Removing instruction b11_from_b11: @@ -26519,7 +26582,9 @@ Removing instruction b2: Removing instruction b7_from_b5: Removing instruction b33_from_b32: Removing instruction b22_from_b33: +Removing instruction print_str_at_from_b22: Removing instruction b1_from_b3: +Removing instruction form_field_ptr_from_b1: Removing instruction b34_from_b33: Removing instruction b22_from_apply_preset: Removing instruction b22_from_b34: @@ -26679,7 +26744,6 @@ Removing instruction b48: Removing instruction b49: Removing instruction get_vic_screen_from_b49: Removing instruction b50: -Removing instruction b10_from_b50: Removing instruction b32: Removing instruction b33: Removing instruction b13_from_b33: @@ -26760,13 +26824,11 @@ Removing instruction b30: Removing instruction b31: Removing instruction b32: Removing instruction b33: -Removing instruction print_str_at_from_b22: Removing instruction breturn: Removing instruction b1_from_print_str_at: Removing instruction breturn: Removing instruction b1_from_b2: Removing instruction b1_from_form_render_values: -Removing instruction form_field_ptr_from_b1: Removing instruction b3: Removing instruction breturn: Removing instruction breturn: @@ -27075,18 +27137,18 @@ Removing instruction b37: Succesful ASM optimization Pass5UnusedLabelElimination Removing unreachable instruction jmp b7 Succesful ASM optimization Pass5UnreachableCodeElimination -Fixing long branch [686] beq b5 to bne -Fixing long branch [690] beq b6 to bne -Fixing long branch [694] beq b7 to bne -Fixing long branch [698] beq b8 to bne -Fixing long branch [684] beq b4 to bne -Fixing long branch [704] beq b9 to bne -Fixing long branch [708] beq b10 to bne -Fixing long branch [712] beq b11 to bne -Fixing long branch [716] beq b12 to bne -Fixing long branch [682] beq b3 to bne -Fixing long branch [722] beq b13 to bne -Fixing long branch [1246] bmi b2 to bpl +Fixing long branch [704] beq b5 to bne +Fixing long branch [708] beq b6 to bne +Fixing long branch [712] beq b7 to bne +Fixing long branch [716] beq b8 to bne +Fixing long branch [702] beq b4 to bne +Fixing long branch [722] beq b9 to bne +Fixing long branch [726] beq b10 to bne +Fixing long branch [730] beq b11 to bne +Fixing long branch [734] beq b12 to bne +Fixing long branch [700] beq b3 to bne +Fixing long branch [740] beq b13 to bne +Fixing long branch [1275] bmi b2 to bpl FINAL SYMBOL TABLE (label) @68 @@ -28979,6 +29041,7 @@ main: { jmp b2 } //SEG34 gfx_mode +// Change graphics mode to show the selected graphics mode gfx_mode: { .label _31 = $a .label _33 = 3 @@ -29148,10 +29211,8 @@ gfx_mode: { //SEG103 [236] phi (byte) get_plane::idx#10 = (byte) get_plane::idx#0 [phi:gfx_mode::@9->get_plane#0] -- register_copy jsr get_plane //SEG104 [50] (dword) get_plane::return#16 ← (dword) get_plane::return#14 - // (dword) get_plane::return#16 = (dword) get_plane::return#14 // register copy zp ZP_DWORD:10 //SEG105 gfx_mode::@46 //SEG106 [51] (dword~) gfx_mode::$31 ← (dword) get_plane::return#16 - // (dword~) gfx_mode::$31 = (dword) get_plane::return#16 // register copy zp ZP_DWORD:10 //SEG107 [52] (dword) gfx_mode::plane_a#0 ← (dword~) gfx_mode::$31 + (byte) gfx_mode::plane_a_offs#0 -- vduz1=vduz1_plus_vbuyy tya clc @@ -29231,10 +29292,8 @@ gfx_mode: { //SEG129 [236] phi (byte) get_plane::idx#10 = (byte) get_plane::idx#1 [phi:gfx_mode::@46->get_plane#0] -- register_copy jsr get_plane //SEG130 [73] (dword) get_plane::return#17 ← (dword) get_plane::return#14 - // (dword) get_plane::return#17 = (dword) get_plane::return#14 // register copy zp ZP_DWORD:10 //SEG131 gfx_mode::@47 //SEG132 [74] (dword~) gfx_mode::$45 ← (dword) get_plane::return#17 - // (dword~) gfx_mode::$45 = (dword) get_plane::return#17 // register copy zp ZP_DWORD:10 //SEG133 [75] (dword) gfx_mode::plane_b#0 ← (dword~) gfx_mode::$45 + (byte) gfx_mode::plane_b_offs#0 -- vduz1=vduz1_plus_vbuyy tya clc @@ -29311,10 +29370,8 @@ gfx_mode: { //SEG155 [222] phi (byte) get_vic_screen::idx#2 = (byte) get_vic_screen::idx#0 [phi:gfx_mode::@47->get_vic_screen#0] -- register_copy jsr get_vic_screen //SEG156 [96] (byte*) get_vic_screen::return#10 ← (byte*) get_vic_screen::return#5 - // (byte*) get_vic_screen::return#10 = (byte*) get_vic_screen::return#5 // register copy zp ZP_WORD:3 //SEG157 gfx_mode::@48 //SEG158 [97] (byte*~) gfx_mode::$61 ← (byte*) get_vic_screen::return#10 - // (byte*~) gfx_mode::$61 = (byte*) get_vic_screen::return#10 // register copy zp ZP_WORD:3 //SEG159 [98] (word~) gfx_mode::$63 ← (word)(byte*~) gfx_mode::$61 & (word/signed word/dword/signed dword) 16383 -- vwuz1=vwuz1_band_vwuc1 lda _63 and #<$3fff @@ -29337,10 +29394,8 @@ gfx_mode: { //SEG163 [102] call get_vic_charset jsr get_vic_charset //SEG164 [103] (byte*) get_vic_charset::return#4 ← (byte*) get_vic_charset::return#2 - // (byte*) get_vic_charset::return#4 = (byte*) get_vic_charset::return#2 // register copy zp ZP_WORD:3 //SEG165 gfx_mode::@49 //SEG166 [104] (byte*~) gfx_mode::$66 ← (byte*) get_vic_charset::return#4 - // (byte*~) gfx_mode::$66 = (byte*) get_vic_charset::return#4 // register copy zp ZP_WORD:3 //SEG167 [105] (word~) gfx_mode::$68 ← (word)(byte*~) gfx_mode::$66 & (word/signed word/dword/signed dword) 16383 -- vwuz1=vwuz1_band_vwuc1 lda _68 and #<$3fff @@ -29363,10 +29418,8 @@ gfx_mode: { //SEG175 [222] phi (byte) get_vic_screen::idx#2 = (byte) get_vic_screen::idx#1 [phi:gfx_mode::@49->get_vic_screen#0] -- register_copy jsr get_vic_screen //SEG176 [112] (byte*) get_vic_screen::return#11 ← (byte*) get_vic_screen::return#5 - // (byte*) get_vic_screen::return#11 = (byte*) get_vic_screen::return#5 // register copy zp ZP_WORD:3 //SEG177 gfx_mode::@50 //SEG178 [113] (byte*) gfx_mode::vic_colors#0 ← (byte*) get_vic_screen::return#11 - // (byte*) gfx_mode::vic_colors#0 = (byte*) get_vic_screen::return#11 // register copy zp ZP_WORD:3 //SEG179 [114] phi from gfx_mode::@50 to gfx_mode::@10 [phi:gfx_mode::@50->gfx_mode::@10] //SEG180 [114] phi (byte) gfx_mode::cy#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:gfx_mode::@50->gfx_mode::@10#0] -- vbuz1=vbuc1 lda #0 @@ -29502,10 +29555,8 @@ gfx_mode: { //SEG237 [145] call keyboard_event_get jsr keyboard_event_get //SEG238 [146] (byte) keyboard_event_get::return#3 ← (byte) keyboard_event_get::return#2 - // (byte) keyboard_event_get::return#3 = (byte) keyboard_event_get::return#2 // register copy reg byte a //SEG239 gfx_mode::@52 //SEG240 [147] (byte) gfx_mode::keyboard_event#0 ← (byte) keyboard_event_get::return#3 - // (byte) gfx_mode::keyboard_event#0 = (byte) keyboard_event_get::return#3 // register copy reg byte a //SEG241 [148] if((byte) gfx_mode::keyboard_event#0!=(const byte) KEY_SPACE#0) goto gfx_mode::@19 -- vbuaa_neq_vbuc1_then_la1 cmp #KEY_SPACE bne b19 @@ -29531,6 +29582,9 @@ gfx_mode: { jmp b19 } //SEG252 keyboard_event_get +// Get the next event from the keyboard event buffer. +// Returns $ff if there is no event waiting. As all events are <$7f it is enough to examine bit 7 when determining if there is any event to process. +// The buffer is filled by keyboard_event_scan() keyboard_event_get: { //SEG253 [154] if((byte) keyboard_events_size#100==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_get::@return -- vbuz1_eq_0_then_la1 lda keyboard_events_size @@ -29557,6 +29611,10 @@ keyboard_event_get: { rts } //SEG265 keyboard_event_scan +// Scans the entire matrix to determine which keys have been pressed/depressed. +// Generates keyboard events into the event buffer. Events can be read using keyboard_event_get(). +// Handles debounce and only generates events when the status of a key changes. +// Also stores current status of modifiers in keyboard_modifiers. keyboard_event_scan: { .label row_scan = $12 .label keycode = 8 @@ -29580,7 +29638,6 @@ keyboard_event_scan: { //SEG276 [162] call keyboard_matrix_read jsr keyboard_matrix_read //SEG277 [163] (byte) keyboard_matrix_read::return#2 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#2 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a //SEG278 keyboard_event_scan::@25 //SEG279 [164] (byte) keyboard_event_scan::row_scan#0 ← (byte) keyboard_matrix_read::return#2 -- vbuz1=vbuaa sta row_scan @@ -29614,10 +29671,8 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG294 [172] (byte) keyboard_event_pressed::return#0 ← (byte) keyboard_event_pressed::return#10 - // (byte) keyboard_event_pressed::return#0 = (byte) keyboard_event_pressed::return#10 // register copy reg byte a //SEG295 keyboard_event_scan::@26 //SEG296 [173] (byte~) keyboard_event_scan::$14 ← (byte) keyboard_event_pressed::return#0 - // (byte~) keyboard_event_scan::$14 = (byte) keyboard_event_pressed::return#0 // register copy reg byte a //SEG297 [174] if((byte~) keyboard_event_scan::$14==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@9 -- vbuaa_eq_0_then_la1 cmp #0 beq b2 @@ -29642,10 +29697,8 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG308 [178] (byte) keyboard_event_pressed::return#1 ← (byte) keyboard_event_pressed::return#10 - // (byte) keyboard_event_pressed::return#1 = (byte) keyboard_event_pressed::return#10 // register copy reg byte a //SEG309 keyboard_event_scan::@27 //SEG310 [179] (byte~) keyboard_event_scan::$18 ← (byte) keyboard_event_pressed::return#1 - // (byte~) keyboard_event_scan::$18 = (byte) keyboard_event_pressed::return#1 // register copy reg byte a //SEG311 [180] if((byte~) keyboard_event_scan::$18==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@10 -- vbuaa_eq_0_then_la1 cmp #0 beq b10 @@ -29665,10 +29718,8 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG320 [184] (byte) keyboard_event_pressed::return#2 ← (byte) keyboard_event_pressed::return#10 - // (byte) keyboard_event_pressed::return#2 = (byte) keyboard_event_pressed::return#10 // register copy reg byte a //SEG321 keyboard_event_scan::@28 //SEG322 [185] (byte~) keyboard_event_scan::$22 ← (byte) keyboard_event_pressed::return#2 - // (byte~) keyboard_event_scan::$22 = (byte) keyboard_event_pressed::return#2 // register copy reg byte a //SEG323 [186] if((byte~) keyboard_event_scan::$22==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@11 -- vbuaa_eq_0_then_la1 cmp #0 beq b11 @@ -29688,10 +29739,8 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG332 [190] (byte) keyboard_event_pressed::return#3 ← (byte) keyboard_event_pressed::return#10 - // (byte) keyboard_event_pressed::return#3 = (byte) keyboard_event_pressed::return#10 // register copy reg byte a //SEG333 keyboard_event_scan::@29 //SEG334 [191] (byte~) keyboard_event_scan::$26 ← (byte) keyboard_event_pressed::return#3 - // (byte~) keyboard_event_scan::$26 = (byte) keyboard_event_pressed::return#3 // register copy reg byte a //SEG335 [192] if((byte~) keyboard_event_scan::$26==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@return -- vbuaa_eq_0_then_la1 cmp #0 beq breturn @@ -29779,6 +29828,8 @@ keyboard_event_scan: { jmp b5 } //SEG374 keyboard_event_pressed +// Determine if a specific key is currently pressed based on the last keyboard_event_scan() +// Returns 0 is not pressed and non-0 if pressed keyboard_event_pressed: { .label row_bits = 8 .label keycode = 7 @@ -29803,6 +29854,11 @@ keyboard_event_pressed: { rts } //SEG381 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { //SEG382 [219] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0 + (byte) keyboard_matrix_read::rowid#0) -- _deref_pbuc1=pbuc2_derefidx_vbuaa tay @@ -29816,6 +29872,7 @@ keyboard_matrix_read: { rts } //SEG386 get_vic_screen +// Get the VIC screen address from the screen index get_vic_screen: { .label return = 3 //SEG387 [223] if((byte) get_vic_screen::idx#2==(byte/signed byte/word/signed word/dword/signed dword) 0) goto get_vic_screen::@return -- vbuaa_eq_0_then_la1 @@ -29883,6 +29940,7 @@ get_vic_screen: { //SEG409 get_vic_screen::@9 } //SEG410 get_vic_charset +// Get the VIC charset/bitmap address from the index get_vic_charset: { .label return = 3 //SEG411 [231] if((byte) get_vic_charset::idx#0==(byte/signed byte/word/signed word/dword/signed dword) 0) goto get_vic_charset::@return -- vbuaa_eq_0_then_la1 @@ -29914,6 +29972,7 @@ get_vic_charset: { //SEG421 get_vic_charset::@3 } //SEG422 get_plane +// Get plane address from a plane index (from the form) get_plane: { .label return = $a //SEG423 [237] if((byte) get_plane::idx#10==(byte/signed byte/word/signed word/dword/signed dword) 0) goto get_plane::@return -- vbuaa_eq_0_then_la1 @@ -30167,6 +30226,7 @@ get_plane: { //SEG481 get_plane::@27 } //SEG482 form_mode +// Show the form - and let the user change values form_mode: { .label preset_current = $f //SEG483 [255] call print_set_screen @@ -30317,7 +30377,6 @@ form_mode: { tya //SEG561 form_mode::@30 //SEG562 [296] (byte~) form_mode::$36 ← (byte) form_control::return#0 - // (byte~) form_mode::$36 = (byte) form_control::return#0 // register copy reg byte a //SEG563 [297] if((byte~) form_mode::$36==(byte/signed byte/word/signed word/dword/signed dword) 0) goto form_mode::@8 -- vbuaa_eq_0_then_la1 cmp #0 beq b8 @@ -30351,6 +30410,8 @@ form_mode: { jmp b5 } //SEG580 render_preset_name +// Render form preset name in the form +// idx is the ID of the preset render_preset_name: { .label name = 3 //SEG581 [307] if((byte) render_preset_name::idx#10==(byte/signed byte/word/signed word/dword/signed dword) 0) goto render_preset_name::@22 -- vbuaa_eq_0_then_la1 @@ -30495,7 +30556,6 @@ render_preset_name: { //SEG628 render_preset_name::@22 b22: //SEG629 [320] (byte*) print_str_at::str#1 ← (byte*) render_preset_name::name#12 - // (byte*) print_str_at::str#1 = (byte*) render_preset_name::name#12 // register copy zp ZP_WORD:3 //SEG630 [321] call print_str_at //SEG631 [323] phi from render_preset_name::@22 to print_str_at [phi:render_preset_name::@22->print_str_at] jsr print_str_at @@ -30516,6 +30576,7 @@ render_preset_name: { name_11: .text "Standard Charset @" } //SEG634 print_str_at +// Print a string at a specific screen position print_str_at: { .label at = 5 .label str = 3 @@ -30558,6 +30619,7 @@ print_str_at: { jmp b1 } //SEG649 form_render_values +// Render all form values from the form_fields_val array form_render_values: { .label field = 3 .label idx = 2 @@ -30570,16 +30632,13 @@ form_render_values: { //SEG654 form_render_values::@1 b1: //SEG655 [332] (byte) form_field_ptr::field_idx#0 ← (byte) form_render_values::idx#2 - // (byte) form_field_ptr::field_idx#0 = (byte) form_render_values::idx#2 // register copy zp ZP_BYTE:2 //SEG656 [333] call form_field_ptr //SEG657 [340] phi from form_render_values::@1 to form_field_ptr [phi:form_render_values::@1->form_field_ptr] //SEG658 [340] phi (byte) form_field_ptr::field_idx#2 = (byte) form_field_ptr::field_idx#0 [phi:form_render_values::@1->form_field_ptr#0] -- register_copy jsr form_field_ptr //SEG659 [334] (byte*) form_field_ptr::return#2 ← (byte*) form_field_ptr::return#0 - // (byte*) form_field_ptr::return#2 = (byte*) form_field_ptr::return#0 // register copy zp ZP_WORD:3 //SEG660 form_render_values::@3 //SEG661 [335] (byte*) form_render_values::field#0 ← (byte*) form_field_ptr::return#2 - // (byte*) form_render_values::field#0 = (byte*) form_field_ptr::return#2 // register copy zp ZP_WORD:3 //SEG662 [336] *((byte*) form_render_values::field#0) ← *((const byte[]) print_hextab#0 + *((const byte[]) form_fields_val#0 + (byte) form_render_values::idx#2)) -- _deref_pbuz1=pbuc1_derefidx_pbuc2_derefidx_vbuz2 ldy idx lda form_fields_val,y @@ -30598,6 +30657,8 @@ form_render_values: { rts } //SEG667 form_field_ptr +// Get the screen address of a form field +// field_idx is the index of the field to get the screen address for form_field_ptr: { .label return = 3 .label field_idx = 2 @@ -30626,6 +30687,8 @@ form_field_ptr: { rts } //SEG674 apply_preset +// Apply a form value preset to the form values +// idx is the ID of the preset apply_preset: { .label preset = 3 //SEG675 [346] if((byte) apply_preset::idx#0==(byte/signed byte/word/signed word/dword/signed dword) 0) goto apply_preset::@22 -- vbuaa_eq_0_then_la1 @@ -30782,6 +30845,8 @@ apply_preset: { rts } //SEG731 form_control +// Reads keyboard and allows the user to navigate and change the fields of the form +// Returns 0 if space is not pressed, non-0 if space is pressed form_control: { .label field = 3 //SEG732 [364] (byte) form_field_ptr::field_idx#1 ← (byte) form_field_idx#28 -- vbuz1=vbuxx @@ -30791,10 +30856,8 @@ form_control: { //SEG735 [340] phi (byte) form_field_ptr::field_idx#2 = (byte) form_field_ptr::field_idx#1 [phi:form_control->form_field_ptr#0] -- register_copy jsr form_field_ptr //SEG736 [366] (byte*) form_field_ptr::return#3 ← (byte*) form_field_ptr::return#0 - // (byte*) form_field_ptr::return#3 = (byte*) form_field_ptr::return#0 // register copy zp ZP_WORD:3 //SEG737 form_control::@33 //SEG738 [367] (byte*) form_control::field#0 ← (byte*) form_field_ptr::return#3 - // (byte*) form_control::field#0 = (byte*) form_field_ptr::return#3 // register copy zp ZP_WORD:3 //SEG739 [368] (signed byte) form_cursor_count#5 ← -- (signed byte) form_cursor_count#21 -- vbsz1=_dec_vbsz1 dec form_cursor_count //SEG740 [369] if((signed byte) form_cursor_count#5>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto form_control::@36 -- vbsz1_ge_0_then_la1 @@ -30836,10 +30899,8 @@ form_control: { //SEG755 [377] call keyboard_event_get jsr keyboard_event_get //SEG756 [378] (byte) keyboard_event_get::return#4 ← (byte) keyboard_event_get::return#2 - // (byte) keyboard_event_get::return#4 = (byte) keyboard_event_get::return#2 // register copy reg byte a //SEG757 form_control::@35 //SEG758 [379] (byte) form_control::key_event#0 ← (byte) keyboard_event_get::return#4 - // (byte) form_control::key_event#0 = (byte) keyboard_event_get::return#4 // register copy reg byte a //SEG759 [380] if((byte) form_control::key_event#0!=(const byte) KEY_CRSR_DOWN#0) goto form_control::@4 -- vbuaa_neq_vbuc1_then_la1 cmp #KEY_CRSR_DOWN bne b4 @@ -30977,6 +31038,8 @@ form_control: { //SEG823 [370] phi (signed byte) form_cursor_count#15 = (signed byte) form_cursor_count#5 [phi:form_control::@36->form_control::@1#0] -- register_copy } //SEG824 form_set_screen +// Set the screen to use for the form. +// screen is the start address of the screen to use form_set_screen: { .label line = 3 //SEG825 [410] phi from form_set_screen to form_set_screen::@1 [phi:form_set_screen->form_set_screen::@1] @@ -31018,6 +31081,8 @@ form_set_screen: { rts } //SEG841 print_str_lines +// Print a number of zero-terminated strings, each followed by a newline. +// The sequence of lines is terminated by another zero. print_str_lines: { .label str = 3 //SEG842 [420] (byte*~) print_char_cursor#77 ← (byte*) print_set_screen::screen#2 -- pbuz1=pbuz2 @@ -31084,6 +31149,7 @@ print_str_lines: { jmp b1 } //SEG870 print_ln +// Print a newline print_ln: { //SEG871 [436] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] //SEG872 [436] phi (byte*) print_line_cursor#21 = (byte*) print_line_cursor#2 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy @@ -31111,6 +31177,7 @@ print_ln: { rts } //SEG878 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label _0 = 5 .label sc = 3 @@ -31152,6 +31219,7 @@ print_cls: { rts } //SEG889 print_set_screen +// Set the screen to print on. Also resets current line/char cursor. print_set_screen: { .label screen = $10 //SEG890 print_set_screen::@return @@ -31159,6 +31227,7 @@ print_set_screen: { rts } //SEG892 gfx_init +// Initialize the different graphics in the memory gfx_init: { //SEG893 [450] call gfx_init_screen0 //SEG894 [848] phi from gfx_init to gfx_init_screen0 [phi:gfx_init->gfx_init_screen0] @@ -31237,6 +31306,7 @@ gfx_init: { rts } //SEG952 gfx_init_plane_full +// Initialize Plane with all pixels gfx_init_plane_full: { //SEG953 [481] call gfx_init_plane_fill //SEG954 [483] phi from gfx_init_plane_full to gfx_init_plane_fill [phi:gfx_init_plane_full->gfx_init_plane_fill] @@ -31258,6 +31328,7 @@ gfx_init_plane_full: { rts } //SEG959 gfx_init_plane_fill +// Initialize 320*200 1bpp pixel ($2000) plane with identical bytes gfx_init_plane_fill: { .label _0 = $13 .label _1 = 3 @@ -31323,7 +31394,6 @@ gfx_init_plane_fill: { adc #>$4000 sta _6+1 //SEG972 [493] (byte*~) gfx_init_plane_fill::gfxb#6 ← (byte*)(word/signed dword/dword~) gfx_init_plane_fill::$6 - // (byte*~) gfx_init_plane_fill::gfxb#6 = (byte*)(word/signed dword/dword~) gfx_init_plane_fill::$6 // register copy zp ZP_WORD:3 //SEG973 [494] phi from gfx_init_plane_fill::@5 to gfx_init_plane_fill::@1 [phi:gfx_init_plane_fill::@5->gfx_init_plane_fill::@1] //SEG974 [494] phi (byte) gfx_init_plane_fill::by#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:gfx_init_plane_fill::@5->gfx_init_plane_fill::@1#0] -- vbuz1=vbuc1 lda #0 @@ -31376,6 +31446,9 @@ gfx_init_plane_fill: { rts } //SEG1001 dtvSetCpuBankSegment1 +// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) +// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff +// The actual memory addressed will be $4000*cpuSegmentIdx dtvSetCpuBankSegment1: { .label cpuBank = $ff //SEG1002 [506] *((const byte*) dtvSetCpuBankSegment1::cpuBank#0) ← (byte) dtvSetCpuBankSegment1::cpuBankIdx#13 -- _deref_pbuc1=vbuaa @@ -31389,6 +31462,7 @@ dtvSetCpuBankSegment1: { rts } //SEG1006 gfx_init_plane_blank +// Initialize Plane with blank pixels gfx_init_plane_blank: { //SEG1007 [510] call gfx_init_plane_fill //SEG1008 [483] phi from gfx_init_plane_blank to gfx_init_plane_fill [phi:gfx_init_plane_blank->gfx_init_plane_fill] @@ -31410,6 +31484,7 @@ gfx_init_plane_blank: { rts } //SEG1013 gfx_init_plane_vertical2 +// Initialize Plane with Vertical Stripes every 2 pixels gfx_init_plane_vertical2: { //SEG1014 [513] call gfx_init_plane_fill //SEG1015 [483] phi from gfx_init_plane_vertical2 to gfx_init_plane_fill [phi:gfx_init_plane_vertical2->gfx_init_plane_fill] @@ -31431,6 +31506,7 @@ gfx_init_plane_vertical2: { rts } //SEG1020 gfx_init_plane_horisontal2 +// Initialize Plane with Horizontal Stripes every 2 pixels gfx_init_plane_horisontal2: { .const gfxbCpuBank = PLANE_HORISONTAL2/$4000 .label gfxa = 3 @@ -31503,6 +31579,7 @@ gfx_init_plane_horisontal2: { row_bitmask: .byte 0, $55, $aa, $ff } //SEG1054 gfx_init_plane_vertical +// Initialize Plane with Vertical Stripes gfx_init_plane_vertical: { .const gfxbCpuBank = PLANE_VERTICAL/$4000 .label gfxb = 3 @@ -31568,6 +31645,7 @@ gfx_init_plane_vertical: { rts } //SEG1086 gfx_init_plane_horisontal +// Initialize Plane with Horizontal Stripes gfx_init_plane_horisontal: { .const gfxbCpuBank = PLANE_HORISONTAL/$4000 .label gfxa = 3 @@ -31656,6 +31734,7 @@ gfx_init_plane_horisontal: { jmp b4 } //SEG1127 gfx_init_plane_charset8 +// Initialize Plane with 8bpp charset gfx_init_plane_charset8: { .const gfxbCpuBank = PLANE_CHARSET8/$4000 .label bits = 8 @@ -31795,6 +31874,7 @@ gfx_init_plane_charset8: { rts } //SEG1196 gfx_init_plane_8bppchunky +// Initialize 8BPP Chunky Bitmap (contains 8bpp pixels) gfx_init_plane_8bppchunky: { .label _6 = $10 .label gfxb = 5 @@ -31913,6 +31993,7 @@ gfx_init_plane_8bppchunky: { rts } //SEG1249 gfx_init_vic_bitmap +// Initialize VIC bitmap gfx_init_vic_bitmap: { .const lines_cnt = 9 .label l = 2 @@ -31960,6 +32041,7 @@ gfx_init_vic_bitmap: { lines_y: .byte 0, 0, $c7, $c7, 0, 0, $64, $c7, $64, 0 } //SEG1270 bitmap_line +// Draw a line on the bitmap bitmap_line: { .label xd = 8 .label yd = 7 @@ -31997,11 +32079,8 @@ bitmap_line: { //SEG1280 [625] (byte) bitmap_line_ydxi::x#0 ← (byte) bitmap_line::x1#0 -- vbuxx=vbuz1 ldx x1 //SEG1281 [626] (byte) bitmap_line_ydxi::y1#0 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_ydxi::y1#0 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:15 //SEG1282 [627] (byte) bitmap_line_ydxi::yd#0 ← (byte) bitmap_line::yd#1 - // (byte) bitmap_line_ydxi::yd#0 = (byte) bitmap_line::yd#1 // register copy zp ZP_BYTE:7 //SEG1283 [628] (byte) bitmap_line_ydxi::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_ydxi::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1284 [629] call bitmap_line_ydxi //SEG1285 [703] phi from bitmap_line::@17 to bitmap_line_ydxi [phi:bitmap_line::@17->bitmap_line_ydxi] //SEG1286 [703] phi (byte) bitmap_line_ydxi::y1#6 = (byte) bitmap_line_ydxi::y1#0 [phi:bitmap_line::@17->bitmap_line_ydxi#0] -- register_copy @@ -32022,11 +32101,8 @@ bitmap_line: { //SEG1295 [632] (byte) bitmap_line_xdyi::y#0 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_xdyi.y //SEG1296 [633] (byte) bitmap_line_xdyi::x1#0 ← (byte) bitmap_line::x0#0 - // (byte) bitmap_line_xdyi::x1#0 = (byte) bitmap_line::x0#0 // register copy zp ZP_BYTE:9 //SEG1297 [634] (byte) bitmap_line_xdyi::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_xdyi::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1298 [635] (byte) bitmap_line_xdyi::yd#0 ← (byte) bitmap_line::yd#1 - // (byte) bitmap_line_xdyi::yd#0 = (byte) bitmap_line::yd#1 // register copy zp ZP_BYTE:7 //SEG1299 [636] call bitmap_line_xdyi //SEG1300 [681] phi from bitmap_line::@3 to bitmap_line_xdyi [phi:bitmap_line::@3->bitmap_line_xdyi] //SEG1301 [681] phi (byte) bitmap_line_xdyi::x1#6 = (byte) bitmap_line_xdyi::x1#0 [phi:bitmap_line::@3->bitmap_line_xdyi#0] -- register_copy @@ -32055,9 +32131,7 @@ bitmap_line: { //SEG1312 [641] (byte) bitmap_line_ydxd::y1#0 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_ydxd.y1 //SEG1313 [642] (byte) bitmap_line_ydxd::yd#0 ← (byte) bitmap_line::yd#0 - // (byte) bitmap_line_ydxd::yd#0 = (byte) bitmap_line::yd#0 // register copy zp ZP_BYTE:7 //SEG1314 [643] (byte) bitmap_line_ydxd::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_ydxd::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1315 [644] call bitmap_line_ydxd //SEG1316 [733] phi from bitmap_line::@20 to bitmap_line_ydxd [phi:bitmap_line::@20->bitmap_line_ydxd] //SEG1317 [733] phi (byte) bitmap_line_ydxd::y1#6 = (byte) bitmap_line_ydxd::y1#0 [phi:bitmap_line::@20->bitmap_line_ydxd#0] -- register_copy @@ -32078,9 +32152,7 @@ bitmap_line: { lda x0 sta bitmap_line_xdyd.x1 //SEG1326 [648] (byte) bitmap_line_xdyd::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_xdyd::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1327 [649] (byte) bitmap_line_xdyd::yd#0 ← (byte) bitmap_line::yd#0 - // (byte) bitmap_line_xdyd::yd#0 = (byte) bitmap_line::yd#0 // register copy zp ZP_BYTE:7 //SEG1328 [650] call bitmap_line_xdyd //SEG1329 [718] phi from bitmap_line::@6 to bitmap_line_xdyd [phi:bitmap_line::@6->bitmap_line_xdyd] //SEG1330 [718] phi (byte) bitmap_line_xdyd::x1#6 = (byte) bitmap_line_xdyd::x1#0 [phi:bitmap_line::@6->bitmap_line_xdyd#0] -- register_copy @@ -32119,11 +32191,8 @@ bitmap_line: { //SEG1343 [656] (byte) bitmap_line_ydxd::x#1 ← (byte) bitmap_line::x1#0 -- vbuxx=vbuz1 ldx x1 //SEG1344 [657] (byte) bitmap_line_ydxd::y1#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_ydxd::y1#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:15 //SEG1345 [658] (byte) bitmap_line_ydxd::yd#1 ← (byte) bitmap_line::yd#3 - // (byte) bitmap_line_ydxd::yd#1 = (byte) bitmap_line::yd#3 // register copy zp ZP_BYTE:7 //SEG1346 [659] (byte) bitmap_line_ydxd::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_ydxd::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1347 [660] call bitmap_line_ydxd //SEG1348 [733] phi from bitmap_line::@24 to bitmap_line_ydxd [phi:bitmap_line::@24->bitmap_line_ydxd] //SEG1349 [733] phi (byte) bitmap_line_ydxd::y1#6 = (byte) bitmap_line_ydxd::y1#1 [phi:bitmap_line::@24->bitmap_line_ydxd#0] -- register_copy @@ -32139,13 +32208,9 @@ bitmap_line: { lda x0 sta bitmap_line_xdyd.x //SEG1356 [662] (byte) bitmap_line_xdyd::y#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_xdyd::y#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:15 //SEG1357 [663] (byte) bitmap_line_xdyd::x1#1 ← (byte) bitmap_line::x1#0 - // (byte) bitmap_line_xdyd::x1#1 = (byte) bitmap_line::x1#0 // register copy zp ZP_BYTE:18 //SEG1358 [664] (byte) bitmap_line_xdyd::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_xdyd::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1359 [665] (byte) bitmap_line_xdyd::yd#1 ← (byte) bitmap_line::yd#3 - // (byte) bitmap_line_xdyd::yd#1 = (byte) bitmap_line::yd#3 // register copy zp ZP_BYTE:7 //SEG1360 [666] call bitmap_line_xdyd //SEG1361 [718] phi from bitmap_line::@10 to bitmap_line_xdyd [phi:bitmap_line::@10->bitmap_line_xdyd] //SEG1362 [718] phi (byte) bitmap_line_xdyd::x1#6 = (byte) bitmap_line_xdyd::x1#1 [phi:bitmap_line::@10->bitmap_line_xdyd#0] -- register_copy @@ -32174,9 +32239,7 @@ bitmap_line: { //SEG1373 [671] (byte) bitmap_line_ydxi::y1#1 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_ydxi.y1 //SEG1374 [672] (byte) bitmap_line_ydxi::yd#1 ← (byte) bitmap_line::yd#10 - // (byte) bitmap_line_ydxi::yd#1 = (byte) bitmap_line::yd#10 // register copy zp ZP_BYTE:7 //SEG1375 [673] (byte) bitmap_line_ydxi::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_ydxi::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1376 [674] call bitmap_line_ydxi //SEG1377 [703] phi from bitmap_line::@27 to bitmap_line_ydxi [phi:bitmap_line::@27->bitmap_line_ydxi] //SEG1378 [703] phi (byte) bitmap_line_ydxi::y1#6 = (byte) bitmap_line_ydxi::y1#1 [phi:bitmap_line::@27->bitmap_line_ydxi#0] -- register_copy @@ -32192,14 +32255,11 @@ bitmap_line: { lda x0 sta bitmap_line_xdyi.x //SEG1385 [676] (byte) bitmap_line_xdyi::y#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_xdyi::y#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:15 //SEG1386 [677] (byte) bitmap_line_xdyi::x1#1 ← (byte) bitmap_line::x1#0 -- vbuz1=vbuz2 lda x1 sta bitmap_line_xdyi.x1 //SEG1387 [678] (byte) bitmap_line_xdyi::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_xdyi::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1388 [679] (byte) bitmap_line_xdyi::yd#1 ← (byte) bitmap_line::yd#10 - // (byte) bitmap_line_xdyi::yd#1 = (byte) bitmap_line::yd#10 // register copy zp ZP_BYTE:7 //SEG1389 [680] call bitmap_line_xdyi //SEG1390 [681] phi from bitmap_line::@13 to bitmap_line_xdyi [phi:bitmap_line::@13->bitmap_line_xdyi] //SEG1391 [681] phi (byte) bitmap_line_xdyi::x1#6 = (byte) bitmap_line_xdyi::x1#1 [phi:bitmap_line::@13->bitmap_line_xdyi#0] -- register_copy @@ -32323,7 +32383,6 @@ bitmap_line_ydxi: { //SEG1438 bitmap_line_ydxi::@1 b1: //SEG1439 [706] (byte) bitmap_plot::x#2 ← (byte) bitmap_line_ydxi::x#3 - // (byte) bitmap_plot::x#2 = (byte) bitmap_line_ydxi::x#3 // register copy reg byte x //SEG1440 [707] (byte) bitmap_plot::y#2 ← (byte) bitmap_line_ydxi::y#3 -- vbuyy=vbuz1 ldy y //SEG1441 [708] call bitmap_plot @@ -32447,7 +32506,6 @@ bitmap_line_ydxd: { //SEG1494 bitmap_line_ydxd::@1 b1: //SEG1495 [736] (byte) bitmap_plot::x#3 ← (byte) bitmap_line_ydxd::x#3 - // (byte) bitmap_plot::x#3 = (byte) bitmap_line_ydxd::x#3 // register copy reg byte x //SEG1496 [737] (byte) bitmap_plot::y#3 ← (byte) bitmap_line_ydxd::y#2 -- vbuyy=vbuz1 ldy y //SEG1497 [738] call bitmap_plot @@ -32492,6 +32550,7 @@ bitmap_line_ydxd: { rts } //SEG1516 bitmap_clear +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = 3 .label y = 2 @@ -32502,7 +32561,6 @@ bitmap_clear: { lda bitmap_plot_xhi sta _3+1 //SEG1518 [749] (byte*~) bitmap_clear::bitmap#5 ← (byte*)(word~) bitmap_clear::$3 - // (byte*~) bitmap_clear::bitmap#5 = (byte*)(word~) bitmap_clear::$3 // register copy zp ZP_WORD:3 //SEG1519 [750] phi from bitmap_clear to bitmap_clear::@1 [phi:bitmap_clear->bitmap_clear::@1] //SEG1520 [750] phi (byte) bitmap_clear::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:bitmap_clear->bitmap_clear::@1#0] -- vbuz1=vbuc1 lda #0 @@ -32548,6 +32606,7 @@ bitmap_clear: { rts } //SEG1542 bitmap_init +// Initialize the bitmap plotter tables for a specific bitmap bitmap_init: { .label _6 = 2 .label yoffs = 3 @@ -32721,6 +32780,7 @@ gfx_init_charset: { rts } //SEG1621 gfx_init_screen4 +// Initialize VIC screen 4 - all chars are 00 gfx_init_screen4: { .label ch = 3 .label cy = 2 @@ -32773,6 +32833,7 @@ gfx_init_screen4: { rts } //SEG1645 gfx_init_screen3 +// Initialize VIC screen 3 ( value is %00xx00yy where xx is xpos and yy is ypos gfx_init_screen3: { .label _1 = 7 .label ch = 3 @@ -32839,6 +32900,7 @@ gfx_init_screen3: { rts } //SEG1673 gfx_init_screen2 +// Initialize VIC screen 2 ( value is %ccccrrrr where cccc is (x+y mod $f) and rrrr is %1111-%cccc) gfx_init_screen2: { .label col2 = 7 .label ch = 3 @@ -32912,6 +32974,7 @@ gfx_init_screen2: { rts } //SEG1702 gfx_init_screen1 +// Initialize VIC screen 1 ( value is %0000cccc where cccc is (x+y mod $f)) gfx_init_screen1: { .label ch = 3 .label cy = 2 @@ -32969,6 +33032,7 @@ gfx_init_screen1: { rts } //SEG1728 gfx_init_screen0 +// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos) gfx_init_screen0: { .label _1 = 7 .label ch = 3 @@ -33035,6 +33099,7 @@ gfx_init_screen0: { rts } //SEG1756 keyboard_init +// Initialize keyboard reading by setting CIA#$ Data Direction Registers keyboard_init: { //SEG1757 [862] *((const byte*) CIA1_PORT_A_DDR#0) ← (byte/word/signed word/dword/signed dword) 255 -- _deref_pbuc1=vbuc2 lda #$ff diff --git a/src/test/ref/c64dtv-gfxmodes.asm b/src/test/ref/c64dtv-gfxmodes.asm index 50e284627..ec3b5ad46 100644 --- a/src/test/ref/c64dtv-gfxmodes.asm +++ b/src/test/ref/c64dtv-gfxmodes.asm @@ -230,6 +230,12 @@ menu: { jsr mode_8bppchunkybmm jmp breturn } +// Chunky 8bpp Bitmap Mode (BMM = 0, ECM/MCM/HICOL/LINEAR/CHUNK/COLDIS = 1) +// Resolution: 320x200 +// Linear Adressing +// CharData/PlaneB Pixel Shifter (8): +// - 8bpp color PlaneB[7:0] +// To set up a linear video frame buffer the step size must be set to 8. mode_8bppchunkybmm: { .const PLANEB = $20000 .label _23 = $d @@ -324,6 +330,7 @@ mode_8bppchunkybmm: { jsr mode_ctrl rts } +// Allow the user to control the DTV graphics using different keys mode_ctrl: { b4: lda RASTER @@ -397,6 +404,10 @@ mode_ctrl: { stx BORDERCOL jmp b4 } +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { .label colidx = 7 tya @@ -412,6 +423,11 @@ keyboard_key_pressed: { and keyboard_matrix_col_bitmask,y rts } +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { lda keyboard_matrix_row_bitmask,y sta CIA1_PORT_A @@ -419,6 +435,9 @@ keyboard_matrix_read: { eor #$ff rts } +// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) +// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff +// The actual memory addressed will be $4000*cpuSegmentIdx dtvSetCpuBankSegment1: { .label cpuBank = $ff sta cpuBank @@ -427,6 +446,15 @@ dtvSetCpuBankSegment1: { .byte $32, $00 rts } +// 8bpp Pixel Cell Mode (BMM/COLDIS = 0, ECM/MCM/HICOL/LINEAR/CHUNK = 1) +// Pixel Cell Adressing +// CharData[8]: (PlaneA[21:0]) +// GfxData[8]: (PlaneB[21:14] & CharData[7:0] & RowCounter[3:0] & PixelCounter[7:0] ) +// GfxData Pixel Shifter (8): +// - 8bpp color GfxData[7:0] +// Pixel cell mode can be thought of as a text mode that uses a 8x8 pixel 8bpp font (64 bytes/char). +// The characters come from counter A and the font (or "cells") from counter B. +// Counter B step and modulo should be set to 0, counter A modulo to 0 and counter A step to 1 for normal operation. mode_8bpppixelcell: { .label PLANEA = $3c00 .label PLANEB = $4000 @@ -566,6 +594,12 @@ mode_8bpppixelcell: { jsr mode_ctrl rts } +// Sixs Fred Mode - 8bpp Packed Bitmap - Generated from the two DTV linear graphics plane counters +// Two Plane MultiColor Bitmap - 8bpp Packed Bitmap (CHUNK/COLDIS = 0, ECM/BMM/MCM/HICOL/LINEAR = 1) +// Resolution: 160x200 +// Linear Adressing +// GfxData/PlaneA Pixel Shifter (2), CharData/PlaneB Pixel Shifter (2): +// - 8bpp color (ColorData[3:0],CharData/PlaneB[1:0], GfxData/PlaneA[1:0]) mode_sixsfred: { .label PLANEA = $4000 .label PLANEB = $6000 @@ -699,6 +733,15 @@ mode_sixsfred: { rts row_bitmask: .byte 0, $55, $aa, $ff } +// Two Plane Bitmap - generated from the two DTV linear graphics plane counters +// Two Plane Bitmap Mode (CHUNK/COLDIS/MCM = 0, ECM/BMM/HICOL/LINEAR = 1) +// Resolution: 320x200 +// Linear Adressing +// GfxData/PlaneA Pixel Shifter (1), CharData/PlaneB Pixel Shifter (1): +// - Plane A = 0 Plane B = 0: 8bpp BgColor0[7:0] +// - Plane A = 0 Plane B = 1: 8bpp "0000" & ColorData[7:4] +// - Plane A = 1 Plane B = 0: 8bpp "0000" & ColorData[3:0] +// - Plane A = 1 Plane B = 1: 8bpp BgColor1[7:0] mode_twoplanebitmap: { .label PLANEA = $4000 .label PLANEB = $6000 @@ -852,6 +895,12 @@ mode_twoplanebitmap: { !: jmp b7 } +// Sixs Fred Mode 2 - 8bpp Packed Bitmap - Generated from the two DTV linear graphics plane counters +// Two Plane MultiColor Bitmap - 8bpp Packed Bitmap (CHUNK/COLDIS/HICOL = 0, ECM/BMM/MCM/LINEAR = 1) +// Resolution: 160x200 +// Linear Adressing +// PlaneA Pixel Shifter (2), PlaneB Pixel Shifter (2): +// - 8bpp color (PlaneB[1:0],ColorData[5:4],PlaneA[1:0],ColorData[1:0]) mode_sixsfred2: { .label PLANEA = $4000 .label PLANEB = $6000 @@ -992,6 +1041,18 @@ mode_sixsfred2: { rts row_bitmask: .byte 0, $55, $aa, $ff } +// High Color Multicolor Character Mode (LINEAR/CHUNK/COLDIS/BMM/ECM = 0, MCM/HICOL = 1) +// Resolution: 160x200 (320x200) +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & CharData[7:0] & RowCounter[2:0] ) +// GfxData Pixel Shifter (1) if ColorData[3:3] = 0: +// - 0: 8bpp BgColor0[7:0] +// - 1: 8bpp ColorData[7:4] "0" & Color[2:0] +// GfxData Pixel Shifter (2) if ColorData[3:3] = 1: +// - 00: 8bpp BgColor0[7:0] +// - 01: 8bpp BgColor1[7:0] +// - 10: 8bpp BgColor2[7:0] +// - 11: 8bpp ColorData[7:4] "0" & Color[2:0] mode_hicolmcchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -1080,6 +1141,17 @@ mode_hicolmcchar: { jsr mode_ctrl rts } +// High Color Extended Background Color Character Mode (LINEAR/CHUNK/COLDIS/MCM/BMM = 0, ECM/HICOL = 1) +// Resolution: 320x200 +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & "00" & CharData[5:0] & RowCounter[2:0] ) +// GfxData Pixel Shifter (1) +// - 0: 8bpp Background Color +// - CharData[7:6] 00: 8bpp BgColor0[7:0] +// - CharData[7:6] 01: 8bpp BgColor1[7:0] +// - CharData[7:6] 10: 8bpp BgColor2[7:0] +// - CharData[7:6] 11: 8bpp BgColor3[7:0] +// - 1: 8bpp ColorData[7:0] mode_hicolecmchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -1170,6 +1242,13 @@ mode_hicolecmchar: { jsr mode_ctrl rts } +// High Color Standard Character Mode (LINEAR/CHUNK/COLDIS/ECM/MCM/BMM = 0, HICOL = 1) +// Resolution: 320x200 +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & CharData[7:0] & RowCounter[2:0] ) +// Pixel Shifter (1) +// - 0: 8bpp BgColor0[7:0] +// - 1: 8bpp ColorData[7:0] mode_hicolstdchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -1253,6 +1332,13 @@ mode_hicolstdchar: { jsr mode_ctrl rts } +// Standard Bitmap Mode (LINEAR/HICOL/CHUNK/COLDIS/MCM/ECM = 0, BMM = 1) +// Resolution: 320x200 +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:2] & Matrix[9:0] & RowCounter[2:0] ) +// Pixel Shifter (1) +// - 0: 4bpp CharData[3:0] +// - 1: 4bpp CharData[7:4] mode_stdbitmap: { .label SCREEN = $4000 .label BITMAP = $6000 @@ -1349,6 +1435,7 @@ mode_stdbitmap: { lines_x: .byte 0, $ff, $ff, 0, 0, $80, $ff, $80, 0, $80 lines_y: .byte 0, 0, $c7, $c7, 0, 0, $64, $c7, $64, 0 } +// Draw a line on the bitmap bitmap_line: { .label xd = 8 .label yd = 7 @@ -1611,6 +1698,7 @@ bitmap_line_ydxd: { bne b1 rts } +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = 2 .label y = 4 @@ -1640,6 +1728,7 @@ bitmap_clear: { bne b1 rts } +// Initialize the bitmap plotter tables for a specific bitmap bitmap_init: { .label _6 = 4 .label yoffs = 2 @@ -1693,6 +1782,18 @@ bitmap_init: { bne b3 rts } +// Multicolor Character Mode (LINEAR/HICOL/CHUNK/COLDIS/BMM/ECM = 0, MCM = 1) +// Resolution: 160x200 (320x200) +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & CharData[7:0] & RowCounter[2:0] ) +// GfxData Pixel Shifter (1) if ColorData[3:3] = 0: +// - 0: 4bpp BgColor0[3:0] +// - 1: 4bpp ColorData[2:0] +// GfxData Pixel Shifter (2) if ColorData[3:3] = 1: +// - 00: 4bpp BgColor0[3:0] +// - 01: 4bpp BgColor1[3:0] +// - 10: 4bpp BgColor2[3:0] +// - 11: 4bpp ColorData[2:0]// Standard Character Mode (LINEAR/HICOL/CHUNK/COLDIS/ECM/MCM/BMM = 0) mode_mcchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -1784,6 +1885,17 @@ mode_mcchar: { jsr mode_ctrl rts } +// Extended Background Color Character Mode (LINEAR/HICOL/CHUNK/COLDIS/MCM/BMM = 0, ECM = 1) +// Resolution: 320x200 +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & "00" & CharData[5:0] & RowCounter[2:0] ) +// GfxData Pixel Shifter (1) +// - 0: 4bpp Background Color +// - CharData[7:6] 00: 4bpp BgColor0[3:0] +// - CharData[7:6] 01: 4bpp BgColor1[3:0] +// - CharData[7:6] 10: 4bpp BgColor2[3:0] +// - CharData[7:6] 11: 4bpp BgColor3[3:0] +// - 1: 4bpp ColorData[3:0] mode_ecmchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -1876,6 +1988,13 @@ mode_ecmchar: { jsr mode_ctrl rts } +// Standard Character Mode (LINEAR/HICOL/CHUNK/COLDIS/ECM/MCM/BMM = 0) +// Resolution: 320x200 +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & CharData[7:0] & RowCounter[2:0] ) +// Pixel Shifter (1) +// - 0: 4bpp BgColor0[3:0] +// - 1: 4bpp ColorData[3:0] mode_stdchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -1962,6 +2081,8 @@ mode_stdchar: { jsr mode_ctrl rts } +// Print a number of zero-terminated strings, each followed by a newline. +// The sequence of lines is terminated by another zero. print_str_lines: { .label str = 2 lda #print_ln::@1] b1_from_print_ln: @@ -17565,6 +17687,7 @@ print_ln: { rts } //SEG1646 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = $9f //SEG1647 [886] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -17604,6 +17727,7 @@ print_cls: { rts } //SEG1657 print_set_screen +// Set the screen to print on. Also resets current line/char cursor. print_set_screen: { jmp breturn //SEG1658 print_set_screen::@return @@ -19468,12 +19592,10 @@ menu: { ldy #KEY_1 jsr keyboard_key_pressed //SEG60 [36] (byte) keyboard_key_pressed::return#2 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#2 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b50 //SEG61 menu::@50 b50: //SEG62 [37] (byte~) menu::$29 ← (byte) keyboard_key_pressed::return#2 - // (byte~) menu::$29 = (byte) keyboard_key_pressed::return#2 // register copy reg byte a //SEG63 [38] if((byte~) menu::$29==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@6 -- vbuaa_eq_0_then_la1 cmp #0 beq b6_from_b50 @@ -19501,12 +19623,10 @@ menu: { ldy #KEY_2 jsr keyboard_key_pressed //SEG74 [44] (byte) keyboard_key_pressed::return#24 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#24 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b51 //SEG75 menu::@51 b51: //SEG76 [45] (byte~) menu::$33 ← (byte) keyboard_key_pressed::return#24 - // (byte~) menu::$33 = (byte) keyboard_key_pressed::return#24 // register copy reg byte a //SEG77 [46] if((byte~) menu::$33==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@7 -- vbuaa_eq_0_then_la1 cmp #0 beq b7_from_b51 @@ -19530,12 +19650,10 @@ menu: { ldy #KEY_3 jsr keyboard_key_pressed //SEG86 [51] (byte) keyboard_key_pressed::return#25 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#25 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b53 //SEG87 menu::@53 b53: //SEG88 [52] (byte~) menu::$37 ← (byte) keyboard_key_pressed::return#25 - // (byte~) menu::$37 = (byte) keyboard_key_pressed::return#25 // register copy reg byte a //SEG89 [53] if((byte~) menu::$37==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@8 -- vbuaa_eq_0_then_la1 cmp #0 beq b8_from_b53 @@ -19559,12 +19677,10 @@ menu: { ldy #KEY_4 jsr keyboard_key_pressed //SEG98 [58] (byte) keyboard_key_pressed::return#26 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#26 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b55 //SEG99 menu::@55 b55: //SEG100 [59] (byte~) menu::$41 ← (byte) keyboard_key_pressed::return#26 - // (byte~) menu::$41 = (byte) keyboard_key_pressed::return#26 // register copy reg byte a //SEG101 [60] if((byte~) menu::$41==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@9 -- vbuaa_eq_0_then_la1 cmp #0 beq b9_from_b55 @@ -19588,12 +19704,10 @@ menu: { ldy #KEY_6 jsr keyboard_key_pressed //SEG110 [65] (byte) keyboard_key_pressed::return#27 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#27 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b57 //SEG111 menu::@57 b57: //SEG112 [66] (byte~) menu::$45 ← (byte) keyboard_key_pressed::return#27 - // (byte~) menu::$45 = (byte) keyboard_key_pressed::return#27 // register copy reg byte a //SEG113 [67] if((byte~) menu::$45==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@10 -- vbuaa_eq_0_then_la1 cmp #0 beq b10_from_b57 @@ -19617,12 +19731,10 @@ menu: { ldy #KEY_7 jsr keyboard_key_pressed //SEG122 [72] (byte) keyboard_key_pressed::return#28 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#28 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b59 //SEG123 menu::@59 b59: //SEG124 [73] (byte~) menu::$49 ← (byte) keyboard_key_pressed::return#28 - // (byte~) menu::$49 = (byte) keyboard_key_pressed::return#28 // register copy reg byte a //SEG125 [74] if((byte~) menu::$49==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@11 -- vbuaa_eq_0_then_la1 cmp #0 beq b11_from_b59 @@ -19646,12 +19758,10 @@ menu: { ldy #KEY_8 jsr keyboard_key_pressed //SEG134 [79] (byte) keyboard_key_pressed::return#29 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#29 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b61 //SEG135 menu::@61 b61: //SEG136 [80] (byte~) menu::$53 ← (byte) keyboard_key_pressed::return#29 - // (byte~) menu::$53 = (byte) keyboard_key_pressed::return#29 // register copy reg byte a //SEG137 [81] if((byte~) menu::$53==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@12 -- vbuaa_eq_0_then_la1 cmp #0 beq b12_from_b61 @@ -19675,12 +19785,10 @@ menu: { ldy #KEY_A jsr keyboard_key_pressed //SEG146 [86] (byte) keyboard_key_pressed::return#30 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#30 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b63 //SEG147 menu::@63 b63: //SEG148 [87] (byte~) menu::$57 ← (byte) keyboard_key_pressed::return#30 - // (byte~) menu::$57 = (byte) keyboard_key_pressed::return#30 // register copy reg byte a //SEG149 [88] if((byte~) menu::$57==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@13 -- vbuaa_eq_0_then_la1 cmp #0 beq b13_from_b63 @@ -19704,12 +19812,10 @@ menu: { ldy #KEY_B jsr keyboard_key_pressed //SEG158 [93] (byte) keyboard_key_pressed::return#10 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#10 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b65 //SEG159 menu::@65 b65: //SEG160 [94] (byte~) menu::$61 ← (byte) keyboard_key_pressed::return#10 - // (byte~) menu::$61 = (byte) keyboard_key_pressed::return#10 // register copy reg byte a //SEG161 [95] if((byte~) menu::$61==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@14 -- vbuaa_eq_0_then_la1 cmp #0 beq b14_from_b65 @@ -19733,12 +19839,10 @@ menu: { ldy #KEY_C jsr keyboard_key_pressed //SEG170 [100] (byte) keyboard_key_pressed::return#11 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#11 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b67 //SEG171 menu::@67 b67: //SEG172 [101] (byte~) menu::$65 ← (byte) keyboard_key_pressed::return#11 - // (byte~) menu::$65 = (byte) keyboard_key_pressed::return#11 // register copy reg byte a //SEG173 [102] if((byte~) menu::$65==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@15 -- vbuaa_eq_0_then_la1 cmp #0 beq b15_from_b67 @@ -19762,12 +19866,10 @@ menu: { ldy #KEY_D jsr keyboard_key_pressed //SEG182 [107] (byte) keyboard_key_pressed::return#12 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#12 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b69 //SEG183 menu::@69 b69: //SEG184 [108] (byte~) menu::$69 ← (byte) keyboard_key_pressed::return#12 - // (byte~) menu::$69 = (byte) keyboard_key_pressed::return#12 // register copy reg byte a //SEG185 [109] if((byte~) menu::$69==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@16 -- vbuaa_eq_0_then_la1 cmp #0 beq b16_from_b69 @@ -19791,12 +19893,10 @@ menu: { ldy #KEY_E jsr keyboard_key_pressed //SEG194 [114] (byte) keyboard_key_pressed::return#13 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#13 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b71 //SEG195 menu::@71 b71: //SEG196 [115] (byte~) menu::$73 ← (byte) keyboard_key_pressed::return#13 - // (byte~) menu::$73 = (byte) keyboard_key_pressed::return#13 // register copy reg byte a //SEG197 [116] if((byte~) menu::$73==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@4 -- vbuaa_eq_0_then_la1 cmp #0 beq b4_from_b71 @@ -19810,6 +19910,12 @@ menu: { jmp breturn } //SEG201 mode_8bppchunkybmm +// Chunky 8bpp Bitmap Mode (BMM = 0, ECM/MCM/HICOL/LINEAR/CHUNK/COLDIS = 1) +// Resolution: 320x200 +// Linear Adressing +// CharData/PlaneB Pixel Shifter (8): +// - 8bpp color PlaneB[7:0] +// To set up a linear video frame buffer the step size must be set to 8. mode_8bppchunkybmm: { .const PLANEB = $20000 .label _23 = $d @@ -20022,6 +20128,7 @@ mode_8bppchunkybmm: { rts } //SEG279 mode_ctrl +// Allow the user to control the DTV graphics using different keys mode_ctrl: { //SEG280 [156] phi from mode_ctrl mode_ctrl::@30 to mode_ctrl::@1 [phi:mode_ctrl/mode_ctrl::@30->mode_ctrl::@1] b1_from_mode_ctrl: @@ -20052,12 +20159,10 @@ mode_ctrl: { ldy #KEY_SPACE jsr keyboard_key_pressed //SEG291 [160] (byte) keyboard_key_pressed::return#14 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#14 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b32 //SEG292 mode_ctrl::@32 b32: //SEG293 [161] (byte~) mode_ctrl::$1 ← (byte) keyboard_key_pressed::return#14 - // (byte~) mode_ctrl::$1 = (byte) keyboard_key_pressed::return#14 // register copy reg byte a //SEG294 [162] if((byte~) mode_ctrl::$1==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@7 -- vbuaa_eq_0_then_la1 cmp #0 beq b7 @@ -20077,12 +20182,10 @@ mode_ctrl: { ldy #KEY_L jsr keyboard_key_pressed //SEG302 [166] (byte) keyboard_key_pressed::return#15 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#15 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b33 //SEG303 mode_ctrl::@33 b33: //SEG304 [167] (byte~) mode_ctrl::$4 ← (byte) keyboard_key_pressed::return#15 - // (byte~) mode_ctrl::$4 = (byte) keyboard_key_pressed::return#15 // register copy reg byte a //SEG305 [168] if((byte~) mode_ctrl::$4==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@8 -- vbuaa_eq_0_then_la1 cmp #0 beq b8_from_b33 @@ -20107,12 +20210,10 @@ mode_ctrl: { ldy #KEY_H jsr keyboard_key_pressed //SEG314 [172] (byte) keyboard_key_pressed::return#16 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#16 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b34 //SEG315 mode_ctrl::@34 b34: //SEG316 [173] (byte~) mode_ctrl::$8 ← (byte) keyboard_key_pressed::return#16 - // (byte~) mode_ctrl::$8 = (byte) keyboard_key_pressed::return#16 // register copy reg byte a //SEG317 [174] if((byte~) mode_ctrl::$8==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@9 -- vbuaa_eq_0_then_la1 cmp #0 beq b9_from_b34 @@ -20137,12 +20238,10 @@ mode_ctrl: { ldy #KEY_O jsr keyboard_key_pressed //SEG326 [178] (byte) keyboard_key_pressed::return#17 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#17 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b35 //SEG327 mode_ctrl::@35 b35: //SEG328 [179] (byte~) mode_ctrl::$12 ← (byte) keyboard_key_pressed::return#17 - // (byte~) mode_ctrl::$12 = (byte) keyboard_key_pressed::return#17 // register copy reg byte a //SEG329 [180] if((byte~) mode_ctrl::$12==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@10 -- vbuaa_eq_0_then_la1 cmp #0 beq b10_from_b35 @@ -20167,12 +20266,10 @@ mode_ctrl: { ldy #KEY_B jsr keyboard_key_pressed //SEG338 [184] (byte) keyboard_key_pressed::return#18 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#18 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b36 //SEG339 mode_ctrl::@36 b36: //SEG340 [185] (byte~) mode_ctrl::$16 ← (byte) keyboard_key_pressed::return#18 - // (byte~) mode_ctrl::$16 = (byte) keyboard_key_pressed::return#18 // register copy reg byte a //SEG341 [186] if((byte~) mode_ctrl::$16==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@11 -- vbuaa_eq_0_then_la1 cmp #0 beq b11_from_b36 @@ -20197,12 +20294,10 @@ mode_ctrl: { ldy #KEY_U jsr keyboard_key_pressed //SEG350 [190] (byte) keyboard_key_pressed::return#19 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#19 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b37 //SEG351 mode_ctrl::@37 b37: //SEG352 [191] (byte~) mode_ctrl::$20 ← (byte) keyboard_key_pressed::return#19 - // (byte~) mode_ctrl::$20 = (byte) keyboard_key_pressed::return#19 // register copy reg byte a //SEG353 [192] if((byte~) mode_ctrl::$20==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@12 -- vbuaa_eq_0_then_la1 cmp #0 beq b12_from_b37 @@ -20227,12 +20322,10 @@ mode_ctrl: { ldy #KEY_C jsr keyboard_key_pressed //SEG362 [196] (byte) keyboard_key_pressed::return#20 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#20 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b38 //SEG363 mode_ctrl::@38 b38: //SEG364 [197] (byte~) mode_ctrl::$24 ← (byte) keyboard_key_pressed::return#20 - // (byte~) mode_ctrl::$24 = (byte) keyboard_key_pressed::return#20 // register copy reg byte a //SEG365 [198] if((byte~) mode_ctrl::$24==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@13 -- vbuaa_eq_0_then_la1 cmp #0 beq b13_from_b38 @@ -20257,12 +20350,10 @@ mode_ctrl: { ldy #KEY_0 jsr keyboard_key_pressed //SEG374 [202] (byte) keyboard_key_pressed::return#21 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#21 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b39 //SEG375 mode_ctrl::@39 b39: //SEG376 [203] (byte~) mode_ctrl::$28 ← (byte) keyboard_key_pressed::return#21 - // (byte~) mode_ctrl::$28 = (byte) keyboard_key_pressed::return#21 // register copy reg byte a //SEG377 [204] if((byte~) mode_ctrl::$28==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@46 -- vbuaa_eq_0_then_la1 cmp #0 beq b46_from_b39 @@ -20297,6 +20388,10 @@ mode_ctrl: { jmp b14 } //SEG390 keyboard_key_pressed +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { .label colidx = 7 //SEG391 [212] (byte) keyboard_key_pressed::colidx#0 ← (byte) keyboard_key_pressed::key#20 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuz1=vbuyy_band_vbuc1 @@ -20313,12 +20408,10 @@ keyboard_key_pressed: { //SEG394 [215] call keyboard_matrix_read jsr keyboard_matrix_read //SEG395 [216] (byte) keyboard_matrix_read::return#2 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#2 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a jmp b2 //SEG396 keyboard_key_pressed::@2 b2: //SEG397 [217] (byte~) keyboard_key_pressed::$2 ← (byte) keyboard_matrix_read::return#2 - // (byte~) keyboard_key_pressed::$2 = (byte) keyboard_matrix_read::return#2 // register copy reg byte a //SEG398 [218] (byte) keyboard_key_pressed::return#0 ← (byte~) keyboard_key_pressed::$2 & *((const byte[8]) keyboard_matrix_col_bitmask#0 + (byte) keyboard_key_pressed::colidx#0) -- vbuaa=vbuaa_band_pbuc1_derefidx_vbuz1 ldy colidx and keyboard_matrix_col_bitmask,y @@ -20329,6 +20422,11 @@ keyboard_key_pressed: { rts } //SEG401 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { //SEG402 [220] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0 + (byte) keyboard_matrix_read::rowid#0) -- _deref_pbuc1=pbuc2_derefidx_vbuyy lda keyboard_matrix_row_bitmask,y @@ -20343,6 +20441,9 @@ keyboard_matrix_read: { rts } //SEG406 dtvSetCpuBankSegment1 +// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) +// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff +// The actual memory addressed will be $4000*cpuSegmentIdx dtvSetCpuBankSegment1: { .label cpuBank = $ff //SEG407 [224] *((const byte*) dtvSetCpuBankSegment1::cpuBank#0) ← (byte) dtvSetCpuBankSegment1::cpuBankIdx#3 -- _deref_pbuc1=vbuaa @@ -20358,6 +20459,15 @@ dtvSetCpuBankSegment1: { rts } //SEG411 mode_8bpppixelcell +// 8bpp Pixel Cell Mode (BMM/COLDIS = 0, ECM/MCM/HICOL/LINEAR/CHUNK = 1) +// Pixel Cell Adressing +// CharData[8]: (PlaneA[21:0]) +// GfxData[8]: (PlaneB[21:14] & CharData[7:0] & RowCounter[3:0] & PixelCounter[7:0] ) +// GfxData Pixel Shifter (8): +// - 8bpp color GfxData[7:0] +// Pixel cell mode can be thought of as a text mode that uses a 8x8 pixel 8bpp font (64 bytes/char). +// The characters come from counter A and the font (or "cells") from counter B. +// Counter B step and modulo should be set to 0, counter A modulo to 0 and counter A step to 1 for normal operation. mode_8bpppixelcell: { .label PLANEA = $3c00 .label PLANEB = $4000 @@ -20659,6 +20769,12 @@ mode_8bpppixelcell: { rts } //SEG526 mode_sixsfred +// Sixs Fred Mode - 8bpp Packed Bitmap - Generated from the two DTV linear graphics plane counters +// Two Plane MultiColor Bitmap - 8bpp Packed Bitmap (CHUNK/COLDIS = 0, ECM/BMM/MCM/HICOL/LINEAR = 1) +// Resolution: 160x200 +// Linear Adressing +// GfxData/PlaneA Pixel Shifter (2), CharData/PlaneB Pixel Shifter (2): +// - 8bpp color (ColorData[3:0],CharData/PlaneB[1:0], GfxData/PlaneA[1:0]) mode_sixsfred: { .label PLANEA = $4000 .label PLANEB = $6000 @@ -20938,6 +21054,15 @@ mode_sixsfred: { row_bitmask: .byte 0, $55, $aa, $ff } //SEG628 mode_twoplanebitmap +// Two Plane Bitmap - generated from the two DTV linear graphics plane counters +// Two Plane Bitmap Mode (CHUNK/COLDIS/MCM = 0, ECM/BMM/HICOL/LINEAR = 1) +// Resolution: 320x200 +// Linear Adressing +// GfxData/PlaneA Pixel Shifter (1), CharData/PlaneB Pixel Shifter (1): +// - Plane A = 0 Plane B = 0: 8bpp BgColor0[7:0] +// - Plane A = 0 Plane B = 1: 8bpp "0000" & ColorData[7:4] +// - Plane A = 1 Plane B = 0: 8bpp "0000" & ColorData[3:0] +// - Plane A = 1 Plane B = 1: 8bpp BgColor1[7:0] mode_twoplanebitmap: { .label PLANEA = $4000 .label PLANEB = $6000 @@ -21253,6 +21378,12 @@ mode_twoplanebitmap: { jmp b7_from_b6 } //SEG741 mode_sixsfred2 +// Sixs Fred Mode 2 - 8bpp Packed Bitmap - Generated from the two DTV linear graphics plane counters +// Two Plane MultiColor Bitmap - 8bpp Packed Bitmap (CHUNK/COLDIS/HICOL = 0, ECM/BMM/MCM/LINEAR = 1) +// Resolution: 160x200 +// Linear Adressing +// PlaneA Pixel Shifter (2), PlaneB Pixel Shifter (2): +// - 8bpp color (PlaneB[1:0],ColorData[5:4],PlaneA[1:0],ColorData[1:0]) mode_sixsfred2: { .label PLANEA = $4000 .label PLANEB = $6000 @@ -21541,6 +21672,18 @@ mode_sixsfred2: { row_bitmask: .byte 0, $55, $aa, $ff } //SEG845 mode_hicolmcchar +// High Color Multicolor Character Mode (LINEAR/CHUNK/COLDIS/BMM/ECM = 0, MCM/HICOL = 1) +// Resolution: 160x200 (320x200) +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & CharData[7:0] & RowCounter[2:0] ) +// GfxData Pixel Shifter (1) if ColorData[3:3] = 0: +// - 0: 8bpp BgColor0[7:0] +// - 1: 8bpp ColorData[7:4] "0" & Color[2:0] +// GfxData Pixel Shifter (2) if ColorData[3:3] = 1: +// - 00: 8bpp BgColor0[7:0] +// - 01: 8bpp BgColor1[7:0] +// - 10: 8bpp BgColor2[7:0] +// - 11: 8bpp ColorData[7:4] "0" & Color[2:0] mode_hicolmcchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -21712,6 +21855,17 @@ mode_hicolmcchar: { rts } //SEG906 mode_hicolecmchar +// High Color Extended Background Color Character Mode (LINEAR/CHUNK/COLDIS/MCM/BMM = 0, ECM/HICOL = 1) +// Resolution: 320x200 +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & "00" & CharData[5:0] & RowCounter[2:0] ) +// GfxData Pixel Shifter (1) +// - 0: 8bpp Background Color +// - CharData[7:6] 00: 8bpp BgColor0[7:0] +// - CharData[7:6] 01: 8bpp BgColor1[7:0] +// - CharData[7:6] 10: 8bpp BgColor2[7:0] +// - CharData[7:6] 11: 8bpp BgColor3[7:0] +// - 1: 8bpp ColorData[7:0] mode_hicolecmchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -21886,6 +22040,13 @@ mode_hicolecmchar: { rts } //SEG968 mode_hicolstdchar +// High Color Standard Character Mode (LINEAR/CHUNK/COLDIS/ECM/MCM/BMM = 0, HICOL = 1) +// Resolution: 320x200 +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & CharData[7:0] & RowCounter[2:0] ) +// Pixel Shifter (1) +// - 0: 8bpp BgColor0[7:0] +// - 1: 8bpp ColorData[7:0] mode_hicolstdchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -22051,6 +22212,13 @@ mode_hicolstdchar: { rts } //SEG1027 mode_stdbitmap +// Standard Bitmap Mode (LINEAR/HICOL/CHUNK/COLDIS/MCM/ECM = 0, BMM = 1) +// Resolution: 320x200 +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:2] & Matrix[9:0] & RowCounter[2:0] ) +// Pixel Shifter (1) +// - 0: 4bpp CharData[3:0] +// - 1: 4bpp CharData[7:4] mode_stdbitmap: { .label SCREEN = $4000 .label BITMAP = $6000 @@ -22257,6 +22425,7 @@ mode_stdbitmap: { lines_y: .byte 0, 0, $c7, $c7, 0, 0, $64, $c7, $64, 0 } //SEG1099 bitmap_line +// Draw a line on the bitmap bitmap_line: { .label xd = 8 .label yd = 7 @@ -22302,11 +22471,8 @@ bitmap_line: { //SEG1109 [598] (byte) bitmap_line_ydxi::x#0 ← (byte) bitmap_line::x1#0 -- vbuxx=vbuz1 ldx x1 //SEG1110 [599] (byte) bitmap_line_ydxi::y1#0 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_ydxi::y1#0 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:11 //SEG1111 [600] (byte) bitmap_line_ydxi::yd#0 ← (byte) bitmap_line::yd#1 - // (byte) bitmap_line_ydxi::yd#0 = (byte) bitmap_line::yd#1 // register copy zp ZP_BYTE:7 //SEG1112 [601] (byte) bitmap_line_ydxi::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_ydxi::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1113 [602] call bitmap_line_ydxi //SEG1114 [676] phi from bitmap_line::@17 to bitmap_line_ydxi [phi:bitmap_line::@17->bitmap_line_ydxi] bitmap_line_ydxi_from_b17: @@ -22329,11 +22495,8 @@ bitmap_line: { //SEG1124 [605] (byte) bitmap_line_xdyi::y#0 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_xdyi.y //SEG1125 [606] (byte) bitmap_line_xdyi::x1#0 ← (byte) bitmap_line::x0#0 - // (byte) bitmap_line_xdyi::x1#0 = (byte) bitmap_line::x0#0 // register copy zp ZP_BYTE:9 //SEG1126 [607] (byte) bitmap_line_xdyi::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_xdyi::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1127 [608] (byte) bitmap_line_xdyi::yd#0 ← (byte) bitmap_line::yd#1 - // (byte) bitmap_line_xdyi::yd#0 = (byte) bitmap_line::yd#1 // register copy zp ZP_BYTE:7 //SEG1128 [609] call bitmap_line_xdyi //SEG1129 [654] phi from bitmap_line::@3 to bitmap_line_xdyi [phi:bitmap_line::@3->bitmap_line_xdyi] bitmap_line_xdyi_from_b3: @@ -22366,9 +22529,7 @@ bitmap_line: { //SEG1141 [614] (byte) bitmap_line_ydxd::y1#0 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_ydxd.y1 //SEG1142 [615] (byte) bitmap_line_ydxd::yd#0 ← (byte) bitmap_line::yd#0 - // (byte) bitmap_line_ydxd::yd#0 = (byte) bitmap_line::yd#0 // register copy zp ZP_BYTE:7 //SEG1143 [616] (byte) bitmap_line_ydxd::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_ydxd::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1144 [617] call bitmap_line_ydxd //SEG1145 [706] phi from bitmap_line::@20 to bitmap_line_ydxd [phi:bitmap_line::@20->bitmap_line_ydxd] bitmap_line_ydxd_from_b20: @@ -22390,9 +22551,7 @@ bitmap_line: { lda x0 sta bitmap_line_xdyd.x1 //SEG1155 [621] (byte) bitmap_line_xdyd::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_xdyd::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1156 [622] (byte) bitmap_line_xdyd::yd#0 ← (byte) bitmap_line::yd#0 - // (byte) bitmap_line_xdyd::yd#0 = (byte) bitmap_line::yd#0 // register copy zp ZP_BYTE:7 //SEG1157 [623] call bitmap_line_xdyd //SEG1158 [691] phi from bitmap_line::@6 to bitmap_line_xdyd [phi:bitmap_line::@6->bitmap_line_xdyd] bitmap_line_xdyd_from_b6: @@ -22437,11 +22596,8 @@ bitmap_line: { //SEG1172 [629] (byte) bitmap_line_ydxd::x#1 ← (byte) bitmap_line::x1#0 -- vbuxx=vbuz1 ldx x1 //SEG1173 [630] (byte) bitmap_line_ydxd::y1#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_ydxd::y1#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:11 //SEG1174 [631] (byte) bitmap_line_ydxd::yd#1 ← (byte) bitmap_line::yd#3 - // (byte) bitmap_line_ydxd::yd#1 = (byte) bitmap_line::yd#3 // register copy zp ZP_BYTE:7 //SEG1175 [632] (byte) bitmap_line_ydxd::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_ydxd::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1176 [633] call bitmap_line_ydxd //SEG1177 [706] phi from bitmap_line::@24 to bitmap_line_ydxd [phi:bitmap_line::@24->bitmap_line_ydxd] bitmap_line_ydxd_from_b24: @@ -22458,13 +22614,9 @@ bitmap_line: { lda x0 sta bitmap_line_xdyd.x //SEG1185 [635] (byte) bitmap_line_xdyd::y#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_xdyd::y#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:11 //SEG1186 [636] (byte) bitmap_line_xdyd::x1#1 ← (byte) bitmap_line::x1#0 - // (byte) bitmap_line_xdyd::x1#1 = (byte) bitmap_line::x1#0 // register copy zp ZP_BYTE:12 //SEG1187 [637] (byte) bitmap_line_xdyd::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_xdyd::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1188 [638] (byte) bitmap_line_xdyd::yd#1 ← (byte) bitmap_line::yd#3 - // (byte) bitmap_line_xdyd::yd#1 = (byte) bitmap_line::yd#3 // register copy zp ZP_BYTE:7 //SEG1189 [639] call bitmap_line_xdyd //SEG1190 [691] phi from bitmap_line::@10 to bitmap_line_xdyd [phi:bitmap_line::@10->bitmap_line_xdyd] bitmap_line_xdyd_from_b10: @@ -22497,9 +22649,7 @@ bitmap_line: { //SEG1202 [644] (byte) bitmap_line_ydxi::y1#1 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_ydxi.y1 //SEG1203 [645] (byte) bitmap_line_ydxi::yd#1 ← (byte) bitmap_line::yd#10 - // (byte) bitmap_line_ydxi::yd#1 = (byte) bitmap_line::yd#10 // register copy zp ZP_BYTE:7 //SEG1204 [646] (byte) bitmap_line_ydxi::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_ydxi::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1205 [647] call bitmap_line_ydxi //SEG1206 [676] phi from bitmap_line::@27 to bitmap_line_ydxi [phi:bitmap_line::@27->bitmap_line_ydxi] bitmap_line_ydxi_from_b27: @@ -22516,14 +22666,11 @@ bitmap_line: { lda x0 sta bitmap_line_xdyi.x //SEG1214 [649] (byte) bitmap_line_xdyi::y#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_xdyi::y#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:11 //SEG1215 [650] (byte) bitmap_line_xdyi::x1#1 ← (byte) bitmap_line::x1#0 -- vbuz1=vbuz2 lda x1 sta bitmap_line_xdyi.x1 //SEG1216 [651] (byte) bitmap_line_xdyi::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_xdyi::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1217 [652] (byte) bitmap_line_xdyi::yd#1 ← (byte) bitmap_line::yd#10 - // (byte) bitmap_line_xdyi::yd#1 = (byte) bitmap_line::yd#10 // register copy zp ZP_BYTE:7 //SEG1218 [653] call bitmap_line_xdyi //SEG1219 [654] phi from bitmap_line::@13 to bitmap_line_xdyi [phi:bitmap_line::@13->bitmap_line_xdyi] bitmap_line_xdyi_from_b13: @@ -22667,7 +22814,6 @@ bitmap_line_ydxi: { //SEG1267 bitmap_line_ydxi::@1 b1: //SEG1268 [679] (byte) bitmap_plot::x#2 ← (byte) bitmap_line_ydxi::x#3 - // (byte) bitmap_plot::x#2 = (byte) bitmap_line_ydxi::x#3 // register copy reg byte x //SEG1269 [680] (byte) bitmap_plot::y#2 ← (byte) bitmap_line_ydxi::y#3 -- vbuyy=vbuz1 ldy y //SEG1270 [681] call bitmap_plot @@ -22817,7 +22963,6 @@ bitmap_line_ydxd: { //SEG1323 bitmap_line_ydxd::@1 b1: //SEG1324 [709] (byte) bitmap_plot::x#3 ← (byte) bitmap_line_ydxd::x#3 - // (byte) bitmap_plot::x#3 = (byte) bitmap_line_ydxd::x#3 // register copy reg byte x //SEG1325 [710] (byte) bitmap_plot::y#3 ← (byte) bitmap_line_ydxd::y#2 -- vbuyy=vbuz1 ldy y //SEG1326 [711] call bitmap_plot @@ -22872,6 +23017,7 @@ bitmap_line_ydxd: { rts } //SEG1345 bitmap_clear +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = 2 .label y = 4 @@ -22882,7 +23028,6 @@ bitmap_clear: { lda bitmap_plot_xhi sta _3+1 //SEG1347 [722] (byte*~) bitmap_clear::bitmap#5 ← (byte*)(word~) bitmap_clear::$3 - // (byte*~) bitmap_clear::bitmap#5 = (byte*)(word~) bitmap_clear::$3 // register copy zp ZP_WORD:2 //SEG1348 [723] phi from bitmap_clear to bitmap_clear::@1 [phi:bitmap_clear->bitmap_clear::@1] b1_from_bitmap_clear: //SEG1349 [723] phi (byte) bitmap_clear::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:bitmap_clear->bitmap_clear::@1#0] -- vbuz1=vbuc1 @@ -22940,6 +23085,7 @@ bitmap_clear: { rts } //SEG1371 bitmap_init +// Initialize the bitmap plotter tables for a specific bitmap bitmap_init: { .label _6 = 4 .label yoffs = 2 @@ -23063,6 +23209,18 @@ bitmap_init: { jmp b2 } //SEG1418 mode_mcchar +// Multicolor Character Mode (LINEAR/HICOL/CHUNK/COLDIS/BMM/ECM = 0, MCM = 1) +// Resolution: 160x200 (320x200) +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & CharData[7:0] & RowCounter[2:0] ) +// GfxData Pixel Shifter (1) if ColorData[3:3] = 0: +// - 0: 4bpp BgColor0[3:0] +// - 1: 4bpp ColorData[2:0] +// GfxData Pixel Shifter (2) if ColorData[3:3] = 1: +// - 00: 4bpp BgColor0[3:0] +// - 01: 4bpp BgColor1[3:0] +// - 10: 4bpp BgColor2[3:0] +// - 11: 4bpp ColorData[2:0]// Standard Character Mode (LINEAR/HICOL/CHUNK/COLDIS/ECM/MCM/BMM = 0) mode_mcchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -23240,6 +23398,17 @@ mode_mcchar: { rts } //SEG1481 mode_ecmchar +// Extended Background Color Character Mode (LINEAR/HICOL/CHUNK/COLDIS/MCM/BMM = 0, ECM = 1) +// Resolution: 320x200 +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & "00" & CharData[5:0] & RowCounter[2:0] ) +// GfxData Pixel Shifter (1) +// - 0: 4bpp Background Color +// - CharData[7:6] 00: 4bpp BgColor0[3:0] +// - CharData[7:6] 01: 4bpp BgColor1[3:0] +// - CharData[7:6] 10: 4bpp BgColor2[3:0] +// - CharData[7:6] 11: 4bpp BgColor3[3:0] +// - 1: 4bpp ColorData[3:0] mode_ecmchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -23420,6 +23589,13 @@ mode_ecmchar: { rts } //SEG1545 mode_stdchar +// Standard Character Mode (LINEAR/HICOL/CHUNK/COLDIS/ECM/MCM/BMM = 0) +// Resolution: 320x200 +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & CharData[7:0] & RowCounter[2:0] ) +// Pixel Shifter (1) +// - 0: 4bpp BgColor0[3:0] +// - 1: 4bpp ColorData[3:0] mode_stdchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -23591,6 +23767,8 @@ mode_stdchar: { rts } //SEG1606 print_str_lines +// Print a number of zero-terminated strings, each followed by a newline. +// The sequence of lines is terminated by another zero. print_str_lines: { .label str = 2 //SEG1607 [866] phi from print_str_lines to print_str_lines::@1 [phi:print_str_lines->print_str_lines::@1] @@ -23685,6 +23863,7 @@ print_str_lines: { jmp b1 } //SEG1638 print_ln +// Print a newline print_ln: { //SEG1639 [881] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -23717,6 +23896,7 @@ print_ln: { rts } //SEG1646 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG1647 [886] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -23756,6 +23936,7 @@ print_cls: { rts } //SEG1657 print_set_screen +// Set the screen to print on. Also resets current line/char cursor. print_set_screen: { jmp breturn //SEG1658 print_set_screen::@return @@ -26388,10 +26569,8 @@ menu: { ldy #KEY_1 jsr keyboard_key_pressed //SEG60 [36] (byte) keyboard_key_pressed::return#2 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#2 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG61 menu::@50 //SEG62 [37] (byte~) menu::$29 ← (byte) keyboard_key_pressed::return#2 - // (byte~) menu::$29 = (byte) keyboard_key_pressed::return#2 // register copy reg byte a //SEG63 [38] if((byte~) menu::$29==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@6 -- vbuaa_eq_0_then_la1 cmp #0 beq b6 @@ -26412,10 +26591,8 @@ menu: { ldy #KEY_2 jsr keyboard_key_pressed //SEG74 [44] (byte) keyboard_key_pressed::return#24 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#24 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG75 menu::@51 //SEG76 [45] (byte~) menu::$33 ← (byte) keyboard_key_pressed::return#24 - // (byte~) menu::$33 = (byte) keyboard_key_pressed::return#24 // register copy reg byte a //SEG77 [46] if((byte~) menu::$33==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@7 -- vbuaa_eq_0_then_la1 cmp #0 beq b7 @@ -26433,10 +26610,8 @@ menu: { ldy #KEY_3 jsr keyboard_key_pressed //SEG86 [51] (byte) keyboard_key_pressed::return#25 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#25 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG87 menu::@53 //SEG88 [52] (byte~) menu::$37 ← (byte) keyboard_key_pressed::return#25 - // (byte~) menu::$37 = (byte) keyboard_key_pressed::return#25 // register copy reg byte a //SEG89 [53] if((byte~) menu::$37==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@8 -- vbuaa_eq_0_then_la1 cmp #0 beq b8 @@ -26454,10 +26629,8 @@ menu: { ldy #KEY_4 jsr keyboard_key_pressed //SEG98 [58] (byte) keyboard_key_pressed::return#26 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#26 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG99 menu::@55 //SEG100 [59] (byte~) menu::$41 ← (byte) keyboard_key_pressed::return#26 - // (byte~) menu::$41 = (byte) keyboard_key_pressed::return#26 // register copy reg byte a //SEG101 [60] if((byte~) menu::$41==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@9 -- vbuaa_eq_0_then_la1 cmp #0 beq b9 @@ -26475,10 +26648,8 @@ menu: { ldy #KEY_6 jsr keyboard_key_pressed //SEG110 [65] (byte) keyboard_key_pressed::return#27 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#27 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG111 menu::@57 //SEG112 [66] (byte~) menu::$45 ← (byte) keyboard_key_pressed::return#27 - // (byte~) menu::$45 = (byte) keyboard_key_pressed::return#27 // register copy reg byte a //SEG113 [67] if((byte~) menu::$45==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@10 -- vbuaa_eq_0_then_la1 cmp #0 beq b10 @@ -26496,10 +26667,8 @@ menu: { ldy #KEY_7 jsr keyboard_key_pressed //SEG122 [72] (byte) keyboard_key_pressed::return#28 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#28 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG123 menu::@59 //SEG124 [73] (byte~) menu::$49 ← (byte) keyboard_key_pressed::return#28 - // (byte~) menu::$49 = (byte) keyboard_key_pressed::return#28 // register copy reg byte a //SEG125 [74] if((byte~) menu::$49==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@11 -- vbuaa_eq_0_then_la1 cmp #0 beq b11 @@ -26517,10 +26686,8 @@ menu: { ldy #KEY_8 jsr keyboard_key_pressed //SEG134 [79] (byte) keyboard_key_pressed::return#29 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#29 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG135 menu::@61 //SEG136 [80] (byte~) menu::$53 ← (byte) keyboard_key_pressed::return#29 - // (byte~) menu::$53 = (byte) keyboard_key_pressed::return#29 // register copy reg byte a //SEG137 [81] if((byte~) menu::$53==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@12 -- vbuaa_eq_0_then_la1 cmp #0 beq b12 @@ -26538,10 +26705,8 @@ menu: { ldy #KEY_A jsr keyboard_key_pressed //SEG146 [86] (byte) keyboard_key_pressed::return#30 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#30 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG147 menu::@63 //SEG148 [87] (byte~) menu::$57 ← (byte) keyboard_key_pressed::return#30 - // (byte~) menu::$57 = (byte) keyboard_key_pressed::return#30 // register copy reg byte a //SEG149 [88] if((byte~) menu::$57==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@13 -- vbuaa_eq_0_then_la1 cmp #0 beq b13 @@ -26559,10 +26724,8 @@ menu: { ldy #KEY_B jsr keyboard_key_pressed //SEG158 [93] (byte) keyboard_key_pressed::return#10 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#10 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG159 menu::@65 //SEG160 [94] (byte~) menu::$61 ← (byte) keyboard_key_pressed::return#10 - // (byte~) menu::$61 = (byte) keyboard_key_pressed::return#10 // register copy reg byte a //SEG161 [95] if((byte~) menu::$61==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@14 -- vbuaa_eq_0_then_la1 cmp #0 beq b14 @@ -26580,10 +26743,8 @@ menu: { ldy #KEY_C jsr keyboard_key_pressed //SEG170 [100] (byte) keyboard_key_pressed::return#11 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#11 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG171 menu::@67 //SEG172 [101] (byte~) menu::$65 ← (byte) keyboard_key_pressed::return#11 - // (byte~) menu::$65 = (byte) keyboard_key_pressed::return#11 // register copy reg byte a //SEG173 [102] if((byte~) menu::$65==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@15 -- vbuaa_eq_0_then_la1 cmp #0 beq b15 @@ -26601,10 +26762,8 @@ menu: { ldy #KEY_D jsr keyboard_key_pressed //SEG182 [107] (byte) keyboard_key_pressed::return#12 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#12 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG183 menu::@69 //SEG184 [108] (byte~) menu::$69 ← (byte) keyboard_key_pressed::return#12 - // (byte~) menu::$69 = (byte) keyboard_key_pressed::return#12 // register copy reg byte a //SEG185 [109] if((byte~) menu::$69==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@16 -- vbuaa_eq_0_then_la1 cmp #0 beq b16 @@ -26622,10 +26781,8 @@ menu: { ldy #KEY_E jsr keyboard_key_pressed //SEG194 [114] (byte) keyboard_key_pressed::return#13 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#13 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG195 menu::@71 //SEG196 [115] (byte~) menu::$73 ← (byte) keyboard_key_pressed::return#13 - // (byte~) menu::$73 = (byte) keyboard_key_pressed::return#13 // register copy reg byte a //SEG197 [116] if((byte~) menu::$73==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@4 -- vbuaa_eq_0_then_la1 cmp #0 bne !b4+ @@ -26638,6 +26795,12 @@ menu: { jmp breturn } //SEG201 mode_8bppchunkybmm +// Chunky 8bpp Bitmap Mode (BMM = 0, ECM/MCM/HICOL/LINEAR/CHUNK/COLDIS = 1) +// Resolution: 320x200 +// Linear Adressing +// CharData/PlaneB Pixel Shifter (8): +// - 8bpp color PlaneB[7:0] +// To set up a linear video frame buffer the step size must be set to 8. mode_8bppchunkybmm: { .const PLANEB = $20000 .label _23 = $d @@ -26810,6 +26973,7 @@ mode_8bppchunkybmm: { rts } //SEG279 mode_ctrl +// Allow the user to control the DTV graphics using different keys mode_ctrl: { //SEG280 [156] phi from mode_ctrl mode_ctrl::@30 to mode_ctrl::@1 [phi:mode_ctrl/mode_ctrl::@30->mode_ctrl::@1] //SEG281 [156] phi (byte) dtv_control#114 = (byte) dtv_control#145 [phi:mode_ctrl/mode_ctrl::@30->mode_ctrl::@1#0] -- register_copy @@ -26829,10 +26993,8 @@ mode_ctrl: { ldy #KEY_SPACE jsr keyboard_key_pressed //SEG291 [160] (byte) keyboard_key_pressed::return#14 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#14 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG292 mode_ctrl::@32 //SEG293 [161] (byte~) mode_ctrl::$1 ← (byte) keyboard_key_pressed::return#14 - // (byte~) mode_ctrl::$1 = (byte) keyboard_key_pressed::return#14 // register copy reg byte a //SEG294 [162] if((byte~) mode_ctrl::$1==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@7 -- vbuaa_eq_0_then_la1 cmp #0 beq b7 @@ -26849,10 +27011,8 @@ mode_ctrl: { ldy #KEY_L jsr keyboard_key_pressed //SEG302 [166] (byte) keyboard_key_pressed::return#15 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#15 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG303 mode_ctrl::@33 //SEG304 [167] (byte~) mode_ctrl::$4 ← (byte) keyboard_key_pressed::return#15 - // (byte~) mode_ctrl::$4 = (byte) keyboard_key_pressed::return#15 // register copy reg byte a //SEG305 [168] if((byte~) mode_ctrl::$4==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@8 -- vbuaa_eq_0_then_la1 cmp #0 beq b8 @@ -26871,10 +27031,8 @@ mode_ctrl: { ldy #KEY_H jsr keyboard_key_pressed //SEG314 [172] (byte) keyboard_key_pressed::return#16 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#16 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG315 mode_ctrl::@34 //SEG316 [173] (byte~) mode_ctrl::$8 ← (byte) keyboard_key_pressed::return#16 - // (byte~) mode_ctrl::$8 = (byte) keyboard_key_pressed::return#16 // register copy reg byte a //SEG317 [174] if((byte~) mode_ctrl::$8==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@9 -- vbuaa_eq_0_then_la1 cmp #0 beq b9 @@ -26893,10 +27051,8 @@ mode_ctrl: { ldy #KEY_O jsr keyboard_key_pressed //SEG326 [178] (byte) keyboard_key_pressed::return#17 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#17 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG327 mode_ctrl::@35 //SEG328 [179] (byte~) mode_ctrl::$12 ← (byte) keyboard_key_pressed::return#17 - // (byte~) mode_ctrl::$12 = (byte) keyboard_key_pressed::return#17 // register copy reg byte a //SEG329 [180] if((byte~) mode_ctrl::$12==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@10 -- vbuaa_eq_0_then_la1 cmp #0 beq b10 @@ -26915,10 +27071,8 @@ mode_ctrl: { ldy #KEY_B jsr keyboard_key_pressed //SEG338 [184] (byte) keyboard_key_pressed::return#18 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#18 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG339 mode_ctrl::@36 //SEG340 [185] (byte~) mode_ctrl::$16 ← (byte) keyboard_key_pressed::return#18 - // (byte~) mode_ctrl::$16 = (byte) keyboard_key_pressed::return#18 // register copy reg byte a //SEG341 [186] if((byte~) mode_ctrl::$16==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@11 -- vbuaa_eq_0_then_la1 cmp #0 beq b11 @@ -26937,10 +27091,8 @@ mode_ctrl: { ldy #KEY_U jsr keyboard_key_pressed //SEG350 [190] (byte) keyboard_key_pressed::return#19 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#19 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG351 mode_ctrl::@37 //SEG352 [191] (byte~) mode_ctrl::$20 ← (byte) keyboard_key_pressed::return#19 - // (byte~) mode_ctrl::$20 = (byte) keyboard_key_pressed::return#19 // register copy reg byte a //SEG353 [192] if((byte~) mode_ctrl::$20==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@12 -- vbuaa_eq_0_then_la1 cmp #0 beq b12 @@ -26959,10 +27111,8 @@ mode_ctrl: { ldy #KEY_C jsr keyboard_key_pressed //SEG362 [196] (byte) keyboard_key_pressed::return#20 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#20 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG363 mode_ctrl::@38 //SEG364 [197] (byte~) mode_ctrl::$24 ← (byte) keyboard_key_pressed::return#20 - // (byte~) mode_ctrl::$24 = (byte) keyboard_key_pressed::return#20 // register copy reg byte a //SEG365 [198] if((byte~) mode_ctrl::$24==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@13 -- vbuaa_eq_0_then_la1 cmp #0 beq b13 @@ -26981,10 +27131,8 @@ mode_ctrl: { ldy #KEY_0 jsr keyboard_key_pressed //SEG374 [202] (byte) keyboard_key_pressed::return#21 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#21 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG375 mode_ctrl::@39 //SEG376 [203] (byte~) mode_ctrl::$28 ← (byte) keyboard_key_pressed::return#21 - // (byte~) mode_ctrl::$28 = (byte) keyboard_key_pressed::return#21 // register copy reg byte a //SEG377 [204] if((byte~) mode_ctrl::$28==(byte/signed byte/word/signed word/dword/signed dword) 0) goto mode_ctrl::@46 -- vbuaa_eq_0_then_la1 cmp #0 beq b14 @@ -27010,6 +27158,10 @@ mode_ctrl: { //SEG389 [205] phi (byte) mode_ctrl::ctrl#14 = (byte) mode_ctrl::ctrl#22 [phi:mode_ctrl::@46->mode_ctrl::@14#0] -- register_copy } //SEG390 keyboard_key_pressed +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { .label colidx = 7 //SEG391 [212] (byte) keyboard_key_pressed::colidx#0 ← (byte) keyboard_key_pressed::key#20 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuz1=vbuyy_band_vbuc1 @@ -27026,10 +27178,8 @@ keyboard_key_pressed: { //SEG394 [215] call keyboard_matrix_read jsr keyboard_matrix_read //SEG395 [216] (byte) keyboard_matrix_read::return#2 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#2 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a //SEG396 keyboard_key_pressed::@2 //SEG397 [217] (byte~) keyboard_key_pressed::$2 ← (byte) keyboard_matrix_read::return#2 - // (byte~) keyboard_key_pressed::$2 = (byte) keyboard_matrix_read::return#2 // register copy reg byte a //SEG398 [218] (byte) keyboard_key_pressed::return#0 ← (byte~) keyboard_key_pressed::$2 & *((const byte[8]) keyboard_matrix_col_bitmask#0 + (byte) keyboard_key_pressed::colidx#0) -- vbuaa=vbuaa_band_pbuc1_derefidx_vbuz1 ldy colidx and keyboard_matrix_col_bitmask,y @@ -27038,6 +27188,11 @@ keyboard_key_pressed: { rts } //SEG401 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { //SEG402 [220] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0 + (byte) keyboard_matrix_read::rowid#0) -- _deref_pbuc1=pbuc2_derefidx_vbuyy lda keyboard_matrix_row_bitmask,y @@ -27050,6 +27205,9 @@ keyboard_matrix_read: { rts } //SEG406 dtvSetCpuBankSegment1 +// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff) +// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff +// The actual memory addressed will be $4000*cpuSegmentIdx dtvSetCpuBankSegment1: { .label cpuBank = $ff //SEG407 [224] *((const byte*) dtvSetCpuBankSegment1::cpuBank#0) ← (byte) dtvSetCpuBankSegment1::cpuBankIdx#3 -- _deref_pbuc1=vbuaa @@ -27063,6 +27221,15 @@ dtvSetCpuBankSegment1: { rts } //SEG411 mode_8bpppixelcell +// 8bpp Pixel Cell Mode (BMM/COLDIS = 0, ECM/MCM/HICOL/LINEAR/CHUNK = 1) +// Pixel Cell Adressing +// CharData[8]: (PlaneA[21:0]) +// GfxData[8]: (PlaneB[21:14] & CharData[7:0] & RowCounter[3:0] & PixelCounter[7:0] ) +// GfxData Pixel Shifter (8): +// - 8bpp color GfxData[7:0] +// Pixel cell mode can be thought of as a text mode that uses a 8x8 pixel 8bpp font (64 bytes/char). +// The characters come from counter A and the font (or "cells") from counter B. +// Counter B step and modulo should be set to 0, counter A modulo to 0 and counter A step to 1 for normal operation. mode_8bpppixelcell: { .label PLANEA = $3c00 .label PLANEB = $4000 @@ -27317,6 +27484,12 @@ mode_8bpppixelcell: { rts } //SEG526 mode_sixsfred +// Sixs Fred Mode - 8bpp Packed Bitmap - Generated from the two DTV linear graphics plane counters +// Two Plane MultiColor Bitmap - 8bpp Packed Bitmap (CHUNK/COLDIS = 0, ECM/BMM/MCM/HICOL/LINEAR = 1) +// Resolution: 160x200 +// Linear Adressing +// GfxData/PlaneA Pixel Shifter (2), CharData/PlaneB Pixel Shifter (2): +// - 8bpp color (ColorData[3:0],CharData/PlaneB[1:0], GfxData/PlaneA[1:0]) mode_sixsfred: { .label PLANEA = $4000 .label PLANEB = $6000 @@ -27552,6 +27725,15 @@ mode_sixsfred: { row_bitmask: .byte 0, $55, $aa, $ff } //SEG628 mode_twoplanebitmap +// Two Plane Bitmap - generated from the two DTV linear graphics plane counters +// Two Plane Bitmap Mode (CHUNK/COLDIS/MCM = 0, ECM/BMM/HICOL/LINEAR = 1) +// Resolution: 320x200 +// Linear Adressing +// GfxData/PlaneA Pixel Shifter (1), CharData/PlaneB Pixel Shifter (1): +// - Plane A = 0 Plane B = 0: 8bpp BgColor0[7:0] +// - Plane A = 0 Plane B = 1: 8bpp "0000" & ColorData[7:4] +// - Plane A = 1 Plane B = 0: 8bpp "0000" & ColorData[3:0] +// - Plane A = 1 Plane B = 1: 8bpp BgColor1[7:0] mode_twoplanebitmap: { .label PLANEA = $4000 .label PLANEB = $6000 @@ -27818,6 +28000,12 @@ mode_twoplanebitmap: { jmp b7 } //SEG741 mode_sixsfred2 +// Sixs Fred Mode 2 - 8bpp Packed Bitmap - Generated from the two DTV linear graphics plane counters +// Two Plane MultiColor Bitmap - 8bpp Packed Bitmap (CHUNK/COLDIS/HICOL = 0, ECM/BMM/MCM/LINEAR = 1) +// Resolution: 160x200 +// Linear Adressing +// PlaneA Pixel Shifter (2), PlaneB Pixel Shifter (2): +// - 8bpp color (PlaneB[1:0],ColorData[5:4],PlaneA[1:0],ColorData[1:0]) mode_sixsfred2: { .label PLANEA = $4000 .label PLANEB = $6000 @@ -28062,6 +28250,18 @@ mode_sixsfred2: { row_bitmask: .byte 0, $55, $aa, $ff } //SEG845 mode_hicolmcchar +// High Color Multicolor Character Mode (LINEAR/CHUNK/COLDIS/BMM/ECM = 0, MCM/HICOL = 1) +// Resolution: 160x200 (320x200) +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & CharData[7:0] & RowCounter[2:0] ) +// GfxData Pixel Shifter (1) if ColorData[3:3] = 0: +// - 0: 8bpp BgColor0[7:0] +// - 1: 8bpp ColorData[7:4] "0" & Color[2:0] +// GfxData Pixel Shifter (2) if ColorData[3:3] = 1: +// - 00: 8bpp BgColor0[7:0] +// - 01: 8bpp BgColor1[7:0] +// - 10: 8bpp BgColor2[7:0] +// - 11: 8bpp ColorData[7:4] "0" & Color[2:0] mode_hicolmcchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -28211,6 +28411,17 @@ mode_hicolmcchar: { rts } //SEG906 mode_hicolecmchar +// High Color Extended Background Color Character Mode (LINEAR/CHUNK/COLDIS/MCM/BMM = 0, ECM/HICOL = 1) +// Resolution: 320x200 +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & "00" & CharData[5:0] & RowCounter[2:0] ) +// GfxData Pixel Shifter (1) +// - 0: 8bpp Background Color +// - CharData[7:6] 00: 8bpp BgColor0[7:0] +// - CharData[7:6] 01: 8bpp BgColor1[7:0] +// - CharData[7:6] 10: 8bpp BgColor2[7:0] +// - CharData[7:6] 11: 8bpp BgColor3[7:0] +// - 1: 8bpp ColorData[7:0] mode_hicolecmchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -28363,6 +28574,13 @@ mode_hicolecmchar: { rts } //SEG968 mode_hicolstdchar +// High Color Standard Character Mode (LINEAR/CHUNK/COLDIS/ECM/MCM/BMM = 0, HICOL = 1) +// Resolution: 320x200 +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & CharData[7:0] & RowCounter[2:0] ) +// Pixel Shifter (1) +// - 0: 8bpp BgColor0[7:0] +// - 1: 8bpp ColorData[7:0] mode_hicolstdchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -28505,6 +28723,13 @@ mode_hicolstdchar: { rts } //SEG1027 mode_stdbitmap +// Standard Bitmap Mode (LINEAR/HICOL/CHUNK/COLDIS/MCM/ECM = 0, BMM = 1) +// Resolution: 320x200 +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:2] & Matrix[9:0] & RowCounter[2:0] ) +// Pixel Shifter (1) +// - 0: 4bpp CharData[3:0] +// - 1: 4bpp CharData[7:4] mode_stdbitmap: { .label SCREEN = $4000 .label BITMAP = $6000 @@ -28673,6 +28898,7 @@ mode_stdbitmap: { lines_y: .byte 0, 0, $c7, $c7, 0, 0, $64, $c7, $64, 0 } //SEG1099 bitmap_line +// Draw a line on the bitmap bitmap_line: { .label xd = 8 .label yd = 7 @@ -28710,11 +28936,8 @@ bitmap_line: { //SEG1109 [598] (byte) bitmap_line_ydxi::x#0 ← (byte) bitmap_line::x1#0 -- vbuxx=vbuz1 ldx x1 //SEG1110 [599] (byte) bitmap_line_ydxi::y1#0 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_ydxi::y1#0 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:11 //SEG1111 [600] (byte) bitmap_line_ydxi::yd#0 ← (byte) bitmap_line::yd#1 - // (byte) bitmap_line_ydxi::yd#0 = (byte) bitmap_line::yd#1 // register copy zp ZP_BYTE:7 //SEG1112 [601] (byte) bitmap_line_ydxi::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_ydxi::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1113 [602] call bitmap_line_ydxi //SEG1114 [676] phi from bitmap_line::@17 to bitmap_line_ydxi [phi:bitmap_line::@17->bitmap_line_ydxi] //SEG1115 [676] phi (byte) bitmap_line_ydxi::y1#6 = (byte) bitmap_line_ydxi::y1#0 [phi:bitmap_line::@17->bitmap_line_ydxi#0] -- register_copy @@ -28735,11 +28958,8 @@ bitmap_line: { //SEG1124 [605] (byte) bitmap_line_xdyi::y#0 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_xdyi.y //SEG1125 [606] (byte) bitmap_line_xdyi::x1#0 ← (byte) bitmap_line::x0#0 - // (byte) bitmap_line_xdyi::x1#0 = (byte) bitmap_line::x0#0 // register copy zp ZP_BYTE:9 //SEG1126 [607] (byte) bitmap_line_xdyi::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_xdyi::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1127 [608] (byte) bitmap_line_xdyi::yd#0 ← (byte) bitmap_line::yd#1 - // (byte) bitmap_line_xdyi::yd#0 = (byte) bitmap_line::yd#1 // register copy zp ZP_BYTE:7 //SEG1128 [609] call bitmap_line_xdyi //SEG1129 [654] phi from bitmap_line::@3 to bitmap_line_xdyi [phi:bitmap_line::@3->bitmap_line_xdyi] //SEG1130 [654] phi (byte) bitmap_line_xdyi::x1#6 = (byte) bitmap_line_xdyi::x1#0 [phi:bitmap_line::@3->bitmap_line_xdyi#0] -- register_copy @@ -28768,9 +28988,7 @@ bitmap_line: { //SEG1141 [614] (byte) bitmap_line_ydxd::y1#0 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_ydxd.y1 //SEG1142 [615] (byte) bitmap_line_ydxd::yd#0 ← (byte) bitmap_line::yd#0 - // (byte) bitmap_line_ydxd::yd#0 = (byte) bitmap_line::yd#0 // register copy zp ZP_BYTE:7 //SEG1143 [616] (byte) bitmap_line_ydxd::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_ydxd::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1144 [617] call bitmap_line_ydxd //SEG1145 [706] phi from bitmap_line::@20 to bitmap_line_ydxd [phi:bitmap_line::@20->bitmap_line_ydxd] //SEG1146 [706] phi (byte) bitmap_line_ydxd::y1#6 = (byte) bitmap_line_ydxd::y1#0 [phi:bitmap_line::@20->bitmap_line_ydxd#0] -- register_copy @@ -28791,9 +29009,7 @@ bitmap_line: { lda x0 sta bitmap_line_xdyd.x1 //SEG1155 [621] (byte) bitmap_line_xdyd::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_xdyd::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:8 //SEG1156 [622] (byte) bitmap_line_xdyd::yd#0 ← (byte) bitmap_line::yd#0 - // (byte) bitmap_line_xdyd::yd#0 = (byte) bitmap_line::yd#0 // register copy zp ZP_BYTE:7 //SEG1157 [623] call bitmap_line_xdyd //SEG1158 [691] phi from bitmap_line::@6 to bitmap_line_xdyd [phi:bitmap_line::@6->bitmap_line_xdyd] //SEG1159 [691] phi (byte) bitmap_line_xdyd::x1#6 = (byte) bitmap_line_xdyd::x1#0 [phi:bitmap_line::@6->bitmap_line_xdyd#0] -- register_copy @@ -28832,11 +29048,8 @@ bitmap_line: { //SEG1172 [629] (byte) bitmap_line_ydxd::x#1 ← (byte) bitmap_line::x1#0 -- vbuxx=vbuz1 ldx x1 //SEG1173 [630] (byte) bitmap_line_ydxd::y1#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_ydxd::y1#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:11 //SEG1174 [631] (byte) bitmap_line_ydxd::yd#1 ← (byte) bitmap_line::yd#3 - // (byte) bitmap_line_ydxd::yd#1 = (byte) bitmap_line::yd#3 // register copy zp ZP_BYTE:7 //SEG1175 [632] (byte) bitmap_line_ydxd::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_ydxd::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1176 [633] call bitmap_line_ydxd //SEG1177 [706] phi from bitmap_line::@24 to bitmap_line_ydxd [phi:bitmap_line::@24->bitmap_line_ydxd] //SEG1178 [706] phi (byte) bitmap_line_ydxd::y1#6 = (byte) bitmap_line_ydxd::y1#1 [phi:bitmap_line::@24->bitmap_line_ydxd#0] -- register_copy @@ -28852,13 +29065,9 @@ bitmap_line: { lda x0 sta bitmap_line_xdyd.x //SEG1185 [635] (byte) bitmap_line_xdyd::y#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_xdyd::y#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:11 //SEG1186 [636] (byte) bitmap_line_xdyd::x1#1 ← (byte) bitmap_line::x1#0 - // (byte) bitmap_line_xdyd::x1#1 = (byte) bitmap_line::x1#0 // register copy zp ZP_BYTE:12 //SEG1187 [637] (byte) bitmap_line_xdyd::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_xdyd::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1188 [638] (byte) bitmap_line_xdyd::yd#1 ← (byte) bitmap_line::yd#3 - // (byte) bitmap_line_xdyd::yd#1 = (byte) bitmap_line::yd#3 // register copy zp ZP_BYTE:7 //SEG1189 [639] call bitmap_line_xdyd //SEG1190 [691] phi from bitmap_line::@10 to bitmap_line_xdyd [phi:bitmap_line::@10->bitmap_line_xdyd] //SEG1191 [691] phi (byte) bitmap_line_xdyd::x1#6 = (byte) bitmap_line_xdyd::x1#1 [phi:bitmap_line::@10->bitmap_line_xdyd#0] -- register_copy @@ -28887,9 +29096,7 @@ bitmap_line: { //SEG1202 [644] (byte) bitmap_line_ydxi::y1#1 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_ydxi.y1 //SEG1203 [645] (byte) bitmap_line_ydxi::yd#1 ← (byte) bitmap_line::yd#10 - // (byte) bitmap_line_ydxi::yd#1 = (byte) bitmap_line::yd#10 // register copy zp ZP_BYTE:7 //SEG1204 [646] (byte) bitmap_line_ydxi::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_ydxi::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1205 [647] call bitmap_line_ydxi //SEG1206 [676] phi from bitmap_line::@27 to bitmap_line_ydxi [phi:bitmap_line::@27->bitmap_line_ydxi] //SEG1207 [676] phi (byte) bitmap_line_ydxi::y1#6 = (byte) bitmap_line_ydxi::y1#1 [phi:bitmap_line::@27->bitmap_line_ydxi#0] -- register_copy @@ -28905,14 +29112,11 @@ bitmap_line: { lda x0 sta bitmap_line_xdyi.x //SEG1214 [649] (byte) bitmap_line_xdyi::y#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_xdyi::y#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:11 //SEG1215 [650] (byte) bitmap_line_xdyi::x1#1 ← (byte) bitmap_line::x1#0 -- vbuz1=vbuz2 lda x1 sta bitmap_line_xdyi.x1 //SEG1216 [651] (byte) bitmap_line_xdyi::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_xdyi::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:8 //SEG1217 [652] (byte) bitmap_line_xdyi::yd#1 ← (byte) bitmap_line::yd#10 - // (byte) bitmap_line_xdyi::yd#1 = (byte) bitmap_line::yd#10 // register copy zp ZP_BYTE:7 //SEG1218 [653] call bitmap_line_xdyi //SEG1219 [654] phi from bitmap_line::@13 to bitmap_line_xdyi [phi:bitmap_line::@13->bitmap_line_xdyi] //SEG1220 [654] phi (byte) bitmap_line_xdyi::x1#6 = (byte) bitmap_line_xdyi::x1#1 [phi:bitmap_line::@13->bitmap_line_xdyi#0] -- register_copy @@ -29036,7 +29240,6 @@ bitmap_line_ydxi: { //SEG1267 bitmap_line_ydxi::@1 b1: //SEG1268 [679] (byte) bitmap_plot::x#2 ← (byte) bitmap_line_ydxi::x#3 - // (byte) bitmap_plot::x#2 = (byte) bitmap_line_ydxi::x#3 // register copy reg byte x //SEG1269 [680] (byte) bitmap_plot::y#2 ← (byte) bitmap_line_ydxi::y#3 -- vbuyy=vbuz1 ldy y //SEG1270 [681] call bitmap_plot @@ -29160,7 +29363,6 @@ bitmap_line_ydxd: { //SEG1323 bitmap_line_ydxd::@1 b1: //SEG1324 [709] (byte) bitmap_plot::x#3 ← (byte) bitmap_line_ydxd::x#3 - // (byte) bitmap_plot::x#3 = (byte) bitmap_line_ydxd::x#3 // register copy reg byte x //SEG1325 [710] (byte) bitmap_plot::y#3 ← (byte) bitmap_line_ydxd::y#2 -- vbuyy=vbuz1 ldy y //SEG1326 [711] call bitmap_plot @@ -29205,6 +29407,7 @@ bitmap_line_ydxd: { rts } //SEG1345 bitmap_clear +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = 2 .label y = 4 @@ -29215,7 +29418,6 @@ bitmap_clear: { lda bitmap_plot_xhi sta _3+1 //SEG1347 [722] (byte*~) bitmap_clear::bitmap#5 ← (byte*)(word~) bitmap_clear::$3 - // (byte*~) bitmap_clear::bitmap#5 = (byte*)(word~) bitmap_clear::$3 // register copy zp ZP_WORD:2 //SEG1348 [723] phi from bitmap_clear to bitmap_clear::@1 [phi:bitmap_clear->bitmap_clear::@1] //SEG1349 [723] phi (byte) bitmap_clear::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:bitmap_clear->bitmap_clear::@1#0] -- vbuz1=vbuc1 lda #0 @@ -29261,6 +29463,7 @@ bitmap_clear: { rts } //SEG1371 bitmap_init +// Initialize the bitmap plotter tables for a specific bitmap bitmap_init: { .label _6 = 4 .label yoffs = 2 @@ -29361,6 +29564,18 @@ bitmap_init: { //SEG1417 [740] phi (byte) bitmap_init::bits#4 = (byte) bitmap_init::bits#1 [phi:bitmap_init::@10->bitmap_init::@2#0] -- register_copy } //SEG1418 mode_mcchar +// Multicolor Character Mode (LINEAR/HICOL/CHUNK/COLDIS/BMM/ECM = 0, MCM = 1) +// Resolution: 160x200 (320x200) +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & CharData[7:0] & RowCounter[2:0] ) +// GfxData Pixel Shifter (1) if ColorData[3:3] = 0: +// - 0: 4bpp BgColor0[3:0] +// - 1: 4bpp ColorData[2:0] +// GfxData Pixel Shifter (2) if ColorData[3:3] = 1: +// - 00: 4bpp BgColor0[3:0] +// - 01: 4bpp BgColor1[3:0] +// - 10: 4bpp BgColor2[3:0] +// - 11: 4bpp ColorData[2:0]// Standard Character Mode (LINEAR/HICOL/CHUNK/COLDIS/ECM/MCM/BMM = 0) mode_mcchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -29515,6 +29730,17 @@ mode_mcchar: { rts } //SEG1481 mode_ecmchar +// Extended Background Color Character Mode (LINEAR/HICOL/CHUNK/COLDIS/MCM/BMM = 0, ECM = 1) +// Resolution: 320x200 +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & "00" & CharData[5:0] & RowCounter[2:0] ) +// GfxData Pixel Shifter (1) +// - 0: 4bpp Background Color +// - CharData[7:6] 00: 4bpp BgColor0[3:0] +// - CharData[7:6] 01: 4bpp BgColor1[3:0] +// - CharData[7:6] 10: 4bpp BgColor2[3:0] +// - CharData[7:6] 11: 4bpp BgColor3[3:0] +// - 1: 4bpp ColorData[3:0] mode_ecmchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -29671,6 +29897,13 @@ mode_ecmchar: { rts } //SEG1545 mode_stdchar +// Standard Character Mode (LINEAR/HICOL/CHUNK/COLDIS/ECM/MCM/BMM = 0) +// Resolution: 320x200 +// Normal VIC Adressing: +// VicGfxData[16]: ( VicBank[1:0] & CharBase[2:0] & CharData[7:0] & RowCounter[2:0] ) +// Pixel Shifter (1) +// - 0: 4bpp BgColor0[3:0] +// - 1: 4bpp ColorData[3:0] mode_stdchar: { .label SCREEN = $8000 .label CHARSET = $9000 @@ -29818,6 +30051,8 @@ mode_stdchar: { rts } //SEG1606 print_str_lines +// Print a number of zero-terminated strings, each followed by a newline. +// The sequence of lines is terminated by another zero. print_str_lines: { .label str = 2 //SEG1607 [866] phi from print_str_lines to print_str_lines::@1 [phi:print_str_lines->print_str_lines::@1] @@ -29895,6 +30130,7 @@ print_str_lines: { jmp b1 } //SEG1638 print_ln +// Print a newline print_ln: { //SEG1639 [881] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] //SEG1640 [881] phi (byte*) print_line_cursor#18 = (byte*) print_line_cursor#17 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy @@ -29922,6 +30158,7 @@ print_ln: { rts } //SEG1646 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG1647 [886] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -29955,6 +30192,7 @@ print_cls: { rts } //SEG1657 print_set_screen +// Set the screen to print on. Also resets current line/char cursor. print_set_screen: { //SEG1658 print_set_screen::@return //SEG1659 [892] return diff --git a/src/test/ref/cast-deref.asm b/src/test/ref/cast-deref.asm index 66b88eecf..ea12bf535 100644 --- a/src/test/ref/cast-deref.asm +++ b/src/test/ref/cast-deref.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Example of NOP-casting a dereferenced signed byte to a byte main: { .label SCREEN = $400 ldx #0 diff --git a/src/test/ref/cast-deref.log b/src/test/ref/cast-deref.log index d7eb9e318..62fbc6b4c 100644 --- a/src/test/ref/cast-deref.log +++ b/src/test/ref/cast-deref.log @@ -160,6 +160,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Example of NOP-casting a dereferenced signed byte to a byte main: { .label SCREEN = $400 .label i = 2 @@ -229,6 +230,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Example of NOP-casting a dereferenced signed byte to a byte main: { .label SCREEN = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] @@ -317,6 +319,7 @@ Score: 186 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Example of NOP-casting a dereferenced signed byte to a byte main: { .label SCREEN = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] diff --git a/src/test/ref/cast-precedence-problem.asm b/src/test/ref/cast-precedence-problem.asm index 84e4c463a..787056954 100644 --- a/src/test/ref/cast-precedence-problem.asm +++ b/src/test/ref/cast-precedence-problem.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Tests that casting inside constants in the output handles precedence between cast and + correctly - should generate the following KA-expression ($ff & sumw>>1)+1 main: { .label SCREEN = $400 .const min = $a diff --git a/src/test/ref/cast-precedence-problem.log b/src/test/ref/cast-precedence-problem.log index c3e1c4638..b98653c2e 100644 --- a/src/test/ref/cast-precedence-problem.log +++ b/src/test/ref/cast-precedence-problem.log @@ -189,6 +189,7 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Tests that casting inside constants in the output handles precedence between cast and + correctly - should generate the following KA-expression ($ff & sumw>>1)+1 main: { .label SCREEN = $400 .const min = $a @@ -262,6 +263,7 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Tests that casting inside constants in the output handles precedence between cast and + correctly - should generate the following KA-expression ($ff & sumw>>1)+1 main: { .label SCREEN = $400 .const min = $a @@ -361,6 +363,7 @@ Score: 43 //SEG6 [3] phi from @1 to @end [phi:@1->@end] //SEG7 @end //SEG8 main +// Tests that casting inside constants in the output handles precedence between cast and + correctly - should generate the following KA-expression ($ff & sumw>>1)+1 main: { .label SCREEN = $400 .const min = $a diff --git a/src/test/ref/chessboard.asm b/src/test/ref/chessboard.asm index f0957dc5d..0ff3a26ee 100644 --- a/src/test/ref/chessboard.asm +++ b/src/test/ref/chessboard.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Draws a chess board in the upper left corner of the screen main: { .label screen = 2 .label colors = 4 diff --git a/src/test/ref/chessboard.log b/src/test/ref/chessboard.log index 9769c5144..e261ef744 100644 --- a/src/test/ref/chessboard.log +++ b/src/test/ref/chessboard.log @@ -268,6 +268,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Draws a chess board in the upper left corner of the screen main: { .label color = 8 .label column = 7 @@ -424,6 +425,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Draws a chess board in the upper left corner of the screen main: { .label screen = 2 .label colors = 4 @@ -601,6 +603,7 @@ Score: 3861 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Draws a chess board in the upper left corner of the screen main: { .label screen = 2 .label colors = 4 diff --git a/src/test/ref/complex/tetris/test-sprites.asm b/src/test/ref/complex/tetris/test-sprites.asm index 0f4f86bdd..b4886ebb7 100644 --- a/src/test/ref/complex/tetris/test-sprites.asm +++ b/src/test/ref/complex/tetris/test-sprites.asm @@ -135,6 +135,7 @@ loop: { inc sin_idx jmp b4 } +// Setup the IRQ sprites_irq_init: { sei lda #IRQ_RASTER @@ -160,6 +161,7 @@ sprites_irq_init: { cli rts } +// Setup the sprites sprites_init: { .label xpos = 2 lda #$f @@ -188,6 +190,9 @@ sprites_init: { bne b1 rts } +// Raster Interrupt Routine - sets up the sprites covering the playfield +// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST +// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers sprites_irq: { .const toSpritePtr2_return = PLAYFIELD_SPRITES>>6 .label raster_sprite_gfx_modify = $a diff --git a/src/test/ref/complex/tetris/test-sprites.log b/src/test/ref/complex/tetris/test-sprites.log index 81fc8286c..a1de53f2c 100644 --- a/src/test/ref/complex/tetris/test-sprites.log +++ b/src/test/ref/complex/tetris/test-sprites.log @@ -2504,6 +2504,7 @@ loop: { jmp b1 } //SEG92 sprites_irq_init +// Setup the IRQ sprites_irq_init: { //SEG93 asm { sei } sei @@ -2545,6 +2546,7 @@ sprites_irq_init: { rts } //SEG106 sprites_init +// Setup the sprites sprites_init: { .label s2 = $13 .label xpos = 9 @@ -2607,6 +2609,9 @@ sprites_init: { rts } //SEG126 sprites_irq +// Raster Interrupt Routine - sets up the sprites covering the playfield +// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST +// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers sprites_irq: { .const toSpritePtr2_return = PLAYFIELD_SPRITES>>6 .label _0 = $15 @@ -3377,6 +3382,7 @@ loop: { jmp b1 } //SEG92 sprites_irq_init +// Setup the IRQ sprites_irq_init: { //SEG93 asm { sei } sei @@ -3418,6 +3424,7 @@ sprites_irq_init: { rts } //SEG106 sprites_init +// Setup the sprites sprites_init: { .label xpos = 2 //SEG107 [61] *((const byte*) SPRITES_ENABLE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 15 -- _deref_pbuc1=vbuc2 @@ -3474,6 +3481,9 @@ sprites_init: { rts } //SEG126 sprites_irq +// Raster Interrupt Routine - sets up the sprites covering the playfield +// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST +// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers sprites_irq: { .const toSpritePtr2_return = PLAYFIELD_SPRITES>>6 .label raster_sprite_gfx_modify = $a @@ -4333,6 +4343,7 @@ loop: { jmp b4 } //SEG92 sprites_irq_init +// Setup the IRQ sprites_irq_init: { //SEG93 asm { sei } sei @@ -4372,6 +4383,7 @@ sprites_irq_init: { rts } //SEG106 sprites_init +// Setup the sprites sprites_init: { .label xpos = 2 //SEG107 [61] *((const byte*) SPRITES_ENABLE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 15 -- _deref_pbuc1=vbuc2 @@ -4420,6 +4432,9 @@ sprites_init: { rts } //SEG126 sprites_irq +// Raster Interrupt Routine - sets up the sprites covering the playfield +// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST +// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers sprites_irq: { .const toSpritePtr2_return = PLAYFIELD_SPRITES>>6 .label raster_sprite_gfx_modify = $a diff --git a/src/test/ref/complex/tetris/tetris.asm b/src/test/ref/complex/tetris/tetris.asm index 8e547eca7..3ab415229 100644 --- a/src/test/ref/complex/tetris/tetris.asm +++ b/src/test/ref/complex/tetris/tetris.asm @@ -220,6 +220,7 @@ main: { jsr render_screen_swap jmp b4 } +// Swap rendering to the other screen (used for double buffering) render_screen_swap: { lda render_screen_render eor #$40 @@ -229,6 +230,7 @@ render_screen_swap: { sta render_screen_show rts } +// Show the current score render_score: { .label score_bytes = score_bcd .const score_offset = $28*5+$1c @@ -295,6 +297,11 @@ render_score: { jsr render_bcd rts } +// Render BCD digits on a screen. +// - screen: pointer to the screen to render on +// - offset: offset on the screen +// - bcd: The BCD-value to render +// - only_low: if non-zero only renders the low digit render_bcd: { .const ZERO_CHAR = $35 .label screen = 5 @@ -335,6 +342,7 @@ render_bcd: { !: rts } +// Render the next tetromino in the "next" area render_next: { .const next_area_offset = $28*$c+$18+4 .label next_piece_char = $a @@ -405,6 +413,8 @@ render_next: { sta (screen_next_area),y jmp b6 } +// Render the current moving piece at position (current_xpos, current_ypos) +// Ignores cases where parts of the tetromino is outside the playfield (sides/bottom) since the movement collision routine prevents this. render_moving: { .label ypos2 = $b .label screen_line = 7 @@ -468,6 +478,7 @@ render_moving: { bne b4 jmp b3 } +// Render the static playfield on the screen (all pieces already locked into place) render_playfield: { .label screen_line = 5 .label i = $a @@ -510,6 +521,9 @@ render_playfield: { bne b1 rts } +// Perform any movement of the current piece +// key_event is the next keyboard_event() og $ff if no keyboard event is pending +// Returns a byte signaling whether rendering is needed. (0 no render, >0 render needed) play_movement: { .label render = 9 .label return = 9 @@ -538,6 +552,8 @@ play_movement: { sta return jmp breturn } +// Rotate the current piece based on key-presses +// Return non-zero if a render is needed play_move_rotate: { .label orientation = $a cmp #KEY_Z @@ -585,6 +601,8 @@ play_move_rotate: { sta orientation jmp b4 } +// Test if there is a collision between the current piece moved to (x, y) and anything on the playfield or the playfield boundaries +// Returns information about the type of the collision detected play_collision: { .label xpos = $c .label ypos = $b @@ -676,6 +694,8 @@ play_collision: { sta i_13 jmp b2 } +// Move left/right or rotate the current piece +// Return non-zero if a render is needed play_move_leftright: { cmp #KEY_COMMA beq b1 @@ -719,6 +739,8 @@ play_move_leftright: { dec current_xpos jmp b2 } +// Move down the current piece +// Return non-zero if a render is needed play_move_down: { inc current_movedown_counter cmp #KEY_SPACE @@ -784,6 +806,8 @@ play_move_down: { inc current_ypos jmp b7 } +// Spawn a new piece +// Moves the next piece into the current and spawns a new next piece play_spawn_current: { .label _0 = 4 .label piece_idx = $21 @@ -830,10 +854,13 @@ play_spawn_current: { sta piece_idx jmp b2 } +// Get a random number from the SID voice 3, +// Must be initialized with sid_rnd_init() sid_rnd: { lda SID_VOICE3_OSC rts } +// Update the score based on the number of lines removed play_update_score: { .label lines_before = 4 .label add_bcd = $2b @@ -884,6 +911,7 @@ play_update_score: { breturn: rts } +// Increase the level play_increase_level: { inc level lda level @@ -935,6 +963,10 @@ play_increase_level: { cld rts } +// Look through the playfield for lines - and remove any lines found +// Utilizes two cursors on the playfield - one reading cells and one writing cells +// Whenever a full line is detected the writing cursor is instructed to write to the same line once more. +// Returns the number of lines removed play_remove_lines: { .label c = $c .label x = $a @@ -990,6 +1022,7 @@ play_remove_lines: { dex jmp b5 } +// Lock the current piece onto the playfield play_lock_current: { .label ypos2 = $10 .label playfield_line = 5 @@ -1047,6 +1080,8 @@ play_lock_current: { sta i_9 jmp b2 } +// Determine if a specific key is currently pressed based on the last keyboard_event_scan() +// Returns 0 is not pressed and non-0 if pressed keyboard_event_pressed: { .label row_bits = $a .label keycode = 9 @@ -1064,6 +1099,9 @@ keyboard_event_pressed: { and row_bits rts } +// Get the next event from the keyboard event buffer. +// Returns $ff if there is no event waiting. As all events are <$7f it is enough to examine bit 7 when determining if there is any event to process. +// The buffer is filled by keyboard_event_scan() keyboard_event_get: { lda keyboard_events_size cmp #0 @@ -1078,6 +1116,10 @@ keyboard_event_get: { breturn: rts } +// Scans the entire matrix to determine which keys have been pressed/depressed. +// Generates keyboard events into the event buffer. Events can be read using keyboard_event_get(). +// Handles debounce and only generates events when the status of a key changes. +// Also stores current status of modifiers in keyboard_modifiers. keyboard_event_scan: { .label row_scan = $b .label keycode = $a @@ -1175,6 +1217,11 @@ keyboard_event_scan: { inc keyboard_events_size jmp b5 } +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { lda keyboard_matrix_row_bitmask,x sta CIA1_PORT_A @@ -1182,6 +1229,7 @@ keyboard_matrix_read: { eor #$ff rts } +// Update $D018 to show the current screen (used for double buffering) render_show: { .const toD0181_return = (>(PLAYFIELD_SCREEN_1&$3fff)<<2)|(>PLAYFIELD_CHARSET)>>2&$f .const toD0182_return = (>(PLAYFIELD_SCREEN_2&$3fff)<<2)|(>PLAYFIELD_CHARSET)>>2&$f @@ -1203,6 +1251,7 @@ render_show: { lda #toD0181_return jmp b2 } +// Initialize play data tables play_init: { .label pli = 5 .label idx = 2 @@ -1260,6 +1309,7 @@ play_init: { bne b2 rts } +// Setup the IRQ sprites_irq_init: { sei lda #IRQ_RASTER @@ -1285,6 +1335,7 @@ sprites_irq_init: { cli rts } +// Setup the sprites sprites_init: { .label xpos = 2 lda #$f @@ -1313,6 +1364,7 @@ sprites_init: { bne b1 rts } +// Initialize rendering render_init: { .const vicSelectGfxBank1_toDd001_return = 3^(>PLAYFIELD_CHARSET)>>6 .label li_1 = 5 @@ -1385,6 +1437,8 @@ render_init: { bne b1 rts } +// Copy the original screen data to the passed screen +// Also copies colors to $d800 render_screen_original: { .const SPACE = 0 .label screen = $11 @@ -1476,6 +1530,7 @@ render_screen_original: { bne b1 rts } +// Initialize SID voice 3 for random number generation sid_rnd_init: { lda #<$ffff sta SID_VOICE3_FREQ @@ -1485,6 +1540,9 @@ sid_rnd_init: { sta SID_VOICE3_CONTROL rts } +// Raster Interrupt Routine - sets up the sprites covering the playfield +// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST +// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers sprites_irq: { .const toSpritePtr2_return = PLAYFIELD_SPRITES>>6 .label raster_sprite_gfx_modify = $2f diff --git a/src/test/ref/complex/tetris/tetris.log b/src/test/ref/complex/tetris/tetris.log index 56cb61013..19538b94e 100644 --- a/src/test/ref/complex/tetris/tetris.log +++ b/src/test/ref/complex/tetris/tetris.log @@ -13360,6 +13360,7 @@ main: { jmp b1 } //SEG186 render_screen_swap +// Swap rendering to the other screen (used for double buffering) render_screen_swap: { //SEG187 [70] (byte) render_screen_render#11 ← (byte) render_screen_render#18 ^ (byte/signed byte/word/signed word/dword/signed dword) 64 -- vbuz1=vbuz1_bxor_vbuc1 lda render_screen_render @@ -13376,6 +13377,7 @@ render_screen_swap: { rts } //SEG191 render_score +// Show the current score render_score: { .label score_bytes = score_bcd .const score_offset = $28*5+$1c @@ -13563,6 +13565,11 @@ render_score: { rts } //SEG255 render_bcd +// Render BCD digits on a screen. +// - screen: pointer to the screen to render on +// - offset: offset on the screen +// - bcd: The BCD-value to render +// - only_low: if non-zero only renders the low digit render_bcd: { .const ZERO_CHAR = $35 .label _3 = $81 @@ -13646,6 +13653,7 @@ render_bcd: { rts } //SEG272 render_next +// Render the next tetromino in the "next" area render_next: { .const next_area_offset = $28*$c+$18+4 .label _6 = $87 @@ -13793,6 +13801,8 @@ render_next: { jmp b6 } //SEG319 render_moving +// Render the current moving piece at position (current_xpos, current_ypos) +// Ignores cases where parts of the tetromino is outside the playfield (sides/bottom) since the movement collision routine prevents this. render_moving: { .label _2 = $8a .label ypos2 = $1d @@ -13924,6 +13934,7 @@ render_moving: { jmp b3_from_b5 } //SEG363 render_playfield +// Render the static playfield on the screen (all pieces already locked into place) render_playfield: { .label _2 = $8e .label _3 = $8f @@ -14012,6 +14023,9 @@ render_playfield: { rts } //SEG393 play_movement +// Perform any movement of the current piece +// key_event is the next keyboard_event() og $ff if no keyboard event is pending +// Returns a byte signaling whether rendering is needed. (0 no render, >0 render needed) play_movement: { .label _0 = $92 .label _3 = $95 @@ -14099,6 +14113,8 @@ play_movement: { jmp breturn_from_b7 } //SEG421 play_move_rotate +// Rotate the current piece based on key-presses +// Return non-zero if a render is needed play_move_rotate: { .label _2 = $9a .label _4 = $9d @@ -14220,6 +14236,8 @@ play_move_rotate: { jmp b4_from_b1 } //SEG461 play_collision +// Test if there is a collision between the current piece moved to (x, y) and anything on the playfield or the playfield boundaries +// Returns information about the type of the collision detected play_collision: { .label _7 = $a3 .label xpos = $2f @@ -14406,6 +14424,8 @@ play_collision: { jmp b2 } //SEG519 play_move_leftright +// Move left/right or rotate the current piece +// Return non-zero if a render is needed play_move_leftright: { .label _4 = $a5 .label _8 = $a7 @@ -14534,6 +14554,8 @@ play_move_leftright: { jmp breturn_from_b11 } //SEG565 play_move_down +// Move down the current piece +// Return non-zero if a render is needed play_move_down: { .label _2 = $a9 .label _12 = $ab @@ -14801,6 +14823,8 @@ play_move_down: { jmp b7 } //SEG695 play_spawn_current +// Spawn a new piece +// Moves the next piece into the current and spawns a new next piece play_spawn_current: { .label _0 = $b0 .label _2 = $b2 @@ -14927,6 +14951,8 @@ play_spawn_current: { jmp b1 } //SEG737 sid_rnd +// Get a random number from the SID voice 3, +// Must be initialized with sid_rnd_init() sid_rnd: { .label return = $b5 .label return_2 = $b3 @@ -14940,6 +14966,7 @@ sid_rnd: { rts } //SEG741 play_update_score +// Update the score based on the number of lines removed play_update_score: { .label _2 = $b6 .label _4 = $b8 @@ -15037,6 +15064,7 @@ play_update_score: { rts } //SEG766 play_increase_level +// Increase the level play_increase_level: { .label _1 = $bf .label b4 = $c0 @@ -15145,6 +15173,10 @@ play_increase_level: { rts } //SEG798 play_remove_lines +// Look through the playfield for lines - and remove any lines found +// Utilizes two cursors on the playfield - one reading cells and one writing cells +// Whenever a full line is detected the writing cursor is instructed to write to the same line once more. +// Returns the number of lines removed play_remove_lines: { .label return = $ac .label c = $c1 @@ -15295,6 +15327,7 @@ play_remove_lines: { jmp b3 } //SEG855 play_lock_current +// Lock the current piece onto the playfield play_lock_current: { .label ypos2 = $53 .label playfield_line = $c2 @@ -15411,6 +15444,8 @@ play_lock_current: { jmp b2 } //SEG895 keyboard_event_pressed +// Determine if a specific key is currently pressed based on the last keyboard_event_scan() +// Returns 0 is not pressed and non-0 if pressed keyboard_event_pressed: { .label _0 = $c5 .label _1 = $c7 @@ -15448,6 +15483,9 @@ keyboard_event_pressed: { rts } //SEG902 keyboard_event_get +// Get the next event from the keyboard event buffer. +// Returns $ff if there is no event waiting. As all events are <$7f it is enough to examine bit 7 when determining if there is any event to process. +// The buffer is filled by keyboard_event_scan() keyboard_event_get: { .label return = $59 .label return_3 = $7c @@ -15482,6 +15520,10 @@ keyboard_event_get: { rts } //SEG915 keyboard_event_scan +// Scans the entire matrix to determine which keys have been pressed/depressed. +// Generates keyboard events into the event buffer. Events can be read using keyboard_event_get(). +// Handles debounce and only generates events when the status of a key changes. +// Also stores current status of modifiers in keyboard_modifiers. keyboard_event_scan: { .label _3 = $d5 .label _4 = $d6 @@ -15796,6 +15838,11 @@ keyboard_event_scan: { jmp b5_from_b7 } //SEG1022 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { .label return = $d9 .label rowid = $c9 @@ -15815,6 +15862,7 @@ keyboard_matrix_read: { rts } //SEG1027 render_show +// Update $D018 to show the current screen (used for double buffering) render_show: { .const toD0181_return = (>(PLAYFIELD_SCREEN_1&$3fff)<<2)|(>PLAYFIELD_CHARSET)>>2&$f .const toD0182_return = (>(PLAYFIELD_SCREEN_2&$3fff)<<2)|(>PLAYFIELD_CHARSET)>>2&$f @@ -15868,6 +15916,7 @@ render_show: { jmp b2 } //SEG1044 play_init +// Initialize play data tables play_init: { .label _1 = $db .label pli = $61 @@ -15979,6 +16028,7 @@ play_init: { rts } //SEG1075 sprites_irq_init +// Setup the IRQ sprites_irq_init: { //SEG1076 asm { sei } sei @@ -16020,6 +16070,7 @@ sprites_irq_init: { rts } //SEG1089 sprites_init +// Setup the sprites sprites_init: { .label s2 = $dd .label xpos = $66 @@ -16082,6 +16133,7 @@ sprites_init: { rts } //SEG1109 render_init +// Initialize rendering render_init: { .const vicSelectGfxBank1_toDd001_return = 3^(>PLAYFIELD_CHARSET)>>6 .label _13 = $de @@ -16223,6 +16275,8 @@ render_init: { rts } //SEG1150 render_screen_original +// Copy the original screen data to the passed screen +// Also copies colors to $d800 render_screen_original: { .const SPACE = 0 .label screen = $71 @@ -16399,6 +16453,7 @@ render_screen_original: { rts } //SEG1210 sid_rnd_init +// Initialize SID voice 3 for random number generation sid_rnd_init: { //SEG1211 [552] *((const word*) SID_VOICE3_FREQ#0) ← (word/dword/signed dword) 65535 -- _deref_pwuc1=vwuc2 lda #<$ffff @@ -16415,6 +16470,9 @@ sid_rnd_init: { rts } //SEG1215 sprites_irq +// Raster Interrupt Routine - sets up the sprites covering the playfield +// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST +// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers sprites_irq: { .const toSpritePtr2_return = PLAYFIELD_SPRITES>>6 .label _0 = $e1 @@ -18307,12 +18365,10 @@ main: { //SEG122 [45] call keyboard_event_get jsr keyboard_event_get //SEG123 [46] (byte) keyboard_event_get::return#3 ← (byte) keyboard_event_get::return#2 - // (byte) keyboard_event_get::return#3 = (byte) keyboard_event_get::return#2 // register copy reg byte x jmp b37 //SEG124 main::@37 b37: //SEG125 [47] (byte) main::key_event#0 ← (byte) keyboard_event_get::return#3 - // (byte) main::key_event#0 = (byte) keyboard_event_get::return#3 // register copy reg byte x //SEG126 [48] if((byte) game_over#10==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@7 -- vbuz1_eq_0_then_la1 lda game_over cmp #0 @@ -18335,7 +18391,6 @@ main: { //SEG133 main::@38 b38: //SEG134 [53] (byte) main::render#1 ← (byte) play_movement::return#3 - // (byte) main::render#1 = (byte) play_movement::return#3 // register copy reg byte a jmp b11 //SEG135 main::@11 b11: @@ -18428,6 +18483,7 @@ main: { jmp b1 } //SEG186 render_screen_swap +// Swap rendering to the other screen (used for double buffering) render_screen_swap: { //SEG187 [70] (byte) render_screen_render#11 ← (byte) render_screen_render#18 ^ (byte/signed byte/word/signed word/dword/signed dword) 64 -- vbuz1=vbuz1_bxor_vbuc1 lda render_screen_render @@ -18444,6 +18500,7 @@ render_screen_swap: { rts } //SEG191 render_score +// Show the current score render_score: { .label score_bytes = score_bcd .const score_offset = $28*5+$1c @@ -18478,7 +18535,6 @@ render_score: { //SEG199 render_score::@2 b2: //SEG200 [76] (byte*) render_bcd::screen#0 ← (byte*) render_score::screen#2 - // (byte*) render_bcd::screen#0 = (byte*) render_score::screen#2 // register copy zp ZP_WORD:5 //SEG201 [77] (byte) render_bcd::bcd#0 ← *((const byte*) render_score::score_bytes#0+(byte/signed byte/word/signed word/dword/signed dword) 2) -- vbuxx=_deref_pbuc1 ldx score_bytes+2 //SEG202 [78] call render_bcd @@ -18498,7 +18554,6 @@ render_score: { //SEG208 render_score::@5 b5: //SEG209 [79] (byte*) render_bcd::screen#1 ← (byte*) render_score::screen#2 - // (byte*) render_bcd::screen#1 = (byte*) render_score::screen#2 // register copy zp ZP_WORD:5 //SEG210 [80] (byte) render_bcd::bcd#1 ← *((const byte*) render_score::score_bytes#0+(byte/signed byte/word/signed word/dword/signed dword) 1) -- vbuxx=_deref_pbuc1 ldx score_bytes+1 //SEG211 [81] call render_bcd @@ -18518,7 +18573,6 @@ render_score: { //SEG217 render_score::@6 b6: //SEG218 [82] (byte*) render_bcd::screen#2 ← (byte*) render_score::screen#2 - // (byte*) render_bcd::screen#2 = (byte*) render_score::screen#2 // register copy zp ZP_WORD:5 //SEG219 [83] (byte) render_bcd::bcd#2 ← *((const byte*) render_score::score_bytes#0) -- vbuxx=_deref_pbuc1 ldx score_bytes //SEG220 [84] call render_bcd @@ -18541,7 +18595,6 @@ render_score: { lda lines_bcd+1 tax //SEG228 [86] (byte*) render_bcd::screen#3 ← (byte*) render_score::screen#2 - // (byte*) render_bcd::screen#3 = (byte*) render_score::screen#2 // register copy zp ZP_WORD:5 //SEG229 [87] call render_bcd //SEG230 [95] phi from render_score::@7 to render_bcd [phi:render_score::@7->render_bcd] render_bcd_from_b7: @@ -18562,7 +18615,6 @@ render_score: { lda lines_bcd tax //SEG237 [89] (byte*) render_bcd::screen#4 ← (byte*) render_score::screen#2 - // (byte*) render_bcd::screen#4 = (byte*) render_score::screen#2 // register copy zp ZP_WORD:5 //SEG238 [90] call render_bcd //SEG239 [95] phi from render_score::@8 to render_bcd [phi:render_score::@8->render_bcd] render_bcd_from_b8: @@ -18580,7 +18632,6 @@ render_score: { //SEG244 render_score::@9 b9: //SEG245 [91] (byte*) render_bcd::screen#5 ← (byte*) render_score::screen#2 - // (byte*) render_bcd::screen#5 = (byte*) render_score::screen#2 // register copy zp ZP_WORD:5 //SEG246 [92] (byte) render_bcd::bcd#5 ← (byte) level_bcd#17 -- vbuxx=vbuz1 ldx level_bcd //SEG247 [93] call render_bcd @@ -18603,6 +18654,11 @@ render_score: { rts } //SEG255 render_bcd +// Render BCD digits on a screen. +// - screen: pointer to the screen to render on +// - offset: offset on the screen +// - bcd: The BCD-value to render +// - only_low: if non-zero only renders the low digit render_bcd: { .const ZERO_CHAR = $35 .label screen = 5 @@ -18667,6 +18723,7 @@ render_bcd: { rts } //SEG272 render_next +// Render the next tetromino in the "next" area render_next: { .const next_area_offset = $28*$c+$18+4 .label next_piece_char = $a @@ -18804,6 +18861,8 @@ render_next: { jmp b6 } //SEG319 render_moving +// Render the current moving piece at position (current_xpos, current_ypos) +// Ignores cases where parts of the tetromino is outside the playfield (sides/bottom) since the movement collision routine prevents this. render_moving: { .label ypos2 = $b .label screen_line = 7 @@ -18930,6 +18989,7 @@ render_moving: { jmp b3_from_b5 } //SEG363 render_playfield +// Render the static playfield on the screen (all pieces already locked into place) render_playfield: { .label screen_line = 5 .label i = $a @@ -19014,6 +19074,9 @@ render_playfield: { rts } //SEG393 play_movement +// Perform any movement of the current piece +// key_event is the next keyboard_event() og $ff if no keyboard event is pending +// Returns a byte signaling whether rendering is needed. (0 no render, >0 render needed) play_movement: { .label render = 9 .label return = 9 @@ -19028,7 +19091,6 @@ play_movement: { //SEG397 play_movement::@5 b5: //SEG398 [167] (byte~) play_movement::$0 ← (byte) play_move_down::return#0 - // (byte~) play_movement::$0 = (byte) play_move_down::return#0 // register copy reg byte a //SEG399 [168] (byte) play_movement::render#1 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + (byte~) play_movement::$0 -- vbuz1=vbuc1_plus_vbuaa clc adc #0 @@ -19056,12 +19118,10 @@ play_movement: { //SEG410 [173] call play_move_leftright jsr play_move_leftright //SEG411 [174] (byte) play_move_leftright::return#0 ← (byte) play_move_leftright::return#2 - // (byte) play_move_leftright::return#0 = (byte) play_move_leftright::return#2 // register copy reg byte a jmp b6 //SEG412 play_movement::@6 b6: //SEG413 [175] (byte~) play_movement::$3 ← (byte) play_move_leftright::return#0 - // (byte~) play_movement::$3 = (byte) play_move_leftright::return#0 // register copy reg byte a //SEG414 [176] (byte) play_movement::render#2 ← (byte) play_movement::render#1 + (byte~) play_movement::$3 -- vbuz1=vbuz1_plus_vbuaa clc adc render @@ -19071,12 +19131,10 @@ play_movement: { //SEG416 [178] call play_move_rotate jsr play_move_rotate //SEG417 [179] (byte) play_move_rotate::return#0 ← (byte) play_move_rotate::return#2 - // (byte) play_move_rotate::return#0 = (byte) play_move_rotate::return#2 // register copy reg byte a jmp b7 //SEG418 play_movement::@7 b7: //SEG419 [180] (byte~) play_movement::$4 ← (byte) play_move_rotate::return#0 - // (byte~) play_movement::$4 = (byte) play_move_rotate::return#0 // register copy reg byte a //SEG420 [181] (byte) play_movement::return#0 ← (byte) play_movement::render#2 + (byte~) play_movement::$4 -- vbuz1=vbuz1_plus_vbuaa clc adc return @@ -19084,6 +19142,8 @@ play_movement: { jmp breturn_from_b7 } //SEG421 play_move_rotate +// Rotate the current piece based on key-presses +// Return non-zero if a render is needed play_move_rotate: { .label orientation = $a //SEG422 [182] if((byte) play_move_rotate::key_event#0==(const byte) KEY_Z#0) goto play_move_rotate::@1 -- vbuaa_eq_vbuc1_then_la1 @@ -19145,12 +19205,10 @@ play_move_rotate: { //SEG446 [201] phi (byte*) current_piece#17 = (byte*~) current_piece#101 [phi:play_move_rotate::@4->play_collision#3] -- register_copy jsr play_collision //SEG447 [194] (byte) play_collision::return#14 ← (byte) play_collision::return#15 - // (byte) play_collision::return#14 = (byte) play_collision::return#15 // register copy reg byte a jmp b14 //SEG448 play_move_rotate::@14 b14: //SEG449 [195] (byte~) play_move_rotate::$6 ← (byte) play_collision::return#14 - // (byte~) play_move_rotate::$6 = (byte) play_collision::return#14 // register copy reg byte a //SEG450 [196] if((byte~) play_move_rotate::$6!=(const byte) COLLISION_NONE#0) goto play_move_rotate::@return -- vbuaa_neq_vbuc1_then_la1 cmp #COLLISION_NONE bne breturn_from_b14 @@ -19187,6 +19245,8 @@ play_move_rotate: { jmp b4_from_b1 } //SEG461 play_collision +// Test if there is a collision between the current piece moved to (x, y) and anything on the playfield or the playfield boundaries +// Returns information about the type of the collision detected play_collision: { .label xpos = $c .label ypos = $b @@ -19353,6 +19413,8 @@ play_collision: { jmp b2 } //SEG519 play_move_leftright +// Move left/right or rotate the current piece +// Return non-zero if a render is needed play_move_leftright: { //SEG520 [225] if((byte) play_move_leftright::key_event#0==(const byte) KEY_COMMA#0) goto play_move_leftright::@1 -- vbuaa_eq_vbuc1_then_la1 cmp #KEY_COMMA @@ -19389,12 +19451,10 @@ play_move_leftright: { //SEG533 [201] phi (byte*) current_piece#17 = (byte*~) current_piece#100 [phi:play_move_leftright::@7->play_collision#3] -- register_copy jsr play_collision //SEG534 [232] (byte) play_collision::return#13 ← (byte) play_collision::return#15 - // (byte) play_collision::return#13 = (byte) play_collision::return#15 // register copy reg byte a jmp b15 //SEG535 play_move_leftright::@15 b15: //SEG536 [233] (byte~) play_move_leftright::$4 ← (byte) play_collision::return#13 - // (byte~) play_move_leftright::$4 = (byte) play_collision::return#13 // register copy reg byte a //SEG537 [234] if((byte~) play_move_leftright::$4!=(const byte) COLLISION_NONE#0) goto play_move_leftright::@return -- vbuaa_neq_vbuc1_then_la1 cmp #COLLISION_NONE bne breturn_from_b15 @@ -19447,12 +19507,10 @@ play_move_leftright: { //SEG558 [201] phi (byte*) current_piece#17 = (byte*~) current_piece#99 [phi:play_move_leftright::@1->play_collision#3] -- register_copy jsr play_collision //SEG559 [243] (byte) play_collision::return#1 ← (byte) play_collision::return#15 - // (byte) play_collision::return#1 = (byte) play_collision::return#15 // register copy reg byte a jmp b14 //SEG560 play_move_leftright::@14 b14: //SEG561 [244] (byte~) play_move_leftright::$8 ← (byte) play_collision::return#1 - // (byte~) play_move_leftright::$8 = (byte) play_collision::return#1 // register copy reg byte a //SEG562 [245] if((byte~) play_move_leftright::$8!=(const byte) COLLISION_NONE#0) goto play_move_leftright::@return -- vbuaa_neq_vbuc1_then_la1 cmp #COLLISION_NONE bne breturn_from_b14 @@ -19464,6 +19522,8 @@ play_move_leftright: { jmp breturn_from_b11 } //SEG565 play_move_down +// Move down the current piece +// Return non-zero if a render is needed play_move_down: { //SEG566 [247] (byte) current_movedown_counter#12 ← ++ (byte) current_movedown_counter#16 -- vbuz1=_inc_vbuz1 inc current_movedown_counter @@ -19495,12 +19555,10 @@ play_move_down: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG578 [252] (byte) keyboard_event_pressed::return#12 ← (byte) keyboard_event_pressed::return#11 - // (byte) keyboard_event_pressed::return#12 = (byte) keyboard_event_pressed::return#11 // register copy reg byte a jmp b17 //SEG579 play_move_down::@17 b17: //SEG580 [253] (byte~) play_move_down::$2 ← (byte) keyboard_event_pressed::return#12 - // (byte~) play_move_down::$2 = (byte) keyboard_event_pressed::return#12 // register copy reg byte a //SEG581 [254] if((byte~) play_move_down::$2==(byte/signed byte/word/signed word/dword/signed dword) 0) goto play_move_down::@2 -- vbuaa_eq_0_then_la1 cmp #0 beq b2_from_b17 @@ -19569,12 +19627,10 @@ play_move_down: { //SEG606 [201] phi (byte*) current_piece#17 = (byte*~) current_piece#98 [phi:play_move_down::@12->play_collision#3] -- register_copy jsr play_collision //SEG607 [267] (byte) play_collision::return#0 ← (byte) play_collision::return#15 - // (byte) play_collision::return#0 = (byte) play_collision::return#15 // register copy reg byte a jmp b18 //SEG608 play_move_down::@18 b18: //SEG609 [268] (byte~) play_move_down::$12 ← (byte) play_collision::return#0 - // (byte~) play_move_down::$12 = (byte) play_collision::return#0 // register copy reg byte a //SEG610 [269] if((byte~) play_move_down::$12==(const byte) COLLISION_NONE#0) goto play_move_down::@6 -- vbuaa_eq_vbuc1_then_la1 cmp #COLLISION_NONE beq b6 @@ -19600,7 +19656,6 @@ play_move_down: { //SEG619 play_move_down::@20 b20: //SEG620 [275] (byte) play_move_down::removed#0 ← (byte) play_remove_lines::return#0 - // (byte) play_move_down::removed#0 = (byte) play_remove_lines::return#0 // register copy reg byte a //SEG621 [276] (byte) play_update_score::removed#0 ← (byte) play_move_down::removed#0 -- vbuxx=vbuaa tax //SEG622 [277] call play_update_score @@ -19708,6 +19763,8 @@ play_move_down: { jmp b7 } //SEG695 play_spawn_current +// Spawn a new piece +// Moves the next piece into the current and spawns a new next piece play_spawn_current: { .label _0 = 4 .label piece_idx = $21 @@ -19754,12 +19811,10 @@ play_spawn_current: { //SEG710 [201] phi (byte*) current_piece#17 = (byte*~) current_piece#102 [phi:play_spawn_current->play_collision#3] -- register_copy jsr play_collision //SEG711 [296] (byte) play_collision::return#10 ← (byte) play_collision::return#15 - // (byte) play_collision::return#10 = (byte) play_collision::return#15 // register copy reg byte a jmp b9 //SEG712 play_spawn_current::@9 b9: //SEG713 [297] (byte~) play_spawn_current::$2 ← (byte) play_collision::return#10 - // (byte~) play_spawn_current::$2 = (byte) play_collision::return#10 // register copy reg byte a //SEG714 [298] if((byte~) play_spawn_current::$2!=(const byte) COLLISION_PLAYFIELD#0) goto play_spawn_current::@11 -- vbuaa_neq_vbuc1_then_la1 cmp #COLLISION_PLAYFIELD bne b11_from_b9 @@ -19796,12 +19851,10 @@ play_spawn_current: { //SEG726 [304] call sid_rnd jsr sid_rnd //SEG727 [305] (byte) sid_rnd::return#2 ← (byte) sid_rnd::return#0 - // (byte) sid_rnd::return#2 = (byte) sid_rnd::return#0 // register copy reg byte a jmp b10 //SEG728 play_spawn_current::@10 b10: //SEG729 [306] (byte~) play_spawn_current::$6 ← (byte) sid_rnd::return#2 - // (byte~) play_spawn_current::$6 = (byte) sid_rnd::return#2 // register copy reg byte a //SEG730 [307] (byte) play_spawn_current::piece_idx#1 ← (byte~) play_spawn_current::$6 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuz1=vbuaa_band_vbuc1 and #7 sta piece_idx @@ -19820,6 +19873,8 @@ play_spawn_current: { jmp b1 } //SEG737 sid_rnd +// Get a random number from the SID voice 3, +// Must be initialized with sid_rnd_init() sid_rnd: { //SEG738 [309] (byte) sid_rnd::return#0 ← *((const byte*) SID_VOICE3_OSC#0) -- vbuaa=_deref_pbuc1 lda SID_VOICE3_OSC @@ -19830,6 +19885,7 @@ sid_rnd: { rts } //SEG741 play_update_score +// Update the score based on the number of lines removed play_update_score: { .label lines_before = 4 .label add_bcd = $2b @@ -19914,6 +19970,7 @@ play_update_score: { rts } //SEG766 play_increase_level +// Increase the level play_increase_level: { //SEG767 [327] (byte) level#21 ← ++ (byte) level#10 -- vbuz1=_inc_vbuz1 inc level @@ -20014,6 +20071,10 @@ play_increase_level: { rts } //SEG798 play_remove_lines +// Look through the playfield for lines - and remove any lines found +// Utilizes two cursors on the playfield - one reading cells and one writing cells +// Whenever a full line is detected the writing cursor is instructed to write to the same line once more. +// Returns the number of lines removed play_remove_lines: { .label c = $c .label x = $a @@ -20155,6 +20216,7 @@ play_remove_lines: { jmp b3 } //SEG855 play_lock_current +// Lock the current piece onto the playfield play_lock_current: { .label ypos2 = $10 .label playfield_line = 5 @@ -20266,6 +20328,8 @@ play_lock_current: { jmp b2 } //SEG895 keyboard_event_pressed +// Determine if a specific key is currently pressed based on the last keyboard_event_scan() +// Returns 0 is not pressed and non-0 if pressed keyboard_event_pressed: { .label row_bits = $a .label keycode = 9 @@ -20292,6 +20356,9 @@ keyboard_event_pressed: { rts } //SEG902 keyboard_event_get +// Get the next event from the keyboard event buffer. +// Returns $ff if there is no event waiting. As all events are <$7f it is enough to examine bit 7 when determining if there is any event to process. +// The buffer is filled by keyboard_event_scan() keyboard_event_get: { //SEG903 [390] if((byte) keyboard_events_size#13==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_get::@return -- vbuz1_eq_0_then_la1 lda keyboard_events_size @@ -20323,6 +20390,10 @@ keyboard_event_get: { rts } //SEG915 keyboard_event_scan +// Scans the entire matrix to determine which keys have been pressed/depressed. +// Generates keyboard events into the event buffer. Events can be read using keyboard_event_get(). +// Handles debounce and only generates events when the status of a key changes. +// Also stores current status of modifiers in keyboard_modifiers. keyboard_event_scan: { .label row_scan = $b .label keycode = $a @@ -20350,7 +20421,6 @@ keyboard_event_scan: { //SEG926 [398] call keyboard_matrix_read jsr keyboard_matrix_read //SEG927 [399] (byte) keyboard_matrix_read::return#2 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#2 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a jmp b25 //SEG928 keyboard_event_scan::@25 b25: @@ -20396,12 +20466,10 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG944 [408] (byte) keyboard_event_pressed::return#0 ← (byte) keyboard_event_pressed::return#11 - // (byte) keyboard_event_pressed::return#0 = (byte) keyboard_event_pressed::return#11 // register copy reg byte a jmp b26 //SEG945 keyboard_event_scan::@26 b26: //SEG946 [409] (byte~) keyboard_event_scan::$14 ← (byte) keyboard_event_pressed::return#0 - // (byte~) keyboard_event_scan::$14 = (byte) keyboard_event_pressed::return#0 // register copy reg byte a //SEG947 [410] if((byte~) keyboard_event_scan::$14==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@9 -- vbuaa_eq_0_then_la1 cmp #0 beq b9_from_b26 @@ -20430,12 +20498,10 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG958 [414] (byte) keyboard_event_pressed::return#1 ← (byte) keyboard_event_pressed::return#11 - // (byte) keyboard_event_pressed::return#1 = (byte) keyboard_event_pressed::return#11 // register copy reg byte a jmp b27 //SEG959 keyboard_event_scan::@27 b27: //SEG960 [415] (byte~) keyboard_event_scan::$18 ← (byte) keyboard_event_pressed::return#1 - // (byte~) keyboard_event_scan::$18 = (byte) keyboard_event_pressed::return#1 // register copy reg byte a //SEG961 [416] if((byte~) keyboard_event_scan::$18==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@10 -- vbuaa_eq_0_then_la1 cmp #0 beq b10_from_b27 @@ -20461,12 +20527,10 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG970 [420] (byte) keyboard_event_pressed::return#2 ← (byte) keyboard_event_pressed::return#11 - // (byte) keyboard_event_pressed::return#2 = (byte) keyboard_event_pressed::return#11 // register copy reg byte a jmp b28 //SEG971 keyboard_event_scan::@28 b28: //SEG972 [421] (byte~) keyboard_event_scan::$22 ← (byte) keyboard_event_pressed::return#2 - // (byte~) keyboard_event_scan::$22 = (byte) keyboard_event_pressed::return#2 // register copy reg byte a //SEG973 [422] if((byte~) keyboard_event_scan::$22==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@11 -- vbuaa_eq_0_then_la1 cmp #0 beq b11_from_b28 @@ -20492,12 +20556,10 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG982 [426] (byte) keyboard_event_pressed::return#10 ← (byte) keyboard_event_pressed::return#11 - // (byte) keyboard_event_pressed::return#10 = (byte) keyboard_event_pressed::return#11 // register copy reg byte a jmp b29 //SEG983 keyboard_event_scan::@29 b29: //SEG984 [427] (byte~) keyboard_event_scan::$26 ← (byte) keyboard_event_pressed::return#10 - // (byte~) keyboard_event_scan::$26 = (byte) keyboard_event_pressed::return#10 // register copy reg byte a //SEG985 [428] if((byte~) keyboard_event_scan::$26==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@return -- vbuaa_eq_0_then_la1 cmp #0 beq breturn @@ -20598,6 +20660,11 @@ keyboard_event_scan: { jmp b5_from_b7 } //SEG1022 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { //SEG1023 [448] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0 + (byte) keyboard_matrix_read::rowid#0) -- _deref_pbuc1=pbuc2_derefidx_vbuxx lda keyboard_matrix_row_bitmask,x @@ -20612,6 +20679,7 @@ keyboard_matrix_read: { rts } //SEG1027 render_show +// Update $D018 to show the current screen (used for double buffering) render_show: { .const toD0181_return = (>(PLAYFIELD_SCREEN_1&$3fff)<<2)|(>PLAYFIELD_CHARSET)>>2&$f .const toD0182_return = (>(PLAYFIELD_SCREEN_2&$3fff)<<2)|(>PLAYFIELD_CHARSET)>>2&$f @@ -20661,6 +20729,7 @@ render_show: { jmp b2 } //SEG1044 play_init +// Initialize play data tables play_init: { .label pli = 5 .label idx = 2 @@ -20761,6 +20830,7 @@ play_init: { rts } //SEG1075 sprites_irq_init +// Setup the IRQ sprites_irq_init: { //SEG1076 asm { sei } sei @@ -20802,6 +20872,7 @@ sprites_irq_init: { rts } //SEG1089 sprites_init +// Setup the sprites sprites_init: { .label xpos = 2 //SEG1090 [489] *((const byte*) SPRITES_ENABLE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 15 -- _deref_pbuc1=vbuc2 @@ -20858,6 +20929,7 @@ sprites_init: { rts } //SEG1109 render_init +// Initialize rendering render_init: { .const vicSelectGfxBank1_toDd001_return = 3^(>PLAYFIELD_CHARSET)>>6 .label li_1 = 5 @@ -20992,6 +21064,8 @@ render_init: { rts } //SEG1150 render_screen_original +// Copy the original screen data to the passed screen +// Also copies colors to $d800 render_screen_original: { .const SPACE = 0 .label screen = $11 @@ -21163,6 +21237,7 @@ render_screen_original: { rts } //SEG1210 sid_rnd_init +// Initialize SID voice 3 for random number generation sid_rnd_init: { //SEG1211 [552] *((const word*) SID_VOICE3_FREQ#0) ← (word/dword/signed dword) 65535 -- _deref_pwuc1=vwuc2 lda #<$ffff @@ -21179,6 +21254,9 @@ sid_rnd_init: { rts } //SEG1215 sprites_irq +// Raster Interrupt Routine - sets up the sprites covering the playfield +// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST +// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers sprites_irq: { .const toSpritePtr2_return = PLAYFIELD_SPRITES>>6 .label raster_sprite_gfx_modify = $2f @@ -21716,6 +21794,7 @@ Removing instruction b6_from_b4: Removing instruction b35_from_b6: Removing instruction keyboard_event_scan_from_b35: Removing instruction b36_from_b35: +Removing instruction b38: Removing instruction b41_from_b40: Removing instruction b42_from_b41: Removing instruction b3_from_render_score: @@ -21841,7 +21920,6 @@ Removing instruction b6: Removing instruction b35: Removing instruction b36: Removing instruction b37: -Removing instruction b38: Removing instruction b11: Removing instruction b23: Removing instruction render_playfield_from_b23: @@ -23692,10 +23770,8 @@ main: { //SEG122 [45] call keyboard_event_get jsr keyboard_event_get //SEG123 [46] (byte) keyboard_event_get::return#3 ← (byte) keyboard_event_get::return#2 - // (byte) keyboard_event_get::return#3 = (byte) keyboard_event_get::return#2 // register copy reg byte x //SEG124 main::@37 //SEG125 [47] (byte) main::key_event#0 ← (byte) keyboard_event_get::return#3 - // (byte) main::key_event#0 = (byte) keyboard_event_get::return#3 // register copy reg byte x //SEG126 [48] if((byte) game_over#10==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@7 -- vbuz1_eq_0_then_la1 lda game_over cmp #0 @@ -23715,7 +23791,6 @@ main: { lda play_movement.return //SEG133 main::@38 //SEG134 [53] (byte) main::render#1 ← (byte) play_movement::return#3 - // (byte) main::render#1 = (byte) play_movement::return#3 // register copy reg byte a //SEG135 main::@11 //SEG136 [54] if((byte) main::render#1==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@1 -- vbuaa_eq_0_then_la1 cmp #0 @@ -23790,6 +23865,7 @@ main: { jmp b4 } //SEG186 render_screen_swap +// Swap rendering to the other screen (used for double buffering) render_screen_swap: { //SEG187 [70] (byte) render_screen_render#11 ← (byte) render_screen_render#18 ^ (byte/signed byte/word/signed word/dword/signed dword) 64 -- vbuz1=vbuz1_bxor_vbuc1 lda render_screen_render @@ -23804,6 +23880,7 @@ render_screen_swap: { rts } //SEG191 render_score +// Show the current score render_score: { .label score_bytes = score_bcd .const score_offset = $28*5+$1c @@ -23833,7 +23910,6 @@ render_score: { //SEG199 render_score::@2 b2: //SEG200 [76] (byte*) render_bcd::screen#0 ← (byte*) render_score::screen#2 - // (byte*) render_bcd::screen#0 = (byte*) render_score::screen#2 // register copy zp ZP_WORD:5 //SEG201 [77] (byte) render_bcd::bcd#0 ← *((const byte*) render_score::score_bytes#0+(byte/signed byte/word/signed word/dword/signed dword) 2) -- vbuxx=_deref_pbuc1 ldx score_bytes+2 //SEG202 [78] call render_bcd @@ -23850,7 +23926,6 @@ render_score: { jsr render_bcd //SEG208 render_score::@5 //SEG209 [79] (byte*) render_bcd::screen#1 ← (byte*) render_score::screen#2 - // (byte*) render_bcd::screen#1 = (byte*) render_score::screen#2 // register copy zp ZP_WORD:5 //SEG210 [80] (byte) render_bcd::bcd#1 ← *((const byte*) render_score::score_bytes#0+(byte/signed byte/word/signed word/dword/signed dword) 1) -- vbuxx=_deref_pbuc1 ldx score_bytes+1 //SEG211 [81] call render_bcd @@ -23867,7 +23942,6 @@ render_score: { jsr render_bcd //SEG217 render_score::@6 //SEG218 [82] (byte*) render_bcd::screen#2 ← (byte*) render_score::screen#2 - // (byte*) render_bcd::screen#2 = (byte*) render_score::screen#2 // register copy zp ZP_WORD:5 //SEG219 [83] (byte) render_bcd::bcd#2 ← *((const byte*) render_score::score_bytes#0) -- vbuxx=_deref_pbuc1 ldx score_bytes //SEG220 [84] call render_bcd @@ -23887,7 +23961,6 @@ render_score: { lda lines_bcd+1 tax //SEG228 [86] (byte*) render_bcd::screen#3 ← (byte*) render_score::screen#2 - // (byte*) render_bcd::screen#3 = (byte*) render_score::screen#2 // register copy zp ZP_WORD:5 //SEG229 [87] call render_bcd //SEG230 [95] phi from render_score::@7 to render_bcd [phi:render_score::@7->render_bcd] //SEG231 [95] phi (byte) render_bcd::bcd#6 = (byte) render_bcd::bcd#3 [phi:render_score::@7->render_bcd#0] -- register_copy @@ -23905,7 +23978,6 @@ render_score: { lda lines_bcd tax //SEG237 [89] (byte*) render_bcd::screen#4 ← (byte*) render_score::screen#2 - // (byte*) render_bcd::screen#4 = (byte*) render_score::screen#2 // register copy zp ZP_WORD:5 //SEG238 [90] call render_bcd //SEG239 [95] phi from render_score::@8 to render_bcd [phi:render_score::@8->render_bcd] //SEG240 [95] phi (byte) render_bcd::bcd#6 = (byte) render_bcd::bcd#4 [phi:render_score::@8->render_bcd#0] -- register_copy @@ -23920,7 +23992,6 @@ render_score: { jsr render_bcd //SEG244 render_score::@9 //SEG245 [91] (byte*) render_bcd::screen#5 ← (byte*) render_score::screen#2 - // (byte*) render_bcd::screen#5 = (byte*) render_score::screen#2 // register copy zp ZP_WORD:5 //SEG246 [92] (byte) render_bcd::bcd#5 ← (byte) level_bcd#17 -- vbuxx=vbuz1 ldx level_bcd //SEG247 [93] call render_bcd @@ -23940,6 +24011,11 @@ render_score: { rts } //SEG255 render_bcd +// Render BCD digits on a screen. +// - screen: pointer to the screen to render on +// - offset: offset on the screen +// - bcd: The BCD-value to render +// - only_low: if non-zero only renders the low digit render_bcd: { .const ZERO_CHAR = $35 .label screen = 5 @@ -23997,6 +24073,7 @@ render_bcd: { rts } //SEG272 render_next +// Render the next tetromino in the "next" area render_next: { .const next_area_offset = $28*$c+$18+4 .label next_piece_char = $a @@ -24114,6 +24191,8 @@ render_next: { jmp b6 } //SEG319 render_moving +// Render the current moving piece at position (current_xpos, current_ypos) +// Ignores cases where parts of the tetromino is outside the playfield (sides/bottom) since the movement collision routine prevents this. render_moving: { .label ypos2 = $b .label screen_line = 7 @@ -24221,6 +24300,7 @@ render_moving: { jmp b3 } //SEG363 render_playfield +// Render the static playfield on the screen (all pieces already locked into place) render_playfield: { .label screen_line = 5 .label i = $a @@ -24293,6 +24373,9 @@ render_playfield: { rts } //SEG393 play_movement +// Perform any movement of the current piece +// key_event is the next keyboard_event() og $ff if no keyboard event is pending +// Returns a byte signaling whether rendering is needed. (0 no render, >0 render needed) play_movement: { .label render = 9 .label return = 9 @@ -24305,7 +24388,6 @@ play_movement: { txa //SEG397 play_movement::@5 //SEG398 [167] (byte~) play_movement::$0 ← (byte) play_move_down::return#0 - // (byte~) play_movement::$0 = (byte) play_move_down::return#0 // register copy reg byte a //SEG399 [168] (byte) play_movement::render#1 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + (byte~) play_movement::$0 -- vbuz1=vbuc1_plus_vbuaa clc adc #0 @@ -24330,10 +24412,8 @@ play_movement: { //SEG410 [173] call play_move_leftright jsr play_move_leftright //SEG411 [174] (byte) play_move_leftright::return#0 ← (byte) play_move_leftright::return#2 - // (byte) play_move_leftright::return#0 = (byte) play_move_leftright::return#2 // register copy reg byte a //SEG412 play_movement::@6 //SEG413 [175] (byte~) play_movement::$3 ← (byte) play_move_leftright::return#0 - // (byte~) play_movement::$3 = (byte) play_move_leftright::return#0 // register copy reg byte a //SEG414 [176] (byte) play_movement::render#2 ← (byte) play_movement::render#1 + (byte~) play_movement::$3 -- vbuz1=vbuz1_plus_vbuaa clc adc render @@ -24343,10 +24423,8 @@ play_movement: { //SEG416 [178] call play_move_rotate jsr play_move_rotate //SEG417 [179] (byte) play_move_rotate::return#0 ← (byte) play_move_rotate::return#2 - // (byte) play_move_rotate::return#0 = (byte) play_move_rotate::return#2 // register copy reg byte a //SEG418 play_movement::@7 //SEG419 [180] (byte~) play_movement::$4 ← (byte) play_move_rotate::return#0 - // (byte~) play_movement::$4 = (byte) play_move_rotate::return#0 // register copy reg byte a //SEG420 [181] (byte) play_movement::return#0 ← (byte) play_movement::render#2 + (byte~) play_movement::$4 -- vbuz1=vbuz1_plus_vbuaa clc adc return @@ -24354,6 +24432,8 @@ play_movement: { jmp breturn } //SEG421 play_move_rotate +// Rotate the current piece based on key-presses +// Return non-zero if a render is needed play_move_rotate: { .label orientation = $a //SEG422 [182] if((byte) play_move_rotate::key_event#0==(const byte) KEY_Z#0) goto play_move_rotate::@1 -- vbuaa_eq_vbuc1_then_la1 @@ -24407,10 +24487,8 @@ play_move_rotate: { //SEG446 [201] phi (byte*) current_piece#17 = (byte*~) current_piece#101 [phi:play_move_rotate::@4->play_collision#3] -- register_copy jsr play_collision //SEG447 [194] (byte) play_collision::return#14 ← (byte) play_collision::return#15 - // (byte) play_collision::return#14 = (byte) play_collision::return#15 // register copy reg byte a //SEG448 play_move_rotate::@14 //SEG449 [195] (byte~) play_move_rotate::$6 ← (byte) play_collision::return#14 - // (byte~) play_move_rotate::$6 = (byte) play_collision::return#14 // register copy reg byte a //SEG450 [196] if((byte~) play_move_rotate::$6!=(const byte) COLLISION_NONE#0) goto play_move_rotate::@return -- vbuaa_neq_vbuc1_then_la1 cmp #COLLISION_NONE bne b3 @@ -24443,6 +24521,8 @@ play_move_rotate: { jmp b4 } //SEG461 play_collision +// Test if there is a collision between the current piece moved to (x, y) and anything on the playfield or the playfield boundaries +// Returns information about the type of the collision detected play_collision: { .label xpos = $c .label ypos = $b @@ -24592,6 +24672,8 @@ play_collision: { jmp b2 } //SEG519 play_move_leftright +// Move left/right or rotate the current piece +// Return non-zero if a render is needed play_move_leftright: { //SEG520 [225] if((byte) play_move_leftright::key_event#0==(const byte) KEY_COMMA#0) goto play_move_leftright::@1 -- vbuaa_eq_vbuc1_then_la1 cmp #KEY_COMMA @@ -24623,10 +24705,8 @@ play_move_leftright: { //SEG533 [201] phi (byte*) current_piece#17 = (byte*~) current_piece#100 [phi:play_move_leftright::@7->play_collision#3] -- register_copy jsr play_collision //SEG534 [232] (byte) play_collision::return#13 ← (byte) play_collision::return#15 - // (byte) play_collision::return#13 = (byte) play_collision::return#15 // register copy reg byte a //SEG535 play_move_leftright::@15 //SEG536 [233] (byte~) play_move_leftright::$4 ← (byte) play_collision::return#13 - // (byte~) play_move_leftright::$4 = (byte) play_collision::return#13 // register copy reg byte a //SEG537 [234] if((byte~) play_move_leftright::$4!=(const byte) COLLISION_NONE#0) goto play_move_leftright::@return -- vbuaa_neq_vbuc1_then_la1 cmp #COLLISION_NONE bne b3 @@ -24672,10 +24752,8 @@ play_move_leftright: { //SEG558 [201] phi (byte*) current_piece#17 = (byte*~) current_piece#99 [phi:play_move_leftright::@1->play_collision#3] -- register_copy jsr play_collision //SEG559 [243] (byte) play_collision::return#1 ← (byte) play_collision::return#15 - // (byte) play_collision::return#1 = (byte) play_collision::return#15 // register copy reg byte a //SEG560 play_move_leftright::@14 //SEG561 [244] (byte~) play_move_leftright::$8 ← (byte) play_collision::return#1 - // (byte~) play_move_leftright::$8 = (byte) play_collision::return#1 // register copy reg byte a //SEG562 [245] if((byte~) play_move_leftright::$8!=(const byte) COLLISION_NONE#0) goto play_move_leftright::@return -- vbuaa_neq_vbuc1_then_la1 cmp #COLLISION_NONE bne b3 @@ -24685,6 +24763,8 @@ play_move_leftright: { jmp b2 } //SEG565 play_move_down +// Move down the current piece +// Return non-zero if a render is needed play_move_down: { //SEG566 [247] (byte) current_movedown_counter#12 ← ++ (byte) current_movedown_counter#16 -- vbuz1=_inc_vbuz1 inc current_movedown_counter @@ -24710,10 +24790,8 @@ play_move_down: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG578 [252] (byte) keyboard_event_pressed::return#12 ← (byte) keyboard_event_pressed::return#11 - // (byte) keyboard_event_pressed::return#12 = (byte) keyboard_event_pressed::return#11 // register copy reg byte a //SEG579 play_move_down::@17 //SEG580 [253] (byte~) play_move_down::$2 ← (byte) keyboard_event_pressed::return#12 - // (byte~) play_move_down::$2 = (byte) keyboard_event_pressed::return#12 // register copy reg byte a //SEG581 [254] if((byte~) play_move_down::$2==(byte/signed byte/word/signed word/dword/signed dword) 0) goto play_move_down::@2 -- vbuaa_eq_0_then_la1 cmp #0 beq b2 @@ -24766,10 +24844,8 @@ play_move_down: { //SEG606 [201] phi (byte*) current_piece#17 = (byte*~) current_piece#98 [phi:play_move_down::@12->play_collision#3] -- register_copy jsr play_collision //SEG607 [267] (byte) play_collision::return#0 ← (byte) play_collision::return#15 - // (byte) play_collision::return#0 = (byte) play_collision::return#15 // register copy reg byte a //SEG608 play_move_down::@18 //SEG609 [268] (byte~) play_move_down::$12 ← (byte) play_collision::return#0 - // (byte~) play_move_down::$12 = (byte) play_collision::return#0 // register copy reg byte a //SEG610 [269] if((byte~) play_move_down::$12==(const byte) COLLISION_NONE#0) goto play_move_down::@6 -- vbuaa_eq_vbuc1_then_la1 cmp #COLLISION_NONE beq b6 @@ -24786,7 +24862,6 @@ play_move_down: { lda play_remove_lines.removed //SEG619 play_move_down::@20 //SEG620 [275] (byte) play_move_down::removed#0 ← (byte) play_remove_lines::return#0 - // (byte) play_move_down::removed#0 = (byte) play_remove_lines::return#0 // register copy reg byte a //SEG621 [276] (byte) play_update_score::removed#0 ← (byte) play_move_down::removed#0 -- vbuxx=vbuaa tax //SEG622 [277] call play_update_score @@ -24885,6 +24960,8 @@ play_move_down: { jmp b7 } //SEG695 play_spawn_current +// Spawn a new piece +// Moves the next piece into the current and spawns a new next piece play_spawn_current: { .label _0 = 4 .label piece_idx = $21 @@ -24929,10 +25006,8 @@ play_spawn_current: { //SEG710 [201] phi (byte*) current_piece#17 = (byte*~) current_piece#102 [phi:play_spawn_current->play_collision#3] -- register_copy jsr play_collision //SEG711 [296] (byte) play_collision::return#10 ← (byte) play_collision::return#15 - // (byte) play_collision::return#10 = (byte) play_collision::return#15 // register copy reg byte a //SEG712 play_spawn_current::@9 //SEG713 [297] (byte~) play_spawn_current::$2 ← (byte) play_collision::return#10 - // (byte~) play_spawn_current::$2 = (byte) play_collision::return#10 // register copy reg byte a //SEG714 [298] if((byte~) play_spawn_current::$2!=(const byte) COLLISION_PLAYFIELD#0) goto play_spawn_current::@11 -- vbuaa_neq_vbuc1_then_la1 cmp #COLLISION_PLAYFIELD bne b1 @@ -24961,10 +25036,8 @@ play_spawn_current: { //SEG726 [304] call sid_rnd jsr sid_rnd //SEG727 [305] (byte) sid_rnd::return#2 ← (byte) sid_rnd::return#0 - // (byte) sid_rnd::return#2 = (byte) sid_rnd::return#0 // register copy reg byte a //SEG728 play_spawn_current::@10 //SEG729 [306] (byte~) play_spawn_current::$6 ← (byte) sid_rnd::return#2 - // (byte~) play_spawn_current::$6 = (byte) sid_rnd::return#2 // register copy reg byte a //SEG730 [307] (byte) play_spawn_current::piece_idx#1 ← (byte~) play_spawn_current::$6 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuz1=vbuaa_band_vbuc1 and #7 sta piece_idx @@ -24977,6 +25050,8 @@ play_spawn_current: { //SEG736 [299] phi (byte) game_over#52 = (byte) game_over#65 [phi:play_spawn_current::@11->play_spawn_current::@1#0] -- register_copy } //SEG737 sid_rnd +// Get a random number from the SID voice 3, +// Must be initialized with sid_rnd_init() sid_rnd: { //SEG738 [309] (byte) sid_rnd::return#0 ← *((const byte*) SID_VOICE3_OSC#0) -- vbuaa=_deref_pbuc1 lda SID_VOICE3_OSC @@ -24985,6 +25060,7 @@ sid_rnd: { rts } //SEG741 play_update_score +// Update the score based on the number of lines removed play_update_score: { .label lines_before = 4 .label add_bcd = $2b @@ -25060,6 +25136,7 @@ play_update_score: { rts } //SEG766 play_increase_level +// Increase the level play_increase_level: { //SEG767 [327] (byte) level#21 ← ++ (byte) level#10 -- vbuz1=_inc_vbuz1 inc level @@ -25143,6 +25220,10 @@ play_increase_level: { rts } //SEG798 play_remove_lines +// Look through the playfield for lines - and remove any lines found +// Utilizes two cursors on the playfield - one reading cells and one writing cells +// Whenever a full line is detected the writing cursor is instructed to write to the same line once more. +// Returns the number of lines removed play_remove_lines: { .label c = $c .label x = $a @@ -25255,6 +25336,7 @@ play_remove_lines: { //SEG854 [350] phi (byte) play_remove_lines::full#2 = (byte) play_remove_lines::full#4 [phi:play_remove_lines::@18->play_remove_lines::@3#0] -- register_copy } //SEG855 play_lock_current +// Lock the current piece onto the playfield play_lock_current: { .label ypos2 = $10 .label playfield_line = 5 @@ -25352,6 +25434,8 @@ play_lock_current: { jmp b2 } //SEG895 keyboard_event_pressed +// Determine if a specific key is currently pressed based on the last keyboard_event_scan() +// Returns 0 is not pressed and non-0 if pressed keyboard_event_pressed: { .label row_bits = $a .label keycode = 9 @@ -25376,6 +25460,9 @@ keyboard_event_pressed: { rts } //SEG902 keyboard_event_get +// Get the next event from the keyboard event buffer. +// Returns $ff if there is no event waiting. As all events are <$7f it is enough to examine bit 7 when determining if there is any event to process. +// The buffer is filled by keyboard_event_scan() keyboard_event_get: { //SEG903 [390] if((byte) keyboard_events_size#13==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_get::@return -- vbuz1_eq_0_then_la1 lda keyboard_events_size @@ -25403,6 +25490,10 @@ keyboard_event_get: { rts } //SEG915 keyboard_event_scan +// Scans the entire matrix to determine which keys have been pressed/depressed. +// Generates keyboard events into the event buffer. Events can be read using keyboard_event_get(). +// Handles debounce and only generates events when the status of a key changes. +// Also stores current status of modifiers in keyboard_modifiers. keyboard_event_scan: { .label row_scan = $b .label keycode = $a @@ -25425,7 +25516,6 @@ keyboard_event_scan: { //SEG926 [398] call keyboard_matrix_read jsr keyboard_matrix_read //SEG927 [399] (byte) keyboard_matrix_read::return#2 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#2 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a //SEG928 keyboard_event_scan::@25 //SEG929 [400] (byte) keyboard_event_scan::row_scan#0 ← (byte) keyboard_matrix_read::return#2 -- vbuz1=vbuaa sta row_scan @@ -25459,10 +25549,8 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG944 [408] (byte) keyboard_event_pressed::return#0 ← (byte) keyboard_event_pressed::return#11 - // (byte) keyboard_event_pressed::return#0 = (byte) keyboard_event_pressed::return#11 // register copy reg byte a //SEG945 keyboard_event_scan::@26 //SEG946 [409] (byte~) keyboard_event_scan::$14 ← (byte) keyboard_event_pressed::return#0 - // (byte~) keyboard_event_scan::$14 = (byte) keyboard_event_pressed::return#0 // register copy reg byte a //SEG947 [410] if((byte~) keyboard_event_scan::$14==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@9 -- vbuaa_eq_0_then_la1 cmp #0 beq b2 @@ -25485,10 +25573,8 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG958 [414] (byte) keyboard_event_pressed::return#1 ← (byte) keyboard_event_pressed::return#11 - // (byte) keyboard_event_pressed::return#1 = (byte) keyboard_event_pressed::return#11 // register copy reg byte a //SEG959 keyboard_event_scan::@27 //SEG960 [415] (byte~) keyboard_event_scan::$18 ← (byte) keyboard_event_pressed::return#1 - // (byte~) keyboard_event_scan::$18 = (byte) keyboard_event_pressed::return#1 // register copy reg byte a //SEG961 [416] if((byte~) keyboard_event_scan::$18==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@10 -- vbuaa_eq_0_then_la1 cmp #0 beq b10 @@ -25508,10 +25594,8 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG970 [420] (byte) keyboard_event_pressed::return#2 ← (byte) keyboard_event_pressed::return#11 - // (byte) keyboard_event_pressed::return#2 = (byte) keyboard_event_pressed::return#11 // register copy reg byte a //SEG971 keyboard_event_scan::@28 //SEG972 [421] (byte~) keyboard_event_scan::$22 ← (byte) keyboard_event_pressed::return#2 - // (byte~) keyboard_event_scan::$22 = (byte) keyboard_event_pressed::return#2 // register copy reg byte a //SEG973 [422] if((byte~) keyboard_event_scan::$22==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@11 -- vbuaa_eq_0_then_la1 cmp #0 beq b11 @@ -25531,10 +25615,8 @@ keyboard_event_scan: { sta keyboard_event_pressed.keycode jsr keyboard_event_pressed //SEG982 [426] (byte) keyboard_event_pressed::return#10 ← (byte) keyboard_event_pressed::return#11 - // (byte) keyboard_event_pressed::return#10 = (byte) keyboard_event_pressed::return#11 // register copy reg byte a //SEG983 keyboard_event_scan::@29 //SEG984 [427] (byte~) keyboard_event_scan::$26 ← (byte) keyboard_event_pressed::return#10 - // (byte~) keyboard_event_scan::$26 = (byte) keyboard_event_pressed::return#10 // register copy reg byte a //SEG985 [428] if((byte~) keyboard_event_scan::$26==(byte/signed byte/word/signed word/dword/signed dword) 0) goto keyboard_event_scan::@return -- vbuaa_eq_0_then_la1 cmp #0 beq breturn @@ -25616,6 +25698,11 @@ keyboard_event_scan: { jmp b5 } //SEG1022 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { //SEG1023 [448] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0 + (byte) keyboard_matrix_read::rowid#0) -- _deref_pbuc1=pbuc2_derefidx_vbuxx lda keyboard_matrix_row_bitmask,x @@ -25628,6 +25715,7 @@ keyboard_matrix_read: { rts } //SEG1027 render_show +// Update $D018 to show the current screen (used for double buffering) render_show: { .const toD0181_return = (>(PLAYFIELD_SCREEN_1&$3fff)<<2)|(>PLAYFIELD_CHARSET)>>2&$f .const toD0182_return = (>(PLAYFIELD_SCREEN_2&$3fff)<<2)|(>PLAYFIELD_CHARSET)>>2&$f @@ -25666,6 +25754,7 @@ render_show: { jmp b2 } //SEG1044 play_init +// Initialize play data tables play_init: { .label pli = 5 .label idx = 2 @@ -25754,6 +25843,7 @@ play_init: { rts } //SEG1075 sprites_irq_init +// Setup the IRQ sprites_irq_init: { //SEG1076 asm { sei } sei @@ -25793,6 +25883,7 @@ sprites_irq_init: { rts } //SEG1089 sprites_init +// Setup the sprites sprites_init: { .label xpos = 2 //SEG1090 [489] *((const byte*) SPRITES_ENABLE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 15 -- _deref_pbuc1=vbuc2 @@ -25841,6 +25932,7 @@ sprites_init: { rts } //SEG1109 render_init +// Initialize rendering render_init: { .const vicSelectGfxBank1_toDd001_return = 3^(>PLAYFIELD_CHARSET)>>6 .label li_1 = 5 @@ -25954,6 +26046,8 @@ render_init: { rts } //SEG1150 render_screen_original +// Copy the original screen data to the passed screen +// Also copies colors to $d800 render_screen_original: { .const SPACE = 0 .label screen = $11 @@ -26105,6 +26199,7 @@ render_screen_original: { rts } //SEG1210 sid_rnd_init +// Initialize SID voice 3 for random number generation sid_rnd_init: { //SEG1211 [552] *((const word*) SID_VOICE3_FREQ#0) ← (word/dword/signed dword) 65535 -- _deref_pwuc1=vwuc2 lda #<$ffff @@ -26119,6 +26214,9 @@ sid_rnd_init: { rts } //SEG1215 sprites_irq +// Raster Interrupt Routine - sets up the sprites covering the playfield +// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST +// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers sprites_irq: { .const toSpritePtr2_return = PLAYFIELD_SPRITES>>6 .label raster_sprite_gfx_modify = $2f diff --git a/src/test/ref/concat-char.asm b/src/test/ref/concat-char.asm index 3db611ffd..858fd8f65 100644 --- a/src/test/ref/concat-char.asm +++ b/src/test/ref/concat-char.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Concatenate a char to a string main: { .label screen = $400 ldx #0 diff --git a/src/test/ref/concat-char.log b/src/test/ref/concat-char.log index 0405d872b..5aa245521 100644 --- a/src/test/ref/concat-char.log +++ b/src/test/ref/concat-char.log @@ -151,6 +151,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Concatenate a char to a string main: { .label screen = $400 .label i = 2 @@ -220,6 +221,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Concatenate a char to a string main: { .label screen = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] @@ -309,6 +311,7 @@ Score: 186 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Concatenate a char to a string main: { .label screen = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] diff --git a/src/test/ref/const-condition.asm b/src/test/ref/const-condition.asm index df4edbee3..16ffa98fe 100644 --- a/src/test/ref/const-condition.asm +++ b/src/test/ref/const-condition.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Ensure that if()'s with constant comparisons are identified and eliminated main: { .label SCREEN = $400 lda #'!' diff --git a/src/test/ref/const-condition.log b/src/test/ref/const-condition.log index 207a419d4..d5b10a7f7 100644 --- a/src/test/ref/const-condition.log +++ b/src/test/ref/const-condition.log @@ -115,6 +115,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Ensure that if()'s with constant comparisons are identified and eliminated main: { .label SCREEN = $400 jmp b3 @@ -163,6 +164,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Ensure that if()'s with constant comparisons are identified and eliminated main: { .label SCREEN = $400 jmp b3 @@ -227,6 +229,7 @@ Score: 12 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Ensure that if()'s with constant comparisons are identified and eliminated main: { .label SCREEN = $400 //SEG10 main::@3 diff --git a/src/test/ref/const-identification.log b/src/test/ref/const-identification.log index b76800ce5..2c23779c8 100644 --- a/src/test/ref/const-identification.log +++ b/src/test/ref/const-identification.log @@ -517,7 +517,6 @@ line: { //SEG28 line::@3 b3: //SEG29 [14] (byte) plot::x#1 ← (byte) line::x#2 - // (byte) plot::x#1 = (byte) line::x#2 // register copy reg byte x //SEG30 [15] call plot jsr plot jmp b8 @@ -689,7 +688,6 @@ line: { //SEG28 line::@3 b3: //SEG29 [14] (byte) plot::x#1 ← (byte) line::x#2 - // (byte) plot::x#1 = (byte) line::x#2 // register copy reg byte x //SEG30 [15] call plot jsr plot //SEG31 line::@8 diff --git a/src/test/ref/const-mult-div.asm b/src/test/ref/const-mult-div.asm index a875eb2b1..4ee045b61 100644 --- a/src/test/ref/const-mult-div.asm +++ b/src/test/ref/const-mult-div.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Test a constant with multiplication and division main: { .label screen = $400 .const b = 6*$e/3+mod($16,3) diff --git a/src/test/ref/const-mult-div.log b/src/test/ref/const-mult-div.log index c9adf5d98..f0d8e3418 100644 --- a/src/test/ref/const-mult-div.log +++ b/src/test/ref/const-mult-div.log @@ -115,6 +115,7 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Test a constant with multiplication and division main: { .label screen = $400 .const b = 6*$e/3+mod($16,3) @@ -159,6 +160,7 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Test a constant with multiplication and division main: { .label screen = $400 .const b = 6*$e/3+mod($16,3) @@ -218,6 +220,7 @@ Score: 12 //SEG6 [3] phi from @1 to @end [phi:@1->@end] //SEG7 @end //SEG8 main +// Test a constant with multiplication and division main: { .label screen = $400 .const b = 6*$e/3+mod($16,3) diff --git a/src/test/ref/const-param.asm b/src/test/ref/const-param.asm index 114de7b0a..bca0dafc6 100644 --- a/src/test/ref/const-param.asm +++ b/src/test/ref/const-param.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Test that the compiler optimizes when the same parameter value is passed into a function in all calls main: { .label screen = $400 .label reverse = $80 diff --git a/src/test/ref/const-param.log b/src/test/ref/const-param.log index c40732f0f..2d6a9710f 100644 --- a/src/test/ref/const-param.log +++ b/src/test/ref/const-param.log @@ -264,6 +264,7 @@ bend_from_b2: //SEG8 @end bend: //SEG9 main +// Test that the compiler optimizes when the same parameter value is passed into a function in all calls main: { .label screen = $400 .label reverse = $80 @@ -398,6 +399,7 @@ bend_from_b2: //SEG8 @end bend: //SEG9 main +// Test that the compiler optimizes when the same parameter value is passed into a function in all calls main: { .label screen = $400 .label reverse = $80 @@ -408,12 +410,10 @@ main: { lda #'c' jsr sum //SEG13 [6] (byte) sum::return#0 ← (byte) sum::return#3 - // (byte) sum::return#0 = (byte) sum::return#3 // register copy reg byte a jmp b1 //SEG14 main::@1 b1: //SEG15 [7] (byte~) main::$0 ← (byte) sum::return#0 - // (byte~) main::$0 = (byte) sum::return#0 // register copy reg byte a //SEG16 [8] *((const byte*) main::screen#0) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa sta screen //SEG17 [9] call sum @@ -423,12 +423,10 @@ main: { lda #'m' jsr sum //SEG20 [10] (byte) sum::return#1 ← (byte) sum::return#3 - // (byte) sum::return#1 = (byte) sum::return#3 // register copy reg byte a jmp b2 //SEG21 main::@2 b2: //SEG22 [11] (byte~) main::$1 ← (byte) sum::return#1 - // (byte~) main::$1 = (byte) sum::return#1 // register copy reg byte a //SEG23 [12] *((const byte*) main::screen#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte~) main::$1 -- _deref_pbuc1=vbuaa sta screen+1 //SEG24 [13] call sum @@ -438,12 +436,10 @@ main: { lda #'l' jsr sum //SEG27 [14] (byte) sum::return#2 ← (byte) sum::return#3 - // (byte) sum::return#2 = (byte) sum::return#3 // register copy reg byte a jmp b3 //SEG28 main::@3 b3: //SEG29 [15] (byte~) main::$2 ← (byte) sum::return#2 - // (byte~) main::$2 = (byte) sum::return#2 // register copy reg byte a //SEG30 [16] *((const byte*) main::screen#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte~) main::$2 -- _deref_pbuc1=vbuaa sta screen+2 jmp breturn @@ -547,6 +543,7 @@ Score: 52 //SEG7 [3] phi from @2 to @end [phi:@2->@end] //SEG8 @end //SEG9 main +// Test that the compiler optimizes when the same parameter value is passed into a function in all calls main: { .label screen = $400 .label reverse = $80 @@ -556,10 +553,8 @@ main: { lda #'c' jsr sum //SEG13 [6] (byte) sum::return#0 ← (byte) sum::return#3 - // (byte) sum::return#0 = (byte) sum::return#3 // register copy reg byte a //SEG14 main::@1 //SEG15 [7] (byte~) main::$0 ← (byte) sum::return#0 - // (byte~) main::$0 = (byte) sum::return#0 // register copy reg byte a //SEG16 [8] *((const byte*) main::screen#0) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa sta screen //SEG17 [9] call sum @@ -568,10 +563,8 @@ main: { lda #'m' jsr sum //SEG20 [10] (byte) sum::return#1 ← (byte) sum::return#3 - // (byte) sum::return#1 = (byte) sum::return#3 // register copy reg byte a //SEG21 main::@2 //SEG22 [11] (byte~) main::$1 ← (byte) sum::return#1 - // (byte~) main::$1 = (byte) sum::return#1 // register copy reg byte a //SEG23 [12] *((const byte*) main::screen#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte~) main::$1 -- _deref_pbuc1=vbuaa sta screen+1 //SEG24 [13] call sum @@ -580,10 +573,8 @@ main: { lda #'l' jsr sum //SEG27 [14] (byte) sum::return#2 ← (byte) sum::return#3 - // (byte) sum::return#2 = (byte) sum::return#3 // register copy reg byte a //SEG28 main::@3 //SEG29 [15] (byte~) main::$2 ← (byte) sum::return#2 - // (byte~) main::$2 = (byte) sum::return#2 // register copy reg byte a //SEG30 [16] *((const byte*) main::screen#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte~) main::$2 -- _deref_pbuc1=vbuaa sta screen+2 //SEG31 main::@return diff --git a/src/test/ref/const-pointer.asm b/src/test/ref/const-pointer.asm index ebcb4632f..b984d848e 100644 --- a/src/test/ref/const-pointer.asm +++ b/src/test/ref/const-pointer.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Test that constant pointers are detected correctly main: { .label screen = $400 lda #'*' diff --git a/src/test/ref/const-pointer.log b/src/test/ref/const-pointer.log index afea7d1be..989095cc4 100644 --- a/src/test/ref/const-pointer.log +++ b/src/test/ref/const-pointer.log @@ -132,6 +132,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Test that constant pointers are detected correctly main: { .label screen = $400 jmp b1 @@ -180,6 +181,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Test that constant pointers are detected correctly main: { .label screen = $400 jmp b1 @@ -246,6 +248,7 @@ Score: 12 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Test that constant pointers are detected correctly main: { .label screen = $400 //SEG10 main::@1 diff --git a/src/test/ref/const-word-pointer.asm b/src/test/ref/const-word-pointer.asm index 578d4ce50..87090a031 100644 --- a/src/test/ref/const-word-pointer.asm +++ b/src/test/ref/const-word-pointer.asm @@ -1,6 +1,8 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Test a constant word pointers (pointing to a word placed on zeropage). +// The result when running is "CML!" on the screen. main: { .label screen = $400 .label wp = w diff --git a/src/test/ref/const-word-pointer.log b/src/test/ref/const-word-pointer.log index 8a6fb71d8..7d2364c51 100644 --- a/src/test/ref/const-word-pointer.log +++ b/src/test/ref/const-word-pointer.log @@ -148,6 +148,8 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Test a constant word pointers (pointing to a word placed on zeropage). +// The result when running is "CML!" on the screen. main: { .label screen = $400 .label wp = w @@ -235,6 +237,8 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Test a constant word pointers (pointing to a word placed on zeropage). +// The result when running is "CML!" on the screen. main: { .label screen = $400 .label wp = w @@ -329,6 +333,8 @@ Score: 60 //SEG6 [3] phi from @1 to @end [phi:@1->@end] //SEG7 @end //SEG8 main +// Test a constant word pointers (pointing to a word placed on zeropage). +// The result when running is "CML!" on the screen. main: { .label screen = $400 .label wp = w diff --git a/src/test/ref/constant-string-concat.asm b/src/test/ref/constant-string-concat.asm index 0e12e9278..cf98f71b8 100644 --- a/src/test/ref/constant-string-concat.asm +++ b/src/test/ref/constant-string-concat.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Concatenates string constants in different ways main: { .label SCREEN = $400 ldx #0 diff --git a/src/test/ref/constant-string-concat.log b/src/test/ref/constant-string-concat.log index 7093d3bad..38026addf 100644 --- a/src/test/ref/constant-string-concat.log +++ b/src/test/ref/constant-string-concat.log @@ -191,6 +191,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Concatenates string constants in different ways main: { .label SCREEN = $400 .label i = 2 @@ -263,6 +264,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Concatenates string constants in different ways main: { .label SCREEN = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] @@ -362,6 +364,7 @@ Score: 186 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Concatenates string constants in different ways main: { .label SCREEN = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] diff --git a/src/test/ref/constants.asm b/src/test/ref/constants.asm index 0e195dfab..77eb045b3 100644 --- a/src/test/ref/constants.asm +++ b/src/test/ref/constants.asm @@ -14,6 +14,7 @@ main: { jsr test_sbytes rts } +// Test different signed byte constants test_sbytes: { .const bb = 0 .const bc = bb+2 @@ -103,6 +104,7 @@ assert_sbyte: { str1: .text "fail!@" str2: .text "ok@" } +// Print a zero-terminated string print_str: { .label str = 2 b1: @@ -125,6 +127,7 @@ print_str: { !: jmp b1 } +// Print a newline print_ln: { b1: lda print_line_cursor @@ -144,6 +147,7 @@ print_ln: { !: rts } +// Test different byte constants test_bytes: { .const bb = 0 .const bc = bb+2 @@ -225,6 +229,7 @@ assert_byte: { str1: .text "fail!@" str2: .text "ok@" } +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 lda #<$400 diff --git a/src/test/ref/constants.log b/src/test/ref/constants.log index 0459396e9..d739d2147 100644 --- a/src/test/ref/constants.log +++ b/src/test/ref/constants.log @@ -1391,6 +1391,7 @@ main: { rts } //SEG22 test_sbytes +// Test different signed byte constants test_sbytes: { .const bb = 0 .const bc = bb+2 @@ -1598,6 +1599,7 @@ assert_sbyte: { str2: .text "ok@" } //SEG92 print_str +// Print a zero-terminated string print_str: { .label str = 8 //SEG93 [37] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -1638,6 +1640,7 @@ print_str: { jmp b1_from_b2 } //SEG104 print_ln +// Print a newline print_ln: { //SEG105 [44] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -1670,6 +1673,7 @@ print_ln: { rts } //SEG112 test_bytes +// Test different byte constants test_bytes: { .const bb = 0 .const bc = bb+2 @@ -1848,6 +1852,7 @@ assert_byte: { str2: .text "ok@" } //SEG173 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = $10 //SEG174 [69] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -2026,6 +2031,7 @@ main: { rts } //SEG22 test_sbytes +// Test different signed byte constants test_sbytes: { .const bb = 0 .const bc = bb+2 @@ -2138,7 +2144,6 @@ assert_sbyte: { .label msg = 2 .label c = 4 //SEG59 [23] (byte*) print_str::str#5 ← (byte*) assert_sbyte::msg#5 - // (byte*) print_str::str#5 = (byte*) assert_sbyte::msg#5 // register copy zp ZP_WORD:2 //SEG60 [24] (byte*~) print_char_cursor#87 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -2223,6 +2228,7 @@ assert_sbyte: { str2: .text "ok@" } //SEG92 print_str +// Print a zero-terminated string print_str: { .label str = 2 //SEG93 [37] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -2263,6 +2269,7 @@ print_str: { jmp b1_from_b2 } //SEG104 print_ln +// Print a newline print_ln: { //SEG105 [44] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -2295,6 +2302,7 @@ print_ln: { rts } //SEG112 test_bytes +// Test different byte constants test_bytes: { .const bb = 0 .const bc = bb+2 @@ -2385,7 +2393,6 @@ assert_byte: { .label msg = 2 .label c = 4 //SEG141 [56] (byte*) print_str::str#1 ← (byte*) assert_byte::msg#3 - // (byte*) print_str::str#1 = (byte*) assert_byte::msg#3 // register copy zp ZP_WORD:2 //SEG142 [57] call print_str //SEG143 [36] phi from assert_byte to print_str [phi:assert_byte->print_str] print_str_from_assert_byte: @@ -2465,6 +2472,7 @@ assert_byte: { str2: .text "ok@" } //SEG173 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG174 [69] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -2786,6 +2794,7 @@ main: { rts } //SEG22 test_sbytes +// Test different signed byte constants test_sbytes: { .const bb = 0 .const bc = bb+2 @@ -2879,7 +2888,6 @@ assert_sbyte: { .label msg = 2 .label c = 4 //SEG59 [23] (byte*) print_str::str#5 ← (byte*) assert_sbyte::msg#5 - // (byte*) print_str::str#5 = (byte*) assert_sbyte::msg#5 // register copy zp ZP_WORD:2 //SEG60 [24] (byte*~) print_char_cursor#87 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -2946,6 +2954,7 @@ assert_sbyte: { str2: .text "ok@" } //SEG92 print_str +// Print a zero-terminated string print_str: { .label str = 2 //SEG93 [37] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -2980,6 +2989,7 @@ print_str: { jmp b1 } //SEG104 print_ln +// Print a newline print_ln: { //SEG105 [44] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] //SEG106 [44] phi (byte*) print_line_cursor#24 = (byte*) print_line_cursor#47 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy @@ -3007,6 +3017,7 @@ print_ln: { rts } //SEG112 test_bytes +// Test different byte constants test_bytes: { .const bb = 0 .const bc = bb+2 @@ -3088,7 +3099,6 @@ assert_byte: { .label msg = 2 .label c = 4 //SEG141 [56] (byte*) print_str::str#1 ← (byte*) assert_byte::msg#3 - // (byte*) print_str::str#1 = (byte*) assert_byte::msg#3 // register copy zp ZP_WORD:2 //SEG142 [57] call print_str //SEG143 [36] phi from assert_byte to print_str [phi:assert_byte->print_str] //SEG144 [36] phi (byte*) print_char_cursor#80 = (byte*) print_char_cursor#70 [phi:assert_byte->print_str#0] -- register_copy @@ -3150,6 +3160,7 @@ assert_byte: { str2: .text "ok@" } //SEG173 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG174 [69] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] diff --git a/src/test/ref/double-assignment.asm b/src/test/ref/double-assignment.asm index 51ba5a42b..532c9818b 100644 --- a/src/test/ref/double-assignment.asm +++ b/src/test/ref/double-assignment.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Test that a double-assignment works. main: { .label screen = $400 .const a = $c diff --git a/src/test/ref/double-assignment.log b/src/test/ref/double-assignment.log index 13d40e705..26d848720 100644 --- a/src/test/ref/double-assignment.log +++ b/src/test/ref/double-assignment.log @@ -105,6 +105,7 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Test that a double-assignment works. main: { .label screen = $400 .const a = $c @@ -153,6 +154,7 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Test that a double-assignment works. main: { .label screen = $400 .const a = $c @@ -218,6 +220,7 @@ Score: 16 //SEG6 [3] phi from @1 to @end [phi:@1->@end] //SEG7 @end //SEG8 main +// Test that a double-assignment works. main: { .label screen = $400 .const a = $c diff --git a/src/test/ref/emptyblock-error.asm b/src/test/ref/emptyblock-error.asm index a8cde9c8f..d492f3e1e 100644 --- a/src/test/ref/emptyblock-error.asm +++ b/src/test/ref/emptyblock-error.asm @@ -2,6 +2,7 @@ :BasicUpstart(main) .pc = $80d "Program" .label B = $1000 +// Error cleaning up unused blocks main: { lda #0 b2: diff --git a/src/test/ref/emptyblock-error.log b/src/test/ref/emptyblock-error.log index 03f95d997..9310c863b 100644 --- a/src/test/ref/emptyblock-error.log +++ b/src/test/ref/emptyblock-error.log @@ -327,6 +327,7 @@ bend_from_b3: //SEG8 @end bend: //SEG9 main +// Error cleaning up unused blocks main: { //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] b1_from_main: @@ -434,6 +435,7 @@ bend_from_b3: //SEG8 @end bend: //SEG9 main +// Error cleaning up unused blocks main: { //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] b1_from_main: @@ -591,6 +593,7 @@ Score: 8868 //SEG7 [3] phi from @3 to @end [phi:@3->@end] //SEG8 @end //SEG9 main +// Error cleaning up unused blocks main: { //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] //SEG11 [5] phi (byte) a#1 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuaa=vbuc1 diff --git a/src/test/ref/examples/3d/3d.asm b/src/test/ref/examples/3d/3d.asm index d251011cb..7187eb7ac 100644 --- a/src/test/ref/examples/3d/3d.asm +++ b/src/test/ref/examples/3d/3d.asm @@ -309,6 +309,7 @@ debug_print: { !b1: rts } +// Print a signed byte as hex at a specific screen position print_sbyte_at: { .label at = 6 cpx #0 @@ -334,6 +335,7 @@ print_sbyte_at: { tax jmp b2 } +// Print a single char print_char_at: { .label at = 6 .label ch = 8 @@ -342,6 +344,7 @@ print_char_at: { sta (at),y rts } +// Print a byte as HEX at a specific position print_byte_at: { .label at = 6 txa @@ -365,6 +368,10 @@ print_byte_at: { jsr print_char_at rts } +// Rotate a 3D point (x,y,z) using the rotation matrix +// 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: { .label x = 5 lda x @@ -461,6 +468,9 @@ rotate_matrix: { sta xp rts } +// Store the rotation matrix into the rotation routine rotate() +// After this each call to rotate() will rotate a point with the matrix +// Implemented in assembler to utilize seriously fast multiplication store_matrix: { lda rotation_matrix+0 sta rotate_matrix.A1+1 @@ -500,6 +510,9 @@ store_matrix: { sta rotate_matrix.I2+1 rts } +// Prepare the 3x3 rotation matrix into rotation_matrix[] +// Angles sx, sy, sz are based on 2*PI=$100 +// Method described in C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt calculate_matrix: { .label sy = 3 .label t1 = 4 @@ -1005,6 +1018,7 @@ debug_print_init: { str10: .text "xp@" str11: .text "yp@" } +// Print a string at a specific screen position print_str_at: { .label at = 9 .label str = 6 @@ -1028,6 +1042,7 @@ print_str_at: { !: jmp b1 } +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 6 lda #print_cls::@1] @@ -7605,6 +7620,7 @@ print_cls: { rts } //SEG501 sprites_init +// Initialize sprites sprites_init: { .label SCREEN = $400 .label sprites_ptr = SCREEN+$3f8 @@ -8550,7 +8566,6 @@ anim: { //SEG44 [27] (signed byte) calculate_matrix::sx#0 ← (signed byte) sx#10 -- vbsxx=vbsz1 ldx sx //SEG45 [28] (signed byte) calculate_matrix::sy#0 ← (signed byte) sy#10 - // (signed byte) calculate_matrix::sy#0 = (signed byte) sy#10 // register copy zp ZP_BYTE:3 //SEG46 [29] call calculate_matrix jsr calculate_matrix //SEG47 [30] phi from anim::@12 to anim::@27 [phi:anim::@12->anim::@27] @@ -8699,7 +8714,6 @@ debug_print: { //SEG86 debug_print::print_sbyte_pos1 print_sbyte_pos1: //SEG87 [57] (signed byte) print_sbyte_at::b#4 ← (signed byte) debug_print::print_sbyte_pos1_sb#0 - // (signed byte) print_sbyte_at::b#4 = (signed byte) debug_print::print_sbyte_pos1_sb#0 // register copy reg byte x //SEG88 [58] call print_sbyte_at //SEG89 [114] phi from debug_print::print_sbyte_pos1 to print_sbyte_at [phi:debug_print::print_sbyte_pos1->print_sbyte_at] print_sbyte_at_from_print_sbyte_pos1: @@ -8775,7 +8789,6 @@ debug_print: { //SEG116 debug_print::print_sbyte_pos5 print_sbyte_pos5: //SEG117 [68] (signed byte) print_sbyte_at::b#8 ← (signed byte) debug_print::print_sbyte_pos5_sb#0 - // (signed byte) print_sbyte_at::b#8 = (signed byte) debug_print::print_sbyte_pos5_sb#0 // register copy reg byte x //SEG118 [69] call print_sbyte_at //SEG119 [114] phi from debug_print::print_sbyte_pos5 to print_sbyte_at [phi:debug_print::print_sbyte_pos5->print_sbyte_at] print_sbyte_at_from_print_sbyte_pos5: @@ -8795,7 +8808,6 @@ debug_print: { //SEG124 debug_print::print_sbyte_pos6 print_sbyte_pos6: //SEG125 [71] (signed byte) print_sbyte_at::b#9 ← (signed byte) debug_print::print_sbyte_pos6_sb#0 - // (signed byte) print_sbyte_at::b#9 = (signed byte) debug_print::print_sbyte_pos6_sb#0 // register copy reg byte x //SEG126 [72] call print_sbyte_at //SEG127 [114] phi from debug_print::print_sbyte_pos6 to print_sbyte_at [phi:debug_print::print_sbyte_pos6->print_sbyte_at] print_sbyte_at_from_print_sbyte_pos6: @@ -8815,7 +8827,6 @@ debug_print: { //SEG132 debug_print::print_sbyte_pos7 print_sbyte_pos7: //SEG133 [74] (signed byte) print_sbyte_at::b#10 ← (signed byte) debug_print::print_sbyte_pos7_sb#0 - // (signed byte) print_sbyte_at::b#10 = (signed byte) debug_print::print_sbyte_pos7_sb#0 // register copy reg byte x //SEG134 [75] call print_sbyte_at //SEG135 [114] phi from debug_print::print_sbyte_pos7 to print_sbyte_at [phi:debug_print::print_sbyte_pos7->print_sbyte_at] print_sbyte_at_from_print_sbyte_pos7: @@ -8835,7 +8846,6 @@ debug_print: { //SEG140 debug_print::print_sbyte_pos8 print_sbyte_pos8: //SEG141 [77] (signed byte) print_sbyte_at::b#11 ← (signed byte) debug_print::print_sbyte_pos8_sb#0 - // (signed byte) print_sbyte_at::b#11 = (signed byte) debug_print::print_sbyte_pos8_sb#0 // register copy reg byte x //SEG142 [78] call print_sbyte_at //SEG143 [114] phi from debug_print::print_sbyte_pos8 to print_sbyte_at [phi:debug_print::print_sbyte_pos8->print_sbyte_at] print_sbyte_at_from_print_sbyte_pos8: @@ -8855,7 +8865,6 @@ debug_print: { //SEG148 debug_print::print_sbyte_pos9 print_sbyte_pos9: //SEG149 [80] (signed byte) print_sbyte_at::b#12 ← (signed byte) debug_print::print_sbyte_pos9_sb#0 - // (signed byte) print_sbyte_at::b#12 = (signed byte) debug_print::print_sbyte_pos9_sb#0 // register copy reg byte x //SEG150 [81] call print_sbyte_at //SEG151 [114] phi from debug_print::print_sbyte_pos9 to print_sbyte_at [phi:debug_print::print_sbyte_pos9->print_sbyte_at] print_sbyte_at_from_print_sbyte_pos9: @@ -8875,7 +8884,6 @@ debug_print: { //SEG156 debug_print::print_sbyte_pos10 print_sbyte_pos10: //SEG157 [83] (signed byte) print_sbyte_at::b#13 ← (signed byte) debug_print::print_sbyte_pos10_sb#0 - // (signed byte) print_sbyte_at::b#13 = (signed byte) debug_print::print_sbyte_pos10_sb#0 // register copy reg byte x //SEG158 [84] call print_sbyte_at //SEG159 [114] phi from debug_print::print_sbyte_pos10 to print_sbyte_at [phi:debug_print::print_sbyte_pos10->print_sbyte_at] print_sbyte_at_from_print_sbyte_pos10: @@ -8895,7 +8903,6 @@ debug_print: { //SEG164 debug_print::print_sbyte_pos11 print_sbyte_pos11: //SEG165 [86] (signed byte) print_sbyte_at::b#14 ← (signed byte) debug_print::print_sbyte_pos11_sb#0 - // (signed byte) print_sbyte_at::b#14 = (signed byte) debug_print::print_sbyte_pos11_sb#0 // register copy reg byte x //SEG166 [87] call print_sbyte_at //SEG167 [114] phi from debug_print::print_sbyte_pos11 to print_sbyte_at [phi:debug_print::print_sbyte_pos11->print_sbyte_at] print_sbyte_at_from_print_sbyte_pos11: @@ -8915,7 +8922,6 @@ debug_print: { //SEG172 debug_print::print_sbyte_pos12 print_sbyte_pos12: //SEG173 [89] (signed byte) print_sbyte_at::b#15 ← (signed byte) debug_print::print_sbyte_pos12_sb#0 - // (signed byte) print_sbyte_at::b#15 = (signed byte) debug_print::print_sbyte_pos12_sb#0 // register copy reg byte x //SEG174 [90] call print_sbyte_at //SEG175 [114] phi from debug_print::print_sbyte_pos12 to print_sbyte_at [phi:debug_print::print_sbyte_pos12->print_sbyte_at] print_sbyte_at_from_print_sbyte_pos12: @@ -9086,6 +9092,7 @@ debug_print: { rts } //SEG232 print_sbyte_at +// Print a signed byte as hex at a specific screen position print_sbyte_at: { .label at = 6 //SEG233 [115] if((signed byte) print_sbyte_at::b#22<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte_at::@1 -- vbsxx_lt_0_then_la1 @@ -9095,7 +9102,6 @@ print_sbyte_at: { //SEG234 print_sbyte_at::@3 b3: //SEG235 [116] (byte*) print_char_at::at#1 ← (byte*) print_sbyte_at::at#21 - // (byte*) print_char_at::at#1 = (byte*) print_sbyte_at::at#21 // register copy zp ZP_WORD:6 //SEG236 [117] call print_char_at //SEG237 [125] phi from print_sbyte_at::@3 to print_char_at [phi:print_sbyte_at::@3->print_char_at] print_char_at_from_b3: @@ -9126,7 +9132,6 @@ print_sbyte_at: { //SEG247 print_sbyte_at::@1 b1: //SEG248 [122] (byte*) print_char_at::at#0 ← (byte*) print_sbyte_at::at#21 - // (byte*) print_char_at::at#0 = (byte*) print_sbyte_at::at#21 // register copy zp ZP_WORD:6 //SEG249 [123] call print_char_at //SEG250 [125] phi from print_sbyte_at::@1 to print_char_at [phi:print_sbyte_at::@1->print_char_at] print_char_at_from_b1: @@ -9147,6 +9152,7 @@ print_sbyte_at: { jmp b2_from_b5 } //SEG255 print_char_at +// Print a single char print_char_at: { .label at = 6 .label ch = 8 @@ -9161,6 +9167,7 @@ print_char_at: { rts } //SEG259 print_byte_at +// Print a byte as HEX at a specific position print_byte_at: { .label at = 6 //SEG260 [128] (byte~) print_byte_at::$0 ← (byte)(signed byte) print_sbyte_at::b#24 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 @@ -9174,7 +9181,6 @@ print_byte_at: { lda print_hextab,y sta print_char_at.ch //SEG262 [130] (byte*) print_char_at::at#2 ← (byte*) print_byte_at::at#0 - // (byte*) print_char_at::at#2 = (byte*) print_byte_at::at#0 // register copy zp ZP_WORD:6 //SEG263 [131] call print_char_at //SEG264 [125] phi from print_byte_at to print_char_at [phi:print_byte_at->print_char_at] print_char_at_from_print_byte_at: @@ -9209,6 +9215,10 @@ print_byte_at: { rts } //SEG277 rotate_matrix +// Rotate a 3D point (x,y,z) using the rotation matrix +// 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: { .label x = 5 //SEG278 [137] *((const signed byte*) xr#0) ← (signed byte) rotate_matrix::x#0 -- _deref_pbsc1=vbsz1 @@ -9314,6 +9324,9 @@ rotate_matrix: { rts } //SEG284 store_matrix +// Store the rotation matrix into the rotation routine rotate() +// After this each call to rotate() will rotate a point with the matrix +// Implemented in assembler to utilize seriously fast multiplication store_matrix: { //SEG285 asm { ldarotation_matrix+0 starotate_matrix.A1+1 eor#$ff starotate_matrix.A2+1 ldarotation_matrix+1 starotate_matrix.B1+1 eor#$ff starotate_matrix.B2+1 ldarotation_matrix+2 starotate_matrix.C1+1 eor#$ff starotate_matrix.C2+1 ldarotation_matrix+3 starotate_matrix.D1+1 eor#$ff starotate_matrix.D2+1 ldarotation_matrix+4 starotate_matrix.E1+1 eor#$ff starotate_matrix.E2+1 ldarotation_matrix+5 starotate_matrix.F1+1 eor#$ff starotate_matrix.F2+1 ldarotation_matrix+6 starotate_matrix.G1+1 eor#$ff starotate_matrix.G2+1 ldarotation_matrix+7 starotate_matrix.H1+1 eor#$ff starotate_matrix.H2+1 ldarotation_matrix+8 starotate_matrix.I1+1 eor#$ff starotate_matrix.I2+1 } lda rotation_matrix+0 @@ -9359,6 +9372,9 @@ store_matrix: { rts } //SEG288 calculate_matrix +// Prepare the 3x3 rotation matrix into rotation_matrix[] +// Angles sx, sy, sz are based on 2*PI=$100 +// Method described in C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt calculate_matrix: { .label sy = 3 .label t1 = 4 @@ -10130,6 +10146,7 @@ debug_print_init: { str11: .text "yp@" } //SEG478 print_str_at +// Print a string at a specific screen position print_str_at: { .label at = 9 .label str = 6 @@ -10171,6 +10188,7 @@ print_str_at: { jmp b1_from_b2 } //SEG490 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 6 //SEG491 [268] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -10210,6 +10228,7 @@ print_cls: { rts } //SEG501 sprites_init +// Initialize sprites sprites_init: { .label SCREEN = $400 .label sprites_ptr = SCREEN+$3f8 @@ -10483,11 +10502,22 @@ Removing instruction anim_from_b2: Removing instruction b1: Removing instruction b27_from_b12: Removing instruction b13_from_b29: +Removing instruction print_sbyte_at_from_print_sbyte_pos1: Removing instruction print_sbyte_pos3_from_print_sbyte_pos2: Removing instruction print_sbyte_at_from_print_sbyte_pos3: +Removing instruction print_sbyte_at_from_print_sbyte_pos5: +Removing instruction print_sbyte_at_from_print_sbyte_pos6: +Removing instruction print_sbyte_at_from_print_sbyte_pos7: +Removing instruction print_sbyte_at_from_print_sbyte_pos8: +Removing instruction print_sbyte_at_from_print_sbyte_pos9: +Removing instruction print_sbyte_at_from_print_sbyte_pos10: +Removing instruction print_sbyte_at_from_print_sbyte_pos11: +Removing instruction print_sbyte_at_from_print_sbyte_pos12: Removing instruction b1_from_b32: +Removing instruction print_char_at_from_b3: Removing instruction b2_from_b3: Removing instruction b2_from_b5: +Removing instruction print_char_at_from_b1: Removing instruction b5_from_debug_print_init: Removing instruction print_str_at_from_b5: Removing instruction b6_from_b5: @@ -10533,7 +10563,6 @@ Removing instruction b25: Removing instruction b30: Removing instruction b1_from_b30: Removing instruction print_sbyte_pos1: -Removing instruction print_sbyte_at_from_print_sbyte_pos1: Removing instruction b3: Removing instruction print_sbyte_pos2: Removing instruction print_sbyte_at_from_print_sbyte_pos2: @@ -10543,28 +10572,20 @@ Removing instruction print_sbyte_pos4: Removing instruction print_sbyte_at_from_print_sbyte_pos4: Removing instruction b6: Removing instruction print_sbyte_pos5: -Removing instruction print_sbyte_at_from_print_sbyte_pos5: Removing instruction b7: Removing instruction print_sbyte_pos6: -Removing instruction print_sbyte_at_from_print_sbyte_pos6: Removing instruction b8: Removing instruction print_sbyte_pos7: -Removing instruction print_sbyte_at_from_print_sbyte_pos7: Removing instruction b9: Removing instruction print_sbyte_pos8: -Removing instruction print_sbyte_at_from_print_sbyte_pos8: Removing instruction b10: Removing instruction print_sbyte_pos9: -Removing instruction print_sbyte_at_from_print_sbyte_pos9: Removing instruction b11: Removing instruction print_sbyte_pos10: -Removing instruction print_sbyte_at_from_print_sbyte_pos10: Removing instruction b12: Removing instruction print_sbyte_pos11: -Removing instruction print_sbyte_at_from_print_sbyte_pos11: Removing instruction b13: Removing instruction print_sbyte_pos12: -Removing instruction print_sbyte_at_from_print_sbyte_pos12: Removing instruction b1_from_print_sbyte_pos12: Removing instruction print_sbyte_at_from_b1: Removing instruction b27: @@ -10580,9 +10601,7 @@ Removing instruction print_sbyte_at_from_b31: Removing instruction b32: Removing instruction breturn: Removing instruction b3: -Removing instruction print_char_at_from_b3: Removing instruction breturn: -Removing instruction print_char_at_from_b1: Removing instruction b5: Removing instruction breturn: Removing instruction print_char_at_from_print_byte_at: @@ -10633,8 +10652,8 @@ Succesful ASM optimization Pass5NextJumpElimination Removing instruction bbegin: Succesful ASM optimization Pass5UnusedLabelElimination Fixing long branch [306] bne b1 to beq -Fixing long branch [980] bne b2 to beq -Fixing long branch [990] bne b1 to beq +Fixing long branch [993] bne b2 to beq +Fixing long branch [1003] bne b1 to beq FINAL SYMBOL TABLE (label) @33 @@ -11377,7 +11396,6 @@ anim: { //SEG44 [27] (signed byte) calculate_matrix::sx#0 ← (signed byte) sx#10 -- vbsxx=vbsz1 ldx sx //SEG45 [28] (signed byte) calculate_matrix::sy#0 ← (signed byte) sy#10 - // (signed byte) calculate_matrix::sy#0 = (signed byte) sy#10 // register copy zp ZP_BYTE:3 //SEG46 [29] call calculate_matrix jsr calculate_matrix //SEG47 [30] phi from anim::@12 to anim::@27 [phi:anim::@12->anim::@27] @@ -11504,7 +11522,6 @@ debug_print: { ldx sx //SEG86 debug_print::print_sbyte_pos1 //SEG87 [57] (signed byte) print_sbyte_at::b#4 ← (signed byte) debug_print::print_sbyte_pos1_sb#0 - // (signed byte) print_sbyte_at::b#4 = (signed byte) debug_print::print_sbyte_pos1_sb#0 // register copy reg byte x //SEG88 [58] call print_sbyte_at //SEG89 [114] phi from debug_print::print_sbyte_pos1 to print_sbyte_at [phi:debug_print::print_sbyte_pos1->print_sbyte_at] //SEG90 [114] phi (byte*) print_sbyte_at::at#21 = (const byte*) print_line_cursor#0+(const byte) debug_print::print_sbyte_pos1_row#0*(byte/signed byte/word/signed word/dword/signed dword) 40+(const byte) debug_print::print_sbyte_pos1_col#0 [phi:debug_print::print_sbyte_pos1->print_sbyte_at#0] -- pbuz1=pbuc1 @@ -11561,7 +11578,6 @@ debug_print: { ldx rotation_matrix+1 //SEG116 debug_print::print_sbyte_pos5 //SEG117 [68] (signed byte) print_sbyte_at::b#8 ← (signed byte) debug_print::print_sbyte_pos5_sb#0 - // (signed byte) print_sbyte_at::b#8 = (signed byte) debug_print::print_sbyte_pos5_sb#0 // register copy reg byte x //SEG118 [69] call print_sbyte_at //SEG119 [114] phi from debug_print::print_sbyte_pos5 to print_sbyte_at [phi:debug_print::print_sbyte_pos5->print_sbyte_at] //SEG120 [114] phi (byte*) print_sbyte_at::at#21 = (const byte*) print_line_cursor#0+(const byte) debug_print::print_sbyte_pos5_row#0*(byte/signed byte/word/signed word/dword/signed dword) 40+(const byte) debug_print::print_sbyte_pos5_col#0 [phi:debug_print::print_sbyte_pos5->print_sbyte_at#0] -- pbuz1=pbuc1 @@ -11576,7 +11592,6 @@ debug_print: { ldx rotation_matrix+2 //SEG124 debug_print::print_sbyte_pos6 //SEG125 [71] (signed byte) print_sbyte_at::b#9 ← (signed byte) debug_print::print_sbyte_pos6_sb#0 - // (signed byte) print_sbyte_at::b#9 = (signed byte) debug_print::print_sbyte_pos6_sb#0 // register copy reg byte x //SEG126 [72] call print_sbyte_at //SEG127 [114] phi from debug_print::print_sbyte_pos6 to print_sbyte_at [phi:debug_print::print_sbyte_pos6->print_sbyte_at] //SEG128 [114] phi (byte*) print_sbyte_at::at#21 = (const byte*) print_line_cursor#0+(const byte) debug_print::print_sbyte_pos6_row#0*(byte/signed byte/word/signed word/dword/signed dword) 40+(const byte) debug_print::print_sbyte_pos6_col#0 [phi:debug_print::print_sbyte_pos6->print_sbyte_at#0] -- pbuz1=pbuc1 @@ -11591,7 +11606,6 @@ debug_print: { ldx rotation_matrix+3 //SEG132 debug_print::print_sbyte_pos7 //SEG133 [74] (signed byte) print_sbyte_at::b#10 ← (signed byte) debug_print::print_sbyte_pos7_sb#0 - // (signed byte) print_sbyte_at::b#10 = (signed byte) debug_print::print_sbyte_pos7_sb#0 // register copy reg byte x //SEG134 [75] call print_sbyte_at //SEG135 [114] phi from debug_print::print_sbyte_pos7 to print_sbyte_at [phi:debug_print::print_sbyte_pos7->print_sbyte_at] //SEG136 [114] phi (byte*) print_sbyte_at::at#21 = (const byte*) print_line_cursor#0+(const byte) debug_print::print_sbyte_pos7_row#0*(byte/signed byte/word/signed word/dword/signed dword) 40+(const byte) debug_print::print_sbyte_pos7_col#0 [phi:debug_print::print_sbyte_pos7->print_sbyte_at#0] -- pbuz1=pbuc1 @@ -11606,7 +11620,6 @@ debug_print: { ldx rotation_matrix+4 //SEG140 debug_print::print_sbyte_pos8 //SEG141 [77] (signed byte) print_sbyte_at::b#11 ← (signed byte) debug_print::print_sbyte_pos8_sb#0 - // (signed byte) print_sbyte_at::b#11 = (signed byte) debug_print::print_sbyte_pos8_sb#0 // register copy reg byte x //SEG142 [78] call print_sbyte_at //SEG143 [114] phi from debug_print::print_sbyte_pos8 to print_sbyte_at [phi:debug_print::print_sbyte_pos8->print_sbyte_at] //SEG144 [114] phi (byte*) print_sbyte_at::at#21 = (const byte*) print_line_cursor#0+(const byte) debug_print::print_sbyte_pos8_row#0*(byte/signed byte/word/signed word/dword/signed dword) 40+(const byte) debug_print::print_sbyte_pos8_col#0 [phi:debug_print::print_sbyte_pos8->print_sbyte_at#0] -- pbuz1=pbuc1 @@ -11621,7 +11634,6 @@ debug_print: { ldx rotation_matrix+5 //SEG148 debug_print::print_sbyte_pos9 //SEG149 [80] (signed byte) print_sbyte_at::b#12 ← (signed byte) debug_print::print_sbyte_pos9_sb#0 - // (signed byte) print_sbyte_at::b#12 = (signed byte) debug_print::print_sbyte_pos9_sb#0 // register copy reg byte x //SEG150 [81] call print_sbyte_at //SEG151 [114] phi from debug_print::print_sbyte_pos9 to print_sbyte_at [phi:debug_print::print_sbyte_pos9->print_sbyte_at] //SEG152 [114] phi (byte*) print_sbyte_at::at#21 = (const byte*) print_line_cursor#0+(const byte) debug_print::print_sbyte_pos9_row#0*(byte/signed byte/word/signed word/dword/signed dword) 40+(const byte) debug_print::print_sbyte_pos9_col#0 [phi:debug_print::print_sbyte_pos9->print_sbyte_at#0] -- pbuz1=pbuc1 @@ -11636,7 +11648,6 @@ debug_print: { ldx rotation_matrix+6 //SEG156 debug_print::print_sbyte_pos10 //SEG157 [83] (signed byte) print_sbyte_at::b#13 ← (signed byte) debug_print::print_sbyte_pos10_sb#0 - // (signed byte) print_sbyte_at::b#13 = (signed byte) debug_print::print_sbyte_pos10_sb#0 // register copy reg byte x //SEG158 [84] call print_sbyte_at //SEG159 [114] phi from debug_print::print_sbyte_pos10 to print_sbyte_at [phi:debug_print::print_sbyte_pos10->print_sbyte_at] //SEG160 [114] phi (byte*) print_sbyte_at::at#21 = (const byte*) print_line_cursor#0+(const byte) debug_print::print_sbyte_pos10_row#0*(byte/signed byte/word/signed word/dword/signed dword) 40+(const byte) debug_print::print_sbyte_pos10_col#0 [phi:debug_print::print_sbyte_pos10->print_sbyte_at#0] -- pbuz1=pbuc1 @@ -11651,7 +11662,6 @@ debug_print: { ldx rotation_matrix+7 //SEG164 debug_print::print_sbyte_pos11 //SEG165 [86] (signed byte) print_sbyte_at::b#14 ← (signed byte) debug_print::print_sbyte_pos11_sb#0 - // (signed byte) print_sbyte_at::b#14 = (signed byte) debug_print::print_sbyte_pos11_sb#0 // register copy reg byte x //SEG166 [87] call print_sbyte_at //SEG167 [114] phi from debug_print::print_sbyte_pos11 to print_sbyte_at [phi:debug_print::print_sbyte_pos11->print_sbyte_at] //SEG168 [114] phi (byte*) print_sbyte_at::at#21 = (const byte*) print_line_cursor#0+(const byte) debug_print::print_sbyte_pos11_row#0*(byte/signed byte/word/signed word/dword/signed dword) 40+(const byte) debug_print::print_sbyte_pos11_col#0 [phi:debug_print::print_sbyte_pos11->print_sbyte_at#0] -- pbuz1=pbuc1 @@ -11666,7 +11676,6 @@ debug_print: { ldx rotation_matrix+8 //SEG172 debug_print::print_sbyte_pos12 //SEG173 [89] (signed byte) print_sbyte_at::b#15 ← (signed byte) debug_print::print_sbyte_pos12_sb#0 - // (signed byte) print_sbyte_at::b#15 = (signed byte) debug_print::print_sbyte_pos12_sb#0 // register copy reg byte x //SEG174 [90] call print_sbyte_at //SEG175 [114] phi from debug_print::print_sbyte_pos12 to print_sbyte_at [phi:debug_print::print_sbyte_pos12->print_sbyte_at] //SEG176 [114] phi (byte*) print_sbyte_at::at#21 = (const byte*) print_line_cursor#0+(const byte) debug_print::print_sbyte_pos12_row#0*(byte/signed byte/word/signed word/dword/signed dword) 40+(const byte) debug_print::print_sbyte_pos12_col#0 [phi:debug_print::print_sbyte_pos12->print_sbyte_at#0] -- pbuz1=pbuc1 @@ -11814,6 +11823,7 @@ debug_print: { rts } //SEG232 print_sbyte_at +// Print a signed byte as hex at a specific screen position print_sbyte_at: { .label at = 6 //SEG233 [115] if((signed byte) print_sbyte_at::b#22<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte_at::@1 -- vbsxx_lt_0_then_la1 @@ -11821,7 +11831,6 @@ print_sbyte_at: { bmi b1 //SEG234 print_sbyte_at::@3 //SEG235 [116] (byte*) print_char_at::at#1 ← (byte*) print_sbyte_at::at#21 - // (byte*) print_char_at::at#1 = (byte*) print_sbyte_at::at#21 // register copy zp ZP_WORD:6 //SEG236 [117] call print_char_at //SEG237 [125] phi from print_sbyte_at::@3 to print_char_at [phi:print_sbyte_at::@3->print_char_at] //SEG238 [125] phi (byte*) print_char_at::at#4 = (byte*) print_char_at::at#1 [phi:print_sbyte_at::@3->print_char_at#0] -- register_copy @@ -11846,7 +11855,6 @@ print_sbyte_at: { //SEG247 print_sbyte_at::@1 b1: //SEG248 [122] (byte*) print_char_at::at#0 ← (byte*) print_sbyte_at::at#21 - // (byte*) print_char_at::at#0 = (byte*) print_sbyte_at::at#21 // register copy zp ZP_WORD:6 //SEG249 [123] call print_char_at //SEG250 [125] phi from print_sbyte_at::@1 to print_char_at [phi:print_sbyte_at::@1->print_char_at] //SEG251 [125] phi (byte*) print_char_at::at#4 = (byte*) print_char_at::at#0 [phi:print_sbyte_at::@1->print_char_at#0] -- register_copy @@ -11864,6 +11872,7 @@ print_sbyte_at: { jmp b2 } //SEG255 print_char_at +// Print a single char print_char_at: { .label at = 6 .label ch = 8 @@ -11876,6 +11885,7 @@ print_char_at: { rts } //SEG259 print_byte_at +// Print a byte as HEX at a specific position print_byte_at: { .label at = 6 //SEG260 [128] (byte~) print_byte_at::$0 ← (byte)(signed byte) print_sbyte_at::b#24 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 @@ -11889,7 +11899,6 @@ print_byte_at: { lda print_hextab,y sta print_char_at.ch //SEG262 [130] (byte*) print_char_at::at#2 ← (byte*) print_byte_at::at#0 - // (byte*) print_char_at::at#2 = (byte*) print_byte_at::at#0 // register copy zp ZP_WORD:6 //SEG263 [131] call print_char_at //SEG264 [125] phi from print_byte_at to print_char_at [phi:print_byte_at->print_char_at] //SEG265 [125] phi (byte*) print_char_at::at#4 = (byte*) print_char_at::at#2 [phi:print_byte_at->print_char_at#0] -- register_copy @@ -11918,6 +11927,10 @@ print_byte_at: { rts } //SEG277 rotate_matrix +// Rotate a 3D point (x,y,z) using the rotation matrix +// 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: { .label x = 5 //SEG278 [137] *((const signed byte*) xr#0) ← (signed byte) rotate_matrix::x#0 -- _deref_pbsc1=vbsz1 @@ -12021,6 +12034,9 @@ rotate_matrix: { rts } //SEG284 store_matrix +// Store the rotation matrix into the rotation routine rotate() +// After this each call to rotate() will rotate a point with the matrix +// Implemented in assembler to utilize seriously fast multiplication store_matrix: { //SEG285 asm { ldarotation_matrix+0 starotate_matrix.A1+1 eor#$ff starotate_matrix.A2+1 ldarotation_matrix+1 starotate_matrix.B1+1 eor#$ff starotate_matrix.B2+1 ldarotation_matrix+2 starotate_matrix.C1+1 eor#$ff starotate_matrix.C2+1 ldarotation_matrix+3 starotate_matrix.D1+1 eor#$ff starotate_matrix.D2+1 ldarotation_matrix+4 starotate_matrix.E1+1 eor#$ff starotate_matrix.E2+1 ldarotation_matrix+5 starotate_matrix.F1+1 eor#$ff starotate_matrix.F2+1 ldarotation_matrix+6 starotate_matrix.G1+1 eor#$ff starotate_matrix.G2+1 ldarotation_matrix+7 starotate_matrix.H1+1 eor#$ff starotate_matrix.H2+1 ldarotation_matrix+8 starotate_matrix.I1+1 eor#$ff starotate_matrix.I2+1 } lda rotation_matrix+0 @@ -12064,6 +12080,9 @@ store_matrix: { rts } //SEG288 calculate_matrix +// Prepare the 3x3 rotation matrix into rotation_matrix[] +// Angles sx, sy, sz are based on 2*PI=$100 +// Method described in C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt calculate_matrix: { .label sy = 3 .label t1 = 4 @@ -12759,6 +12778,7 @@ debug_print_init: { str11: .text "yp@" } //SEG478 print_str_at +// Print a string at a specific screen position print_str_at: { .label at = 9 .label str = 6 @@ -12794,6 +12814,7 @@ print_str_at: { jmp b1 } //SEG490 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 6 //SEG491 [268] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -12827,6 +12848,7 @@ print_cls: { rts } //SEG501 sprites_init +// Initialize sprites sprites_init: { .label SCREEN = $400 .label sprites_ptr = SCREEN+$3f8 diff --git a/src/test/ref/examples/3d/perspective.asm b/src/test/ref/examples/3d/perspective.asm index 7ad69c8f5..457534b66 100644 --- a/src/test/ref/examples/3d/perspective.asm +++ b/src/test/ref/examples/3d/perspective.asm @@ -82,6 +82,7 @@ do_perspective: { str4: .text ",@" str5: .text ")@" } +// Print a newline print_ln: { lda #<$400 sta print_line_cursor @@ -105,6 +106,7 @@ print_ln: { !: rts } +// Print a zero-terminated string print_str: { .label str = 2 b1: @@ -127,6 +129,7 @@ print_str: { !: jmp b1 } +// Print a byte as HEX print_byte: { txa lsr @@ -143,6 +146,7 @@ print_byte: { jsr print_char rts } +// Print a single char print_char: { ldy #0 sta (print_char_cursor),y @@ -152,6 +156,8 @@ print_char: { !: rts } +// Apply perspective to a 3d-point. Result is returned in (*xr,*yr) +// Implemented in assembler to utilize seriously fast multiplication perspective: { lda #do_perspective.x sta xr @@ -179,6 +185,7 @@ perspective: { sta xr rts } +// Print a signed byte as HEX print_sbyte: { cpx #0 bmi b1 @@ -197,6 +204,7 @@ print_sbyte: { tax jmp b2 } +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 lda #<$400 @@ -219,6 +227,7 @@ print_cls: { bne b1 rts } +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x) and g(x) = f(1-x) mulf_init: { .label val = 6 .label sqr = 2 diff --git a/src/test/ref/examples/3d/perspective.log b/src/test/ref/examples/3d/perspective.log index 9cf96f4a2..b9b0476ef 100644 --- a/src/test/ref/examples/3d/perspective.log +++ b/src/test/ref/examples/3d/perspective.log @@ -2176,6 +2176,7 @@ do_perspective: { str5: .text ")@" } //SEG94 print_ln +// Print a newline print_ln: { //SEG95 [40] phi from print_ln to print_ln::@1 [phi:print_ln->print_ln::@1] b1_from_print_ln: @@ -2215,6 +2216,7 @@ print_ln: { rts } //SEG104 print_str +// Print a zero-terminated string print_str: { .label str = 4 //SEG105 [45] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -2255,6 +2257,7 @@ print_str: { jmp b1_from_b2 } //SEG116 print_byte +// Print a byte as HEX print_byte: { .label _0 = $12 .label _2 = $13 @@ -2300,6 +2303,7 @@ print_byte: { rts } //SEG132 print_char +// Print a single char print_char: { .label ch = 7 //SEG133 [60] *((byte*) print_char_cursor#44) ← (byte) print_char::ch#4 -- _deref_pbuz1=vbuz2 @@ -2318,6 +2322,8 @@ print_char: { rts } //SEG137 perspective +// Apply perspective to a 3d-point. Result is returned in (*xr,*yr) +// Implemented in assembler to utilize seriously fast multiplication perspective: { //SEG138 [63] *((const signed byte*) xr#0) ← (const signed byte) do_perspective::x#0 -- _deref_pbsc1=vbsc2 lda #do_perspective.x @@ -2355,6 +2361,7 @@ perspective: { rts } //SEG144 print_sbyte +// Print a signed byte as HEX print_sbyte: { .label b = $a //SEG145 [69] if((signed byte) print_sbyte::b#4<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsz1_lt_0_then_la1 @@ -2419,6 +2426,7 @@ print_sbyte: { jmp b2_from_b5 } //SEG170 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = $b //SEG171 [80] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -2458,6 +2466,7 @@ print_cls: { rts } //SEG181 mulf_init +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x) and g(x) = f(1-x) mulf_init: { .label _2 = $15 .label _4 = $16 @@ -2960,6 +2969,7 @@ do_perspective: { str5: .text ")@" } //SEG94 print_ln +// Print a newline print_ln: { //SEG95 [40] phi from print_ln to print_ln::@1 [phi:print_ln->print_ln::@1] b1_from_print_ln: @@ -2999,6 +3009,7 @@ print_ln: { rts } //SEG104 print_str +// Print a zero-terminated string print_str: { .label str = 2 //SEG105 [45] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -3039,6 +3050,7 @@ print_str: { jmp b1_from_b2 } //SEG116 print_byte +// Print a byte as HEX print_byte: { //SEG117 [52] (byte~) print_byte::$0 ← (byte) print_byte::b#3 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -3077,6 +3089,7 @@ print_byte: { rts } //SEG132 print_char +// Print a single char print_char: { //SEG133 [60] *((byte*) print_char_cursor#44) ← (byte) print_char::ch#4 -- _deref_pbuz1=vbuaa ldy #0 @@ -3093,6 +3106,8 @@ print_char: { rts } //SEG137 perspective +// Apply perspective to a 3d-point. Result is returned in (*xr,*yr) +// Implemented in assembler to utilize seriously fast multiplication perspective: { //SEG138 [63] *((const signed byte*) xr#0) ← (const signed byte) do_perspective::x#0 -- _deref_pbsc1=vbsc2 lda #do_perspective.x @@ -3130,6 +3145,7 @@ perspective: { rts } //SEG144 print_sbyte +// Print a signed byte as HEX print_sbyte: { //SEG145 [69] if((signed byte) print_sbyte::b#4<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsxx_lt_0_then_la1 cpx #0 @@ -3154,7 +3170,6 @@ print_sbyte: { //SEG154 print_sbyte::@2 b2: //SEG155 [73] (byte~) print_byte::b#7 ← (byte)(signed byte) print_sbyte::b#6 - // (byte~) print_byte::b#7 = (byte)(signed byte) print_sbyte::b#6 // register copy reg byte x //SEG156 [74] call print_byte //SEG157 [51] phi from print_sbyte::@2 to print_byte [phi:print_sbyte::@2->print_byte] print_byte_from_b2: @@ -3190,6 +3205,7 @@ print_sbyte: { jmp b2_from_b5 } //SEG170 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG171 [80] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -3229,6 +3245,7 @@ print_cls: { rts } //SEG181 mulf_init +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x) and g(x) = f(1-x) mulf_init: { .label val = 6 .label sqr = 2 @@ -3438,6 +3455,7 @@ Removing instruction b3_from_print_sbyte: Removing instruction print_char_from_b3: Removing instruction b2_from_b3: Removing instruction b2_from_b5: +Removing instruction print_byte_from_b2: Removing instruction b1_from_print_sbyte: Removing instruction print_char_from_b1: Removing instruction b1_from_b1: @@ -3475,7 +3493,6 @@ Removing instruction breturn: Removing instruction breturn: Removing instruction breturn: Removing instruction b3: -Removing instruction print_byte_from_b2: Removing instruction breturn: Removing instruction b5: Removing instruction b1_from_print_cls: @@ -3899,6 +3916,7 @@ do_perspective: { str5: .text ")@" } //SEG94 print_ln +// Print a newline print_ln: { //SEG95 [40] phi from print_ln to print_ln::@1 [phi:print_ln->print_ln::@1] //SEG96 [40] phi (byte*) print_line_cursor#11 = ((byte*))(word/signed word/dword/signed dword) 1024 [phi:print_ln->print_ln::@1#0] -- pbuz1=pbuc1 @@ -3932,6 +3950,7 @@ print_ln: { rts } //SEG104 print_str +// Print a zero-terminated string print_str: { .label str = 2 //SEG105 [45] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -3966,6 +3985,7 @@ print_str: { jmp b1 } //SEG116 print_byte +// Print a byte as HEX print_byte: { //SEG117 [52] (byte~) print_byte::$0 ← (byte) print_byte::b#3 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -3998,6 +4018,7 @@ print_byte: { rts } //SEG132 print_char +// Print a single char print_char: { //SEG133 [60] *((byte*) print_char_cursor#44) ← (byte) print_char::ch#4 -- _deref_pbuz1=vbuaa ldy #0 @@ -4012,6 +4033,8 @@ print_char: { rts } //SEG137 perspective +// Apply perspective to a 3d-point. Result is returned in (*xr,*yr) +// Implemented in assembler to utilize seriously fast multiplication perspective: { //SEG138 [63] *((const signed byte*) xr#0) ← (const signed byte) do_perspective::x#0 -- _deref_pbsc1=vbsc2 lda #do_perspective.x @@ -4046,6 +4069,7 @@ perspective: { rts } //SEG144 print_sbyte +// Print a signed byte as HEX print_sbyte: { //SEG145 [69] if((signed byte) print_sbyte::b#4<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsxx_lt_0_then_la1 cpx #0 @@ -4063,7 +4087,6 @@ print_sbyte: { //SEG154 print_sbyte::@2 b2: //SEG155 [73] (byte~) print_byte::b#7 ← (byte)(signed byte) print_sbyte::b#6 - // (byte~) print_byte::b#7 = (byte)(signed byte) print_sbyte::b#6 // register copy reg byte x //SEG156 [74] call print_byte //SEG157 [51] phi from print_sbyte::@2 to print_byte [phi:print_sbyte::@2->print_byte] //SEG158 [51] phi (byte*) print_char_cursor#69 = (byte*) print_char_cursor#12 [phi:print_sbyte::@2->print_byte#0] -- register_copy @@ -4091,6 +4114,7 @@ print_sbyte: { jmp b2 } //SEG170 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG171 [80] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -4124,6 +4148,7 @@ print_cls: { rts } //SEG181 mulf_init +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x) and g(x) = f(1-x) mulf_init: { .label val = 6 .label sqr = 2 diff --git a/src/test/ref/examples/bresenham/bitmap-bresenham.asm b/src/test/ref/examples/bresenham/bitmap-bresenham.asm index cb2b6bfe9..b75f79f20 100644 --- a/src/test/ref/examples/bresenham/bitmap-bresenham.asm +++ b/src/test/ref/examples/bresenham/bitmap-bresenham.asm @@ -47,6 +47,7 @@ lines: { bcc b1 rts } +// Draw a line on the bitmap bitmap_line: { .label xd = 4 .label yd = 3 @@ -325,6 +326,7 @@ init_screen: { bne b1 rts } +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = 9 .label y = 2 @@ -354,6 +356,7 @@ bitmap_clear: { bne b1 rts } +// Initialize the bitmap plotter tables for a specific bitmap bitmap_init: { .label _6 = 2 .label yoffs = 9 diff --git a/src/test/ref/examples/bresenham/bitmap-bresenham.log b/src/test/ref/examples/bresenham/bitmap-bresenham.log index 4ac8b9b40..288cef91c 100644 --- a/src/test/ref/examples/bresenham/bitmap-bresenham.log +++ b/src/test/ref/examples/bresenham/bitmap-bresenham.log @@ -2951,6 +2951,7 @@ lines: { rts } //SEG42 bitmap_line +// Draw a line on the bitmap bitmap_line: { .label xd = $2f .label xd_1 = $2c @@ -3664,6 +3665,7 @@ init_screen: { rts } //SEG299 bitmap_clear +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = $20 .label x = $22 @@ -3738,6 +3740,7 @@ bitmap_clear: { rts } //SEG325 bitmap_init +// Initialize the bitmap plotter tables for a specific bitmap bitmap_init: { .label _0 = $3f .label _6 = $40 @@ -4370,6 +4373,7 @@ lines: { rts } //SEG42 bitmap_line +// Draw a line on the bitmap bitmap_line: { .label xd = 4 .label yd = 3 @@ -4415,11 +4419,8 @@ bitmap_line: { //SEG52 [31] (byte) bitmap_line_ydxi::x#0 ← (byte) bitmap_line::x1#0 -- vbuxx=vbuz1 ldx x1 //SEG53 [32] (byte) bitmap_line_ydxi::y1#0 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_ydxi::y1#0 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:6 //SEG54 [33] (byte) bitmap_line_ydxi::yd#0 ← (byte) bitmap_line::yd#1 - // (byte) bitmap_line_ydxi::yd#0 = (byte) bitmap_line::yd#1 // register copy zp ZP_BYTE:3 //SEG55 [34] (byte) bitmap_line_ydxi::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_ydxi::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:4 //SEG56 [35] call bitmap_line_ydxi //SEG57 [109] phi from bitmap_line::@17 to bitmap_line_ydxi [phi:bitmap_line::@17->bitmap_line_ydxi] bitmap_line_ydxi_from_b17: @@ -4441,11 +4442,8 @@ bitmap_line: { //SEG67 [38] (byte) bitmap_line_xdyi::y#0 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_xdyi.y //SEG68 [39] (byte) bitmap_line_xdyi::x1#0 ← (byte) bitmap_line::x0#0 - // (byte) bitmap_line_xdyi::x1#0 = (byte) bitmap_line::x0#0 // register copy zp ZP_BYTE:5 //SEG69 [40] (byte) bitmap_line_xdyi::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_xdyi::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:4 //SEG70 [41] (byte) bitmap_line_xdyi::yd#0 ← (byte) bitmap_line::yd#1 - // (byte) bitmap_line_xdyi::yd#0 = (byte) bitmap_line::yd#1 // register copy zp ZP_BYTE:3 //SEG71 [42] call bitmap_line_xdyi //SEG72 [87] phi from bitmap_line::@3 to bitmap_line_xdyi [phi:bitmap_line::@3->bitmap_line_xdyi] bitmap_line_xdyi_from_b3: @@ -4478,9 +4476,7 @@ bitmap_line: { //SEG84 [47] (byte) bitmap_line_ydxd::y1#0 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_ydxd.y1 //SEG85 [48] (byte) bitmap_line_ydxd::yd#0 ← (byte) bitmap_line::yd#0 - // (byte) bitmap_line_ydxd::yd#0 = (byte) bitmap_line::yd#0 // register copy zp ZP_BYTE:3 //SEG86 [49] (byte) bitmap_line_ydxd::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_ydxd::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:4 //SEG87 [50] call bitmap_line_ydxd //SEG88 [139] phi from bitmap_line::@20 to bitmap_line_ydxd [phi:bitmap_line::@20->bitmap_line_ydxd] bitmap_line_ydxd_from_b20: @@ -4501,9 +4497,7 @@ bitmap_line: { lda x0 sta bitmap_line_xdyd.x1 //SEG98 [54] (byte) bitmap_line_xdyd::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_xdyd::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:4 //SEG99 [55] (byte) bitmap_line_xdyd::yd#0 ← (byte) bitmap_line::yd#0 - // (byte) bitmap_line_xdyd::yd#0 = (byte) bitmap_line::yd#0 // register copy zp ZP_BYTE:3 //SEG100 [56] call bitmap_line_xdyd //SEG101 [124] phi from bitmap_line::@6 to bitmap_line_xdyd [phi:bitmap_line::@6->bitmap_line_xdyd] bitmap_line_xdyd_from_b6: @@ -4548,11 +4542,8 @@ bitmap_line: { //SEG115 [62] (byte) bitmap_line_ydxd::x#1 ← (byte) bitmap_line::x1#0 -- vbuxx=vbuz1 ldx x1 //SEG116 [63] (byte) bitmap_line_ydxd::y1#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_ydxd::y1#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:6 //SEG117 [64] (byte) bitmap_line_ydxd::yd#1 ← (byte) bitmap_line::yd#3 - // (byte) bitmap_line_ydxd::yd#1 = (byte) bitmap_line::yd#3 // register copy zp ZP_BYTE:3 //SEG118 [65] (byte) bitmap_line_ydxd::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_ydxd::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:4 //SEG119 [66] call bitmap_line_ydxd //SEG120 [139] phi from bitmap_line::@24 to bitmap_line_ydxd [phi:bitmap_line::@24->bitmap_line_ydxd] bitmap_line_ydxd_from_b24: @@ -4568,13 +4559,9 @@ bitmap_line: { //SEG127 [67] (byte) bitmap_line_xdyd::x#1 ← (byte) bitmap_line::x0#0 -- vbuxx=vbuz1 ldx x0 //SEG128 [68] (byte) bitmap_line_xdyd::y#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_xdyd::y#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:6 //SEG129 [69] (byte) bitmap_line_xdyd::x1#1 ← (byte) bitmap_line::x1#0 - // (byte) bitmap_line_xdyd::x1#1 = (byte) bitmap_line::x1#0 // register copy zp ZP_BYTE:8 //SEG130 [70] (byte) bitmap_line_xdyd::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_xdyd::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:4 //SEG131 [71] (byte) bitmap_line_xdyd::yd#1 ← (byte) bitmap_line::yd#3 - // (byte) bitmap_line_xdyd::yd#1 = (byte) bitmap_line::yd#3 // register copy zp ZP_BYTE:3 //SEG132 [72] call bitmap_line_xdyd //SEG133 [124] phi from bitmap_line::@10 to bitmap_line_xdyd [phi:bitmap_line::@10->bitmap_line_xdyd] bitmap_line_xdyd_from_b10: @@ -4607,9 +4594,7 @@ bitmap_line: { //SEG145 [77] (byte) bitmap_line_ydxi::y1#1 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_ydxi.y1 //SEG146 [78] (byte) bitmap_line_ydxi::yd#1 ← (byte) bitmap_line::yd#10 - // (byte) bitmap_line_ydxi::yd#1 = (byte) bitmap_line::yd#10 // register copy zp ZP_BYTE:3 //SEG147 [79] (byte) bitmap_line_ydxi::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_ydxi::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:4 //SEG148 [80] call bitmap_line_ydxi //SEG149 [109] phi from bitmap_line::@27 to bitmap_line_ydxi [phi:bitmap_line::@27->bitmap_line_ydxi] bitmap_line_ydxi_from_b27: @@ -4625,14 +4610,11 @@ bitmap_line: { //SEG156 [81] (byte) bitmap_line_xdyi::x#1 ← (byte) bitmap_line::x0#0 -- vbuxx=vbuz1 ldx x0 //SEG157 [82] (byte) bitmap_line_xdyi::y#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_xdyi::y#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:6 //SEG158 [83] (byte) bitmap_line_xdyi::x1#1 ← (byte) bitmap_line::x1#0 -- vbuz1=vbuz2 lda x1 sta bitmap_line_xdyi.x1 //SEG159 [84] (byte) bitmap_line_xdyi::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_xdyi::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:4 //SEG160 [85] (byte) bitmap_line_xdyi::yd#1 ← (byte) bitmap_line::yd#10 - // (byte) bitmap_line_xdyi::yd#1 = (byte) bitmap_line::yd#10 // register copy zp ZP_BYTE:3 //SEG161 [86] call bitmap_line_xdyi //SEG162 [87] phi from bitmap_line::@13 to bitmap_line_xdyi [phi:bitmap_line::@13->bitmap_line_xdyi] bitmap_line_xdyi_from_b13: @@ -4666,7 +4648,6 @@ bitmap_line_xdyi: { //SEG174 bitmap_line_xdyi::@1 b1: //SEG175 [90] (byte) bitmap_plot::x#0 ← (byte) bitmap_line_xdyi::x#3 - // (byte) bitmap_plot::x#0 = (byte) bitmap_line_xdyi::x#3 // register copy reg byte x //SEG176 [91] (byte) bitmap_plot::y#0 ← (byte) bitmap_line_xdyi::y#3 -- vbuyy=vbuz1 ldy y //SEG177 [92] call bitmap_plot @@ -4777,7 +4758,6 @@ bitmap_line_ydxi: { //SEG210 bitmap_line_ydxi::@1 b1: //SEG211 [112] (byte) bitmap_plot::x#2 ← (byte) bitmap_line_ydxi::x#3 - // (byte) bitmap_plot::x#2 = (byte) bitmap_line_ydxi::x#3 // register copy reg byte x //SEG212 [113] (byte) bitmap_plot::y#2 ← (byte) bitmap_line_ydxi::y#3 -- vbuyy=vbuz1 ldy y //SEG213 [114] call bitmap_plot @@ -4852,7 +4832,6 @@ bitmap_line_xdyd: { //SEG238 bitmap_line_xdyd::@1 b1: //SEG239 [127] (byte) bitmap_plot::x#1 ← (byte) bitmap_line_xdyd::x#3 - // (byte) bitmap_plot::x#1 = (byte) bitmap_line_xdyd::x#3 // register copy reg byte x //SEG240 [128] (byte) bitmap_plot::y#1 ← (byte) bitmap_line_xdyd::y#3 -- vbuyy=vbuz1 ldy y //SEG241 [129] call bitmap_plot @@ -4927,7 +4906,6 @@ bitmap_line_ydxd: { //SEG266 bitmap_line_ydxd::@1 b1: //SEG267 [142] (byte) bitmap_plot::x#3 ← (byte) bitmap_line_ydxd::x#3 - // (byte) bitmap_plot::x#3 = (byte) bitmap_line_ydxd::x#3 // register copy reg byte x //SEG268 [143] (byte) bitmap_plot::y#3 ← (byte) bitmap_line_ydxd::y#2 -- vbuyy=vbuz1 ldy y //SEG269 [144] call bitmap_plot @@ -5020,6 +4998,7 @@ init_screen: { rts } //SEG299 bitmap_clear +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = 9 .label y = 2 @@ -5030,7 +5009,6 @@ bitmap_clear: { lda bitmap_plot_xhi sta _3+1 //SEG301 [161] (byte*~) bitmap_clear::bitmap#5 ← (byte*)(word~) bitmap_clear::$3 - // (byte*~) bitmap_clear::bitmap#5 = (byte*)(word~) bitmap_clear::$3 // register copy zp ZP_WORD:9 //SEG302 [162] phi from bitmap_clear to bitmap_clear::@1 [phi:bitmap_clear->bitmap_clear::@1] b1_from_bitmap_clear: //SEG303 [162] phi (byte) bitmap_clear::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:bitmap_clear->bitmap_clear::@1#0] -- vbuz1=vbuc1 @@ -5088,6 +5066,7 @@ bitmap_clear: { rts } //SEG325 bitmap_init +// Initialize the bitmap plotter tables for a specific bitmap bitmap_init: { .label _6 = 2 .label yoffs = 9 @@ -5911,6 +5890,7 @@ lines: { rts } //SEG42 bitmap_line +// Draw a line on the bitmap bitmap_line: { .label xd = 4 .label yd = 3 @@ -5948,11 +5928,8 @@ bitmap_line: { //SEG52 [31] (byte) bitmap_line_ydxi::x#0 ← (byte) bitmap_line::x1#0 -- vbuxx=vbuz1 ldx x1 //SEG53 [32] (byte) bitmap_line_ydxi::y1#0 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_ydxi::y1#0 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:6 //SEG54 [33] (byte) bitmap_line_ydxi::yd#0 ← (byte) bitmap_line::yd#1 - // (byte) bitmap_line_ydxi::yd#0 = (byte) bitmap_line::yd#1 // register copy zp ZP_BYTE:3 //SEG55 [34] (byte) bitmap_line_ydxi::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_ydxi::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:4 //SEG56 [35] call bitmap_line_ydxi //SEG57 [109] phi from bitmap_line::@17 to bitmap_line_ydxi [phi:bitmap_line::@17->bitmap_line_ydxi] //SEG58 [109] phi (byte) bitmap_line_ydxi::y1#6 = (byte) bitmap_line_ydxi::y1#0 [phi:bitmap_line::@17->bitmap_line_ydxi#0] -- register_copy @@ -5972,11 +5949,8 @@ bitmap_line: { //SEG67 [38] (byte) bitmap_line_xdyi::y#0 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_xdyi.y //SEG68 [39] (byte) bitmap_line_xdyi::x1#0 ← (byte) bitmap_line::x0#0 - // (byte) bitmap_line_xdyi::x1#0 = (byte) bitmap_line::x0#0 // register copy zp ZP_BYTE:5 //SEG69 [40] (byte) bitmap_line_xdyi::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_xdyi::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:4 //SEG70 [41] (byte) bitmap_line_xdyi::yd#0 ← (byte) bitmap_line::yd#1 - // (byte) bitmap_line_xdyi::yd#0 = (byte) bitmap_line::yd#1 // register copy zp ZP_BYTE:3 //SEG71 [42] call bitmap_line_xdyi //SEG72 [87] phi from bitmap_line::@3 to bitmap_line_xdyi [phi:bitmap_line::@3->bitmap_line_xdyi] //SEG73 [87] phi (byte) bitmap_line_xdyi::x1#6 = (byte) bitmap_line_xdyi::x1#0 [phi:bitmap_line::@3->bitmap_line_xdyi#0] -- register_copy @@ -6005,9 +5979,7 @@ bitmap_line: { //SEG84 [47] (byte) bitmap_line_ydxd::y1#0 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_ydxd.y1 //SEG85 [48] (byte) bitmap_line_ydxd::yd#0 ← (byte) bitmap_line::yd#0 - // (byte) bitmap_line_ydxd::yd#0 = (byte) bitmap_line::yd#0 // register copy zp ZP_BYTE:3 //SEG86 [49] (byte) bitmap_line_ydxd::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_ydxd::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:4 //SEG87 [50] call bitmap_line_ydxd //SEG88 [139] phi from bitmap_line::@20 to bitmap_line_ydxd [phi:bitmap_line::@20->bitmap_line_ydxd] //SEG89 [139] phi (byte) bitmap_line_ydxd::y1#6 = (byte) bitmap_line_ydxd::y1#0 [phi:bitmap_line::@20->bitmap_line_ydxd#0] -- register_copy @@ -6027,9 +5999,7 @@ bitmap_line: { lda x0 sta bitmap_line_xdyd.x1 //SEG98 [54] (byte) bitmap_line_xdyd::xd#0 ← (byte) bitmap_line::xd#1 - // (byte) bitmap_line_xdyd::xd#0 = (byte) bitmap_line::xd#1 // register copy zp ZP_BYTE:4 //SEG99 [55] (byte) bitmap_line_xdyd::yd#0 ← (byte) bitmap_line::yd#0 - // (byte) bitmap_line_xdyd::yd#0 = (byte) bitmap_line::yd#0 // register copy zp ZP_BYTE:3 //SEG100 [56] call bitmap_line_xdyd //SEG101 [124] phi from bitmap_line::@6 to bitmap_line_xdyd [phi:bitmap_line::@6->bitmap_line_xdyd] //SEG102 [124] phi (byte) bitmap_line_xdyd::x1#6 = (byte) bitmap_line_xdyd::x1#0 [phi:bitmap_line::@6->bitmap_line_xdyd#0] -- register_copy @@ -6068,11 +6038,8 @@ bitmap_line: { //SEG115 [62] (byte) bitmap_line_ydxd::x#1 ← (byte) bitmap_line::x1#0 -- vbuxx=vbuz1 ldx x1 //SEG116 [63] (byte) bitmap_line_ydxd::y1#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_ydxd::y1#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:6 //SEG117 [64] (byte) bitmap_line_ydxd::yd#1 ← (byte) bitmap_line::yd#3 - // (byte) bitmap_line_ydxd::yd#1 = (byte) bitmap_line::yd#3 // register copy zp ZP_BYTE:3 //SEG118 [65] (byte) bitmap_line_ydxd::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_ydxd::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:4 //SEG119 [66] call bitmap_line_ydxd //SEG120 [139] phi from bitmap_line::@24 to bitmap_line_ydxd [phi:bitmap_line::@24->bitmap_line_ydxd] //SEG121 [139] phi (byte) bitmap_line_ydxd::y1#6 = (byte) bitmap_line_ydxd::y1#1 [phi:bitmap_line::@24->bitmap_line_ydxd#0] -- register_copy @@ -6087,13 +6054,9 @@ bitmap_line: { //SEG127 [67] (byte) bitmap_line_xdyd::x#1 ← (byte) bitmap_line::x0#0 -- vbuxx=vbuz1 ldx x0 //SEG128 [68] (byte) bitmap_line_xdyd::y#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_xdyd::y#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:6 //SEG129 [69] (byte) bitmap_line_xdyd::x1#1 ← (byte) bitmap_line::x1#0 - // (byte) bitmap_line_xdyd::x1#1 = (byte) bitmap_line::x1#0 // register copy zp ZP_BYTE:8 //SEG130 [70] (byte) bitmap_line_xdyd::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_xdyd::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:4 //SEG131 [71] (byte) bitmap_line_xdyd::yd#1 ← (byte) bitmap_line::yd#3 - // (byte) bitmap_line_xdyd::yd#1 = (byte) bitmap_line::yd#3 // register copy zp ZP_BYTE:3 //SEG132 [72] call bitmap_line_xdyd //SEG133 [124] phi from bitmap_line::@10 to bitmap_line_xdyd [phi:bitmap_line::@10->bitmap_line_xdyd] //SEG134 [124] phi (byte) bitmap_line_xdyd::x1#6 = (byte) bitmap_line_xdyd::x1#1 [phi:bitmap_line::@10->bitmap_line_xdyd#0] -- register_copy @@ -6122,9 +6085,7 @@ bitmap_line: { //SEG145 [77] (byte) bitmap_line_ydxi::y1#1 ← (byte) bitmap_line::y1#0 -- vbuz1=vbuyy sty bitmap_line_ydxi.y1 //SEG146 [78] (byte) bitmap_line_ydxi::yd#1 ← (byte) bitmap_line::yd#10 - // (byte) bitmap_line_ydxi::yd#1 = (byte) bitmap_line::yd#10 // register copy zp ZP_BYTE:3 //SEG147 [79] (byte) bitmap_line_ydxi::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_ydxi::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:4 //SEG148 [80] call bitmap_line_ydxi //SEG149 [109] phi from bitmap_line::@27 to bitmap_line_ydxi [phi:bitmap_line::@27->bitmap_line_ydxi] //SEG150 [109] phi (byte) bitmap_line_ydxi::y1#6 = (byte) bitmap_line_ydxi::y1#1 [phi:bitmap_line::@27->bitmap_line_ydxi#0] -- register_copy @@ -6139,14 +6100,11 @@ bitmap_line: { //SEG156 [81] (byte) bitmap_line_xdyi::x#1 ← (byte) bitmap_line::x0#0 -- vbuxx=vbuz1 ldx x0 //SEG157 [82] (byte) bitmap_line_xdyi::y#1 ← (byte) bitmap_line::y0#0 - // (byte) bitmap_line_xdyi::y#1 = (byte) bitmap_line::y0#0 // register copy zp ZP_BYTE:6 //SEG158 [83] (byte) bitmap_line_xdyi::x1#1 ← (byte) bitmap_line::x1#0 -- vbuz1=vbuz2 lda x1 sta bitmap_line_xdyi.x1 //SEG159 [84] (byte) bitmap_line_xdyi::xd#1 ← (byte) bitmap_line::xd#0 - // (byte) bitmap_line_xdyi::xd#1 = (byte) bitmap_line::xd#0 // register copy zp ZP_BYTE:4 //SEG160 [85] (byte) bitmap_line_xdyi::yd#1 ← (byte) bitmap_line::yd#10 - // (byte) bitmap_line_xdyi::yd#1 = (byte) bitmap_line::yd#10 // register copy zp ZP_BYTE:3 //SEG161 [86] call bitmap_line_xdyi //SEG162 [87] phi from bitmap_line::@13 to bitmap_line_xdyi [phi:bitmap_line::@13->bitmap_line_xdyi] //SEG163 [87] phi (byte) bitmap_line_xdyi::x1#6 = (byte) bitmap_line_xdyi::x1#1 [phi:bitmap_line::@13->bitmap_line_xdyi#0] -- register_copy @@ -6176,7 +6134,6 @@ bitmap_line_xdyi: { //SEG174 bitmap_line_xdyi::@1 b1: //SEG175 [90] (byte) bitmap_plot::x#0 ← (byte) bitmap_line_xdyi::x#3 - // (byte) bitmap_plot::x#0 = (byte) bitmap_line_xdyi::x#3 // register copy reg byte x //SEG176 [91] (byte) bitmap_plot::y#0 ← (byte) bitmap_line_xdyi::y#3 -- vbuyy=vbuz1 ldy y //SEG177 [92] call bitmap_plot @@ -6271,7 +6228,6 @@ bitmap_line_ydxi: { //SEG210 bitmap_line_ydxi::@1 b1: //SEG211 [112] (byte) bitmap_plot::x#2 ← (byte) bitmap_line_ydxi::x#3 - // (byte) bitmap_plot::x#2 = (byte) bitmap_line_ydxi::x#3 // register copy reg byte x //SEG212 [113] (byte) bitmap_plot::y#2 ← (byte) bitmap_line_ydxi::y#3 -- vbuyy=vbuz1 ldy y //SEG213 [114] call bitmap_plot @@ -6333,7 +6289,6 @@ bitmap_line_xdyd: { //SEG238 bitmap_line_xdyd::@1 b1: //SEG239 [127] (byte) bitmap_plot::x#1 ← (byte) bitmap_line_xdyd::x#3 - // (byte) bitmap_plot::x#1 = (byte) bitmap_line_xdyd::x#3 // register copy reg byte x //SEG240 [128] (byte) bitmap_plot::y#1 ← (byte) bitmap_line_xdyd::y#3 -- vbuyy=vbuz1 ldy y //SEG241 [129] call bitmap_plot @@ -6395,7 +6350,6 @@ bitmap_line_ydxd: { //SEG266 bitmap_line_ydxd::@1 b1: //SEG267 [142] (byte) bitmap_plot::x#3 ← (byte) bitmap_line_ydxd::x#3 - // (byte) bitmap_plot::x#3 = (byte) bitmap_line_ydxd::x#3 // register copy reg byte x //SEG268 [143] (byte) bitmap_plot::y#3 ← (byte) bitmap_line_ydxd::y#2 -- vbuyy=vbuz1 ldy y //SEG269 [144] call bitmap_plot @@ -6472,6 +6426,7 @@ init_screen: { rts } //SEG299 bitmap_clear +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = 9 .label y = 2 @@ -6482,7 +6437,6 @@ bitmap_clear: { lda bitmap_plot_xhi sta _3+1 //SEG301 [161] (byte*~) bitmap_clear::bitmap#5 ← (byte*)(word~) bitmap_clear::$3 - // (byte*~) bitmap_clear::bitmap#5 = (byte*)(word~) bitmap_clear::$3 // register copy zp ZP_WORD:9 //SEG302 [162] phi from bitmap_clear to bitmap_clear::@1 [phi:bitmap_clear->bitmap_clear::@1] //SEG303 [162] phi (byte) bitmap_clear::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:bitmap_clear->bitmap_clear::@1#0] -- vbuz1=vbuc1 lda #0 @@ -6528,6 +6482,7 @@ bitmap_clear: { rts } //SEG325 bitmap_init +// Initialize the bitmap plotter tables for a specific bitmap bitmap_init: { .label _6 = 2 .label yoffs = 9 diff --git a/src/test/ref/examples/chargen/chargen-analysis.asm b/src/test/ref/examples/chargen/chargen-analysis.asm index f57891c6b..951d6c067 100644 --- a/src/test/ref/examples/chargen/chargen-analysis.asm +++ b/src/test/ref/examples/chargen/chargen-analysis.asm @@ -206,6 +206,7 @@ main: { str2: .text "f5@" str3: .text "f7@" } +// Render 8x8 char (ch) as pixels on char canvas #pos plot_chargen: { .label _0 = 2 .label _1 = 2 @@ -296,6 +297,8 @@ plot_chargen: { cli rts } +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .const b = $a .label mb = $b @@ -332,6 +335,10 @@ mul8u: { rol mb+1 jmp b1 } +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { txa and #7 @@ -345,6 +352,11 @@ keyboard_key_pressed: { and keyboard_matrix_col_bitmask,y rts } +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { lda keyboard_matrix_row_bitmask,x sta CIA1_PORT_A @@ -352,10 +364,15 @@ keyboard_matrix_read: { eor #$ff rts } +// Get the keycode corresponding to a specific screen code character +// ch is the character to get the key code for ($00-$3f) +// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled. +// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) . keyboard_get_keycode: { lda keyboard_char_keycodes,x rts } +// Print a string at a specific screen position print_str_at: { .label at = 9 .label str = 2 diff --git a/src/test/ref/examples/chargen/chargen-analysis.log b/src/test/ref/examples/chargen/chargen-analysis.log index 698ca58cb..c6f39f09a 100644 --- a/src/test/ref/examples/chargen/chargen-analysis.log +++ b/src/test/ref/examples/chargen/chargen-analysis.log @@ -3142,6 +3142,7 @@ main: { str3: .text "f7@" } //SEG168 plot_chargen +// Render 8x8 char (ch) as pixels on char canvas #pos plot_chargen: { .label _0 = $2c .label _1 = $2e @@ -3345,6 +3346,8 @@ plot_chargen: { rts } //SEG227 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .const b = $a .label _1 = $35 @@ -3418,6 +3421,10 @@ mul8u: { jmp b1 } //SEG250 keyboard_key_pressed +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { .label _2 = $3a .label colidx = $36 @@ -3466,6 +3473,11 @@ keyboard_key_pressed: { rts } //SEG261 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { .label return = $3c .label rowid = $38 @@ -3485,6 +3497,10 @@ keyboard_matrix_read: { rts } //SEG266 keyboard_get_keycode +// Get the keycode corresponding to a specific screen code character +// ch is the character to get the key code for ($00-$3f) +// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled. +// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) . keyboard_get_keycode: { .label return = $3d .label ch = $28 @@ -3500,6 +3516,7 @@ keyboard_get_keycode: { rts } //SEG270 print_str_at +// Print a string at a specific screen position print_str_at: { .label at = $1c .label str = $1a @@ -3985,12 +4002,10 @@ main: { ldx #KEY_F1 jsr keyboard_key_pressed //SEG62 [24] (byte) keyboard_key_pressed::return#2 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#2 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b30 //SEG63 main::@30 b30: //SEG64 [25] (byte~) main::$15 ← (byte) keyboard_key_pressed::return#2 - // (byte~) main::$15 = (byte) keyboard_key_pressed::return#2 // register copy reg byte a //SEG65 [26] if((byte~) main::$15==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@41 -- vbuaa_eq_0_then_la1 cmp #0 beq b41_from_b30 @@ -4009,12 +4024,10 @@ main: { ldx #KEY_F3 jsr keyboard_key_pressed //SEG72 [29] (byte) keyboard_key_pressed::return#10 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#10 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b31 //SEG73 main::@31 b31: //SEG74 [30] (byte~) main::$18 ← (byte) keyboard_key_pressed::return#10 - // (byte~) main::$18 = (byte) keyboard_key_pressed::return#10 // register copy reg byte a //SEG75 [31] if((byte~) main::$18==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@42 -- vbuaa_eq_0_then_la1 cmp #0 beq b42_from_b31 @@ -4033,12 +4046,10 @@ main: { ldx #KEY_F5 jsr keyboard_key_pressed //SEG82 [34] (byte) keyboard_key_pressed::return#11 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#11 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b32 //SEG83 main::@32 b32: //SEG84 [35] (byte~) main::$21 ← (byte) keyboard_key_pressed::return#11 - // (byte~) main::$21 = (byte) keyboard_key_pressed::return#11 // register copy reg byte a //SEG85 [36] if((byte~) main::$21==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@43 -- vbuaa_eq_0_then_la1 cmp #0 beq b43_from_b32 @@ -4057,12 +4068,10 @@ main: { ldx #KEY_F7 jsr keyboard_key_pressed //SEG92 [39] (byte) keyboard_key_pressed::return#12 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#12 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b33 //SEG93 main::@33 b33: //SEG94 [40] (byte~) main::$24 ← (byte) keyboard_key_pressed::return#12 - // (byte~) main::$24 = (byte) keyboard_key_pressed::return#12 // register copy reg byte a //SEG95 [41] if((byte~) main::$24==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@44 -- vbuaa_eq_0_then_la1 cmp #0 beq b44_from_b33 @@ -4081,12 +4090,10 @@ main: { ldx #KEY_LSHIFT jsr keyboard_key_pressed //SEG102 [44] (byte) keyboard_key_pressed::return#13 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#13 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b34 //SEG103 main::@34 b34: //SEG104 [45] (byte~) main::$27 ← (byte) keyboard_key_pressed::return#13 - // (byte~) main::$27 = (byte) keyboard_key_pressed::return#13 // register copy reg byte a //SEG105 [46] if((byte~) main::$27!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@9 -- vbuaa_neq_0_then_la1 cmp #0 bne b9_from_b34 @@ -4126,12 +4133,10 @@ main: { //SEG119 [51] call keyboard_get_keycode jsr keyboard_get_keycode //SEG120 [52] (byte) keyboard_get_keycode::return#2 ← (byte) keyboard_get_keycode::return#0 - // (byte) keyboard_get_keycode::return#2 = (byte) keyboard_get_keycode::return#0 // register copy reg byte a jmp b35 //SEG121 main::@35 b35: //SEG122 [53] (byte) main::key#0 ← (byte) keyboard_get_keycode::return#2 - // (byte) main::key#0 = (byte) keyboard_get_keycode::return#2 // register copy reg byte a //SEG123 [54] if((byte) main::key#0==(byte/signed byte/word/signed word/dword/signed dword) 63) goto main::@11 -- vbuaa_eq_vbuc1_then_la1 cmp #$3f beq b11_from_b35 @@ -4146,12 +4151,10 @@ main: { //SEG128 [113] phi (byte) keyboard_key_pressed::key#6 = (byte) keyboard_key_pressed::key#5 [phi:main::@21->keyboard_key_pressed#0] -- register_copy jsr keyboard_key_pressed //SEG129 [57] (byte) keyboard_key_pressed::return#14 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#14 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b36 //SEG130 main::@36 b36: //SEG131 [58] (byte) main::pressed#1 ← (byte) keyboard_key_pressed::return#14 - // (byte) main::pressed#1 = (byte) keyboard_key_pressed::return#14 // register copy reg byte a //SEG132 [59] phi from main::@36 to main::@11 [phi:main::@36->main::@11] b11_from_b36: //SEG133 [59] phi (byte) main::pressed#2 = (byte) main::pressed#1 [phi:main::@36->main::@11#0] -- register_copy @@ -4237,6 +4240,7 @@ main: { str3: .text "f7@" } //SEG168 plot_chargen +// Render 8x8 char (ch) as pixels on char canvas #pos plot_chargen: { .label _0 = 2 .label _1 = 2 @@ -4298,12 +4302,10 @@ plot_chargen: { mul8u_from_b1: jsr mul8u //SEG183 [82] (word) mul8u::return#2 ← (word) mul8u::res#2 - // (word) mul8u::return#2 = (word) mul8u::res#2 // register copy zp ZP_WORD:9 jmp b9 //SEG184 plot_chargen::@9 b9: //SEG185 [83] (word~) plot_chargen::$8 ← (word) mul8u::return#2 - // (word~) plot_chargen::$8 = (word) mul8u::return#2 // register copy zp ZP_WORD:9 //SEG186 [84] (byte*) plot_chargen::sc#0 ← (const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 40+(byte/signed byte/word/signed word/dword/signed dword) 1 + (word~) plot_chargen::$8 -- pbuz1=pbuc1_plus_vwuz1 clc lda sc @@ -4415,6 +4417,8 @@ plot_chargen: { rts } //SEG227 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .const b = $a .label mb = $b @@ -4485,6 +4489,10 @@ mul8u: { jmp b1 } //SEG250 keyboard_key_pressed +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { //SEG251 [114] (byte) keyboard_key_pressed::colidx#0 ← (byte) keyboard_key_pressed::key#6 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuyy=vbuxx_band_vbuc1 txa @@ -4500,12 +4508,10 @@ keyboard_key_pressed: { //SEG254 [117] call keyboard_matrix_read jsr keyboard_matrix_read //SEG255 [118] (byte) keyboard_matrix_read::return#2 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#2 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a jmp b2 //SEG256 keyboard_key_pressed::@2 b2: //SEG257 [119] (byte~) keyboard_key_pressed::$2 ← (byte) keyboard_matrix_read::return#2 - // (byte~) keyboard_key_pressed::$2 = (byte) keyboard_matrix_read::return#2 // register copy reg byte a //SEG258 [120] (byte) keyboard_key_pressed::return#0 ← (byte~) keyboard_key_pressed::$2 & *((const byte[8]) keyboard_matrix_col_bitmask#0 + (byte) keyboard_key_pressed::colidx#0) -- vbuaa=vbuaa_band_pbuc1_derefidx_vbuyy and keyboard_matrix_col_bitmask,y jmp breturn @@ -4515,6 +4521,11 @@ keyboard_key_pressed: { rts } //SEG261 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { //SEG262 [122] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0 + (byte) keyboard_matrix_read::rowid#0) -- _deref_pbuc1=pbuc2_derefidx_vbuxx lda keyboard_matrix_row_bitmask,x @@ -4529,6 +4540,10 @@ keyboard_matrix_read: { rts } //SEG266 keyboard_get_keycode +// Get the keycode corresponding to a specific screen code character +// ch is the character to get the key code for ($00-$3f) +// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled. +// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) . keyboard_get_keycode: { //SEG267 [125] (byte) keyboard_get_keycode::return#0 ← *((const byte[]) keyboard_char_keycodes#0 + (byte) keyboard_get_keycode::ch#0) -- vbuaa=pbuc1_derefidx_vbuxx lda keyboard_char_keycodes,x @@ -4539,6 +4554,7 @@ keyboard_get_keycode: { rts } //SEG270 print_str_at +// Print a string at a specific screen position print_str_at: { .label at = 9 .label str = 2 @@ -4676,6 +4692,7 @@ Removing instruction b19_from_b34: Removing instruction b9_from_b19: Removing instruction b10_from_b9: Removing instruction b10_from_b12: +Removing instruction b11_from_b36: Removing instruction b44_from_b33: Removing instruction b7_from_b44: Removing instruction b43_from_b32: @@ -4719,7 +4736,6 @@ Removing instruction b35: Removing instruction b21: Removing instruction keyboard_key_pressed_from_b21: Removing instruction b36: -Removing instruction b11_from_b36: Removing instruction b22: Removing instruction plot_chargen_from_b22: Removing instruction b3_from_b12: @@ -5422,10 +5438,8 @@ main: { ldx #KEY_F1 jsr keyboard_key_pressed //SEG62 [24] (byte) keyboard_key_pressed::return#2 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#2 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG63 main::@30 //SEG64 [25] (byte~) main::$15 ← (byte) keyboard_key_pressed::return#2 - // (byte~) main::$15 = (byte) keyboard_key_pressed::return#2 // register copy reg byte a //SEG65 [26] if((byte~) main::$15==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@41 -- vbuaa_eq_0_then_la1 cmp #0 beq b4 @@ -5441,10 +5455,8 @@ main: { ldx #KEY_F3 jsr keyboard_key_pressed //SEG72 [29] (byte) keyboard_key_pressed::return#10 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#10 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG73 main::@31 //SEG74 [30] (byte~) main::$18 ← (byte) keyboard_key_pressed::return#10 - // (byte~) main::$18 = (byte) keyboard_key_pressed::return#10 // register copy reg byte a //SEG75 [31] if((byte~) main::$18==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@42 -- vbuaa_eq_0_then_la1 cmp #0 beq b5 @@ -5460,10 +5472,8 @@ main: { ldx #KEY_F5 jsr keyboard_key_pressed //SEG82 [34] (byte) keyboard_key_pressed::return#11 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#11 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG83 main::@32 //SEG84 [35] (byte~) main::$21 ← (byte) keyboard_key_pressed::return#11 - // (byte~) main::$21 = (byte) keyboard_key_pressed::return#11 // register copy reg byte a //SEG85 [36] if((byte~) main::$21==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@43 -- vbuaa_eq_0_then_la1 cmp #0 beq b6 @@ -5479,10 +5489,8 @@ main: { ldx #KEY_F7 jsr keyboard_key_pressed //SEG92 [39] (byte) keyboard_key_pressed::return#12 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#12 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG93 main::@33 //SEG94 [40] (byte~) main::$24 ← (byte) keyboard_key_pressed::return#12 - // (byte~) main::$24 = (byte) keyboard_key_pressed::return#12 // register copy reg byte a //SEG95 [41] if((byte~) main::$24==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@44 -- vbuaa_eq_0_then_la1 cmp #0 beq b7 @@ -5498,10 +5506,8 @@ main: { ldx #KEY_LSHIFT jsr keyboard_key_pressed //SEG102 [44] (byte) keyboard_key_pressed::return#13 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#13 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG103 main::@34 //SEG104 [45] (byte~) main::$27 ← (byte) keyboard_key_pressed::return#13 - // (byte~) main::$27 = (byte) keyboard_key_pressed::return#13 // register copy reg byte a //SEG105 [46] if((byte~) main::$27!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@9 -- vbuaa_neq_0_then_la1 cmp #0 bne b8 @@ -5532,10 +5538,8 @@ main: { //SEG119 [51] call keyboard_get_keycode jsr keyboard_get_keycode //SEG120 [52] (byte) keyboard_get_keycode::return#2 ← (byte) keyboard_get_keycode::return#0 - // (byte) keyboard_get_keycode::return#2 = (byte) keyboard_get_keycode::return#0 // register copy reg byte a //SEG121 main::@35 //SEG122 [53] (byte) main::key#0 ← (byte) keyboard_get_keycode::return#2 - // (byte) main::key#0 = (byte) keyboard_get_keycode::return#2 // register copy reg byte a //SEG123 [54] if((byte) main::key#0==(byte/signed byte/word/signed word/dword/signed dword) 63) goto main::@11 -- vbuaa_eq_vbuc1_then_la1 cmp #$3f beq b13 @@ -5547,10 +5551,8 @@ main: { //SEG128 [113] phi (byte) keyboard_key_pressed::key#6 = (byte) keyboard_key_pressed::key#5 [phi:main::@21->keyboard_key_pressed#0] -- register_copy jsr keyboard_key_pressed //SEG129 [57] (byte) keyboard_key_pressed::return#14 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#14 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG130 main::@36 //SEG131 [58] (byte) main::pressed#1 ← (byte) keyboard_key_pressed::return#14 - // (byte) main::pressed#1 = (byte) keyboard_key_pressed::return#14 // register copy reg byte a //SEG132 [59] phi from main::@36 to main::@11 [phi:main::@36->main::@11] //SEG133 [59] phi (byte) main::pressed#2 = (byte) main::pressed#1 [phi:main::@36->main::@11#0] -- register_copy jmp b11 @@ -5609,6 +5611,7 @@ main: { str3: .text "f7@" } //SEG168 plot_chargen +// Render 8x8 char (ch) as pixels on char canvas #pos plot_chargen: { .label _0 = 2 .label _1 = 2 @@ -5664,10 +5667,8 @@ plot_chargen: { //SEG182 [103] phi from plot_chargen::@1 to mul8u [phi:plot_chargen::@1->mul8u] jsr mul8u //SEG183 [82] (word) mul8u::return#2 ← (word) mul8u::res#2 - // (word) mul8u::return#2 = (word) mul8u::res#2 // register copy zp ZP_WORD:9 //SEG184 plot_chargen::@9 //SEG185 [83] (word~) plot_chargen::$8 ← (word) mul8u::return#2 - // (word~) plot_chargen::$8 = (word) mul8u::return#2 // register copy zp ZP_WORD:9 //SEG186 [84] (byte*) plot_chargen::sc#0 ← (const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 40+(byte/signed byte/word/signed word/dword/signed dword) 1 + (word~) plot_chargen::$8 -- pbuz1=pbuc1_plus_vwuz1 clc lda sc @@ -5760,6 +5761,8 @@ plot_chargen: { rts } //SEG227 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .const b = $a .label mb = $b @@ -5819,6 +5822,10 @@ mul8u: { jmp b1 } //SEG250 keyboard_key_pressed +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { //SEG251 [114] (byte) keyboard_key_pressed::colidx#0 ← (byte) keyboard_key_pressed::key#6 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuyy=vbuxx_band_vbuc1 txa @@ -5834,10 +5841,8 @@ keyboard_key_pressed: { //SEG254 [117] call keyboard_matrix_read jsr keyboard_matrix_read //SEG255 [118] (byte) keyboard_matrix_read::return#2 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#2 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a //SEG256 keyboard_key_pressed::@2 //SEG257 [119] (byte~) keyboard_key_pressed::$2 ← (byte) keyboard_matrix_read::return#2 - // (byte~) keyboard_key_pressed::$2 = (byte) keyboard_matrix_read::return#2 // register copy reg byte a //SEG258 [120] (byte) keyboard_key_pressed::return#0 ← (byte~) keyboard_key_pressed::$2 & *((const byte[8]) keyboard_matrix_col_bitmask#0 + (byte) keyboard_key_pressed::colidx#0) -- vbuaa=vbuaa_band_pbuc1_derefidx_vbuyy and keyboard_matrix_col_bitmask,y //SEG259 keyboard_key_pressed::@return @@ -5845,6 +5850,11 @@ keyboard_key_pressed: { rts } //SEG261 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { //SEG262 [122] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0 + (byte) keyboard_matrix_read::rowid#0) -- _deref_pbuc1=pbuc2_derefidx_vbuxx lda keyboard_matrix_row_bitmask,x @@ -5857,6 +5867,10 @@ keyboard_matrix_read: { rts } //SEG266 keyboard_get_keycode +// Get the keycode corresponding to a specific screen code character +// ch is the character to get the key code for ($00-$3f) +// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled. +// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) . keyboard_get_keycode: { //SEG267 [125] (byte) keyboard_get_keycode::return#0 ← *((const byte[]) keyboard_char_keycodes#0 + (byte) keyboard_get_keycode::ch#0) -- vbuaa=pbuc1_derefidx_vbuxx lda keyboard_char_keycodes,x @@ -5865,6 +5879,7 @@ keyboard_get_keycode: { rts } //SEG270 print_str_at +// Print a string at a specific screen position print_str_at: { .label at = 9 .label str = 2 diff --git a/src/test/ref/examples/fastmultiply/fastmultiply8.kc.asm b/src/test/ref/examples/fastmultiply/fastmultiply8.kc.asm index f8562e678..6664bf078 100644 --- a/src/test/ref/examples/fastmultiply/fastmultiply8.kc.asm +++ b/src/test/ref/examples/fastmultiply/fastmultiply8.kc.asm @@ -96,6 +96,7 @@ main: { bne b2 rts } +// Print a signed byte as hex at a specific screen position print_sbyte_at: { .label b = $a .label at = 8 @@ -122,6 +123,7 @@ print_sbyte_at: { sta b jmp b2 } +// Print a single char print_char_at: { .label at = 8 .label ch = $b @@ -130,6 +132,7 @@ print_char_at: { sta (at),y rts } +// Print a byte as HEX at a specific position print_byte_at: { .label at = 8 lda print_sbyte_at.b @@ -208,6 +211,7 @@ init_screen: { bne b2 rts } +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 lda #print_cls::@1] @@ -2139,12 +2143,10 @@ main: { //SEG55 [24] call fmul8 jsr fmul8 //SEG56 [25] (signed byte) fmul8::return#0 ← (signed byte) fmul8::return#1 - // (signed byte) fmul8::return#0 = (signed byte) fmul8::return#1 // register copy reg byte a jmp b10 //SEG57 main::@10 b10: //SEG58 [26] (signed byte) main::r#0 ← (signed byte) fmul8::return#0 - // (signed byte) main::r#0 = (signed byte) fmul8::return#0 // register copy reg byte a //SEG59 [27] (signed byte) print_sbyte_at::b#3 ← (signed byte) main::r#0 -- vbsz1=vbsaa sta print_sbyte_at.b //SEG60 [28] (byte*) print_sbyte_at::at#2 ← (byte*) main::at#3 -- pbuz1=pbuz2 @@ -2183,6 +2185,7 @@ main: { rts } //SEG73 print_sbyte_at +// Print a signed byte as hex at a specific screen position print_sbyte_at: { .label b = $a .label at = 8 @@ -2193,7 +2196,6 @@ print_sbyte_at: { //SEG75 print_sbyte_at::@3 b3: //SEG76 [37] (byte*) print_char_at::at#1 ← (byte*) print_sbyte_at::at#3 - // (byte*) print_char_at::at#1 = (byte*) print_sbyte_at::at#3 // register copy zp ZP_WORD:8 //SEG77 [38] call print_char_at //SEG78 [46] phi from print_sbyte_at::@3 to print_char_at [phi:print_sbyte_at::@3->print_char_at] print_char_at_from_b3: @@ -2224,7 +2226,6 @@ print_sbyte_at: { //SEG88 print_sbyte_at::@1 b1: //SEG89 [43] (byte*) print_char_at::at#0 ← (byte*) print_sbyte_at::at#3 - // (byte*) print_char_at::at#0 = (byte*) print_sbyte_at::at#3 // register copy zp ZP_WORD:8 //SEG90 [44] call print_char_at //SEG91 [46] phi from print_sbyte_at::@1 to print_char_at [phi:print_sbyte_at::@1->print_char_at] print_char_at_from_b1: @@ -2245,6 +2246,7 @@ print_sbyte_at: { jmp b2_from_b5 } //SEG96 print_char_at +// Print a single char print_char_at: { .label at = 8 .label ch = $b @@ -2259,6 +2261,7 @@ print_char_at: { rts } //SEG100 print_byte_at +// Print a byte as HEX at a specific position print_byte_at: { .label at = 8 //SEG101 [49] (byte~) print_byte_at::$0 ← (byte)(signed byte) print_sbyte_at::b#6 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 @@ -2272,7 +2275,6 @@ print_byte_at: { lda print_hextab,y sta print_char_at.ch //SEG103 [51] (byte*) print_char_at::at#2 ← (byte*) print_byte_at::at#0 - // (byte*) print_char_at::at#2 = (byte*) print_byte_at::at#0 // register copy zp ZP_WORD:8 //SEG104 [52] call print_char_at //SEG105 [46] phi from print_byte_at to print_char_at [phi:print_byte_at->print_char_at] print_char_at_from_print_byte_at: @@ -2413,6 +2415,7 @@ init_screen: { rts } //SEG152 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG153 [79] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -2512,8 +2515,10 @@ Removing instruction bend_from_b22: Removing instruction b1_from_b8: Removing instruction b2_from_b5: Removing instruction b3_from_b11: +Removing instruction print_char_at_from_b3: Removing instruction b2_from_b3: Removing instruction b2_from_b5: +Removing instruction print_char_at_from_b1: Removing instruction b1_from_b1: Removing instruction b2_from_b2: Removing instruction b1_from_b1: @@ -2532,9 +2537,7 @@ Removing instruction b11: Removing instruction b5: Removing instruction breturn: Removing instruction b3: -Removing instruction print_char_at_from_b3: Removing instruction breturn: -Removing instruction print_char_at_from_b1: Removing instruction b5: Removing instruction breturn: Removing instruction print_char_at_from_print_byte_at: @@ -2843,10 +2846,8 @@ main: { //SEG55 [24] call fmul8 jsr fmul8 //SEG56 [25] (signed byte) fmul8::return#0 ← (signed byte) fmul8::return#1 - // (signed byte) fmul8::return#0 = (signed byte) fmul8::return#1 // register copy reg byte a //SEG57 main::@10 //SEG58 [26] (signed byte) main::r#0 ← (signed byte) fmul8::return#0 - // (signed byte) main::r#0 = (signed byte) fmul8::return#0 // register copy reg byte a //SEG59 [27] (signed byte) print_sbyte_at::b#3 ← (signed byte) main::r#0 -- vbsz1=vbsaa sta print_sbyte_at.b //SEG60 [28] (byte*) print_sbyte_at::at#2 ← (byte*) main::at#3 -- pbuz1=pbuz2 @@ -2878,6 +2879,7 @@ main: { rts } //SEG73 print_sbyte_at +// Print a signed byte as hex at a specific screen position print_sbyte_at: { .label b = $a .label at = 8 @@ -2886,7 +2888,6 @@ print_sbyte_at: { bmi b1 //SEG75 print_sbyte_at::@3 //SEG76 [37] (byte*) print_char_at::at#1 ← (byte*) print_sbyte_at::at#3 - // (byte*) print_char_at::at#1 = (byte*) print_sbyte_at::at#3 // register copy zp ZP_WORD:8 //SEG77 [38] call print_char_at //SEG78 [46] phi from print_sbyte_at::@3 to print_char_at [phi:print_sbyte_at::@3->print_char_at] //SEG79 [46] phi (byte*) print_char_at::at#4 = (byte*) print_char_at::at#1 [phi:print_sbyte_at::@3->print_char_at#0] -- register_copy @@ -2911,7 +2912,6 @@ print_sbyte_at: { //SEG88 print_sbyte_at::@1 b1: //SEG89 [43] (byte*) print_char_at::at#0 ← (byte*) print_sbyte_at::at#3 - // (byte*) print_char_at::at#0 = (byte*) print_sbyte_at::at#3 // register copy zp ZP_WORD:8 //SEG90 [44] call print_char_at //SEG91 [46] phi from print_sbyte_at::@1 to print_char_at [phi:print_sbyte_at::@1->print_char_at] //SEG92 [46] phi (byte*) print_char_at::at#4 = (byte*) print_char_at::at#0 [phi:print_sbyte_at::@1->print_char_at#0] -- register_copy @@ -2929,6 +2929,7 @@ print_sbyte_at: { jmp b2 } //SEG96 print_char_at +// Print a single char print_char_at: { .label at = 8 .label ch = $b @@ -2941,6 +2942,7 @@ print_char_at: { rts } //SEG100 print_byte_at +// Print a byte as HEX at a specific position print_byte_at: { .label at = 8 //SEG101 [49] (byte~) print_byte_at::$0 ← (byte)(signed byte) print_sbyte_at::b#6 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 @@ -2954,7 +2956,6 @@ print_byte_at: { lda print_hextab,y sta print_char_at.ch //SEG103 [51] (byte*) print_char_at::at#2 ← (byte*) print_byte_at::at#0 - // (byte*) print_char_at::at#2 = (byte*) print_byte_at::at#0 // register copy zp ZP_WORD:8 //SEG104 [52] call print_char_at //SEG105 [46] phi from print_byte_at to print_char_at [phi:print_byte_at->print_char_at] //SEG106 [46] phi (byte*) print_char_at::at#4 = (byte*) print_char_at::at#2 [phi:print_byte_at->print_char_at#0] -- register_copy @@ -3072,6 +3073,7 @@ init_screen: { rts } //SEG152 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG153 [79] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] diff --git a/src/test/ref/examples/helloworld/helloworld.asm b/src/test/ref/examples/helloworld/helloworld.asm index 9a8b575ee..74bb9742e 100644 --- a/src/test/ref/examples/helloworld/helloworld.asm +++ b/src/test/ref/examples/helloworld/helloworld.asm @@ -9,6 +9,7 @@ main: { rts str: .text "hello world!@" } +// Print a newline print_ln: { lda #<$400 sta print_line_cursor @@ -32,6 +33,7 @@ print_ln: { !: rts } +// Print a zero-terminated string print_str: { .label str = 2 lda #<$400 diff --git a/src/test/ref/examples/helloworld/helloworld.log b/src/test/ref/examples/helloworld/helloworld.log index 21c52d49d..841dea91b 100644 --- a/src/test/ref/examples/helloworld/helloworld.log +++ b/src/test/ref/examples/helloworld/helloworld.log @@ -365,6 +365,7 @@ main: { str: .text "hello world!@" } //SEG18 print_ln +// Print a newline print_ln: { //SEG19 [10] phi from print_ln to print_ln::@1 [phi:print_ln->print_ln::@1] b1_from_print_ln: @@ -404,6 +405,7 @@ print_ln: { rts } //SEG28 print_str +// Print a zero-terminated string print_str: { .label str = 4 //SEG29 [15] phi from print_str to print_str::@1 [phi:print_str->print_str::@1] @@ -524,6 +526,7 @@ main: { str: .text "hello world!@" } //SEG18 print_ln +// Print a newline print_ln: { //SEG19 [10] phi from print_ln to print_ln::@1 [phi:print_ln->print_ln::@1] b1_from_print_ln: @@ -563,6 +566,7 @@ print_ln: { rts } //SEG28 print_str +// Print a zero-terminated string print_str: { .label str = 2 //SEG29 [15] phi from print_str to print_str::@1 [phi:print_str->print_str::@1] @@ -718,6 +722,7 @@ main: { str: .text "hello world!@" } //SEG18 print_ln +// Print a newline print_ln: { //SEG19 [10] phi from print_ln to print_ln::@1 [phi:print_ln->print_ln::@1] //SEG20 [10] phi (byte*) print_line_cursor#6 = ((byte*))(word/signed word/dword/signed dword) 1024 [phi:print_ln->print_ln::@1#0] -- pbuz1=pbuc1 @@ -751,6 +756,7 @@ print_ln: { rts } //SEG28 print_str +// Print a zero-terminated string print_str: { .label str = 2 //SEG29 [15] phi from print_str to print_str::@1 [phi:print_str->print_str::@1] diff --git a/src/test/ref/examples/irq/irq-hyperscreen.asm b/src/test/ref/examples/irq/irq-hyperscreen.asm index b97906bab..daf6fb764 100644 --- a/src/test/ref/examples/irq/irq-hyperscreen.asm +++ b/src/test/ref/examples/irq/irq-hyperscreen.asm @@ -34,6 +34,7 @@ main: { cli rts } +// Interrupt Routine 2 irq_bottom_2: { lda #WHITE sta BORDERCOL @@ -52,6 +53,7 @@ irq_bottom_2: { sta BORDERCOL jmp $ea31 } +// Interrupt Routine 1 irq_bottom_1: { lda #WHITE sta BORDERCOL diff --git a/src/test/ref/examples/irq/irq-hyperscreen.log b/src/test/ref/examples/irq/irq-hyperscreen.log index 11c2ea6b8..331bad59b 100644 --- a/src/test/ref/examples/irq/irq-hyperscreen.log +++ b/src/test/ref/examples/irq/irq-hyperscreen.log @@ -620,6 +620,7 @@ main: { rts } //SEG19 irq_bottom_2 +// Interrupt Routine 2 irq_bottom_2: { //SEG20 entry interrupt(KERNEL_KEYBOARD) //SEG21 [13] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 @@ -650,6 +651,7 @@ irq_bottom_2: { jmp $ea31 } //SEG29 irq_bottom_1 +// Interrupt Routine 1 irq_bottom_1: { //SEG30 entry interrupt(KERNEL_MIN) //SEG31 [20] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 @@ -778,6 +780,7 @@ main: { rts } //SEG19 irq_bottom_2 +// Interrupt Routine 2 irq_bottom_2: { //SEG20 entry interrupt(KERNEL_KEYBOARD) //SEG21 [13] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 @@ -808,6 +811,7 @@ irq_bottom_2: { jmp $ea31 } //SEG29 irq_bottom_1 +// Interrupt Routine 1 irq_bottom_1: { //SEG30 entry interrupt(KERNEL_MIN) //SEG31 [20] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 @@ -1025,6 +1029,7 @@ main: { rts } //SEG19 irq_bottom_2 +// Interrupt Routine 2 irq_bottom_2: { //SEG20 entry interrupt(KERNEL_KEYBOARD) //SEG21 [13] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 @@ -1053,6 +1058,7 @@ irq_bottom_2: { jmp $ea31 } //SEG29 irq_bottom_1 +// Interrupt Routine 1 irq_bottom_1: { //SEG30 entry interrupt(KERNEL_MIN) //SEG31 [20] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 diff --git a/src/test/ref/examples/multiplexer/simple-multiplexer.asm b/src/test/ref/examples/multiplexer/simple-multiplexer.asm index 6790b2a1c..eeecb6478 100644 --- a/src/test/ref/examples/multiplexer/simple-multiplexer.asm +++ b/src/test/ref/examples/multiplexer/simple-multiplexer.asm @@ -28,6 +28,7 @@ main: { jsr loop rts } +// The raster loop loop: { .label sin_idx = 2 .label plexFreeNextYpos1_return = 9 @@ -89,6 +90,8 @@ loop: { sta BORDERCOL jmp b4 } +// Show the next sprite. +// plexSort() prepares showing the sprites plexShowSprite: { .label plex_sprite_idx2 = 9 .label xpos_idx = $a @@ -151,6 +154,15 @@ plexShowSprite: { sta SPRITES_XMSB jmp b2 } +// Ensure that the indices in PLEX_SORTED_IDX is sorted based on the y-positions in PLEX_YPOS +// Assumes that the positions are nearly sorted already (as each sprite just moves a bit) +// Uses an insertion sort: +// 1. Moves a marker (m) from the start to end of the array. Every time the marker moves forward all elements before the marker are sorted correctly. +// 2a. If the next element after the marker is larger that the current element +// the marker can be moved forwards (as the sorting is correct). +// 2b. If the next element after the marker is smaller than the current element: +// elements before the marker are shifted right one at a time until encountering one smaller than the current one. +// It is then inserted at the spot. Now the marker can move forward. plexSort: { .label nxt_idx = 4 .label nxt_y = 5 @@ -198,6 +210,7 @@ plexSort: { bcc b3 jmp b5 } +// Initialize the program init: { .label xp = 7 lda #VIC_DEN|VIC_RSEL|3 @@ -239,6 +252,7 @@ init: { bne b2 rts } +// Initialize the multiplexer data structures plexInit: { ldx #0 b1: diff --git a/src/test/ref/examples/multiplexer/simple-multiplexer.log b/src/test/ref/examples/multiplexer/simple-multiplexer.log index 5d090f81e..329e5d034 100644 --- a/src/test/ref/examples/multiplexer/simple-multiplexer.log +++ b/src/test/ref/examples/multiplexer/simple-multiplexer.log @@ -2520,6 +2520,7 @@ main: { rts } //SEG20 loop +// The raster loop loop: { .label _4 = $12 .label y_idx = 3 @@ -2681,6 +2682,8 @@ loop: { jmp b1 } //SEG78 plexShowSprite +// Show the next sprite. +// plexSort() prepares showing the sprites plexShowSprite: { .label _3 = $19 .label _4 = $1a @@ -2814,6 +2817,15 @@ plexShowSprite: { jmp b2 } //SEG113 plexSort +// Ensure that the indices in PLEX_SORTED_IDX is sorted based on the y-positions in PLEX_YPOS +// Assumes that the positions are nearly sorted already (as each sprite just moves a bit) +// Uses an insertion sort: +// 1. Moves a marker (m) from the start to end of the array. Every time the marker moves forward all elements before the marker are sorted correctly. +// 2a. If the next element after the marker is larger that the current element +// the marker can be moved forwards (as the sorting is correct). +// 2b. If the next element after the marker is smaller than the current element: +// elements before the marker are shifted right one at a time until encountering one smaller than the current one. +// It is then inserted at the spot. Now the marker can move forward. plexSort: { .label nxt_idx = $1d .label nxt_y = $1e @@ -2933,6 +2945,7 @@ plexSort: { jmp b5 } //SEG150 init +// Initialize the program init: { .label _6 = $20 .label xp = $e @@ -3026,6 +3039,7 @@ init: { rts } //SEG179 plexInit +// Initialize the multiplexer data structures plexInit: { .label i = $11 //SEG180 [97] phi from plexInit to plexInit::plexSetScreen1 [phi:plexInit->plexInit::plexSetScreen1] @@ -3333,6 +3347,7 @@ main: { rts } //SEG20 loop +// The raster loop loop: { .label sin_idx = 2 .label plexFreeNextYpos1_return = 9 @@ -3483,6 +3498,8 @@ loop: { jmp b1 } //SEG78 plexShowSprite +// Show the next sprite. +// plexSort() prepares showing the sprites plexShowSprite: { .label plex_sprite_idx2 = 9 .label xpos_idx = $a @@ -3594,6 +3611,15 @@ plexShowSprite: { jmp b2 } //SEG113 plexSort +// Ensure that the indices in PLEX_SORTED_IDX is sorted based on the y-positions in PLEX_YPOS +// Assumes that the positions are nearly sorted already (as each sprite just moves a bit) +// Uses an insertion sort: +// 1. Moves a marker (m) from the start to end of the array. Every time the marker moves forward all elements before the marker are sorted correctly. +// 2a. If the next element after the marker is larger that the current element +// the marker can be moved forwards (as the sorting is correct). +// 2b. If the next element after the marker is smaller than the current element: +// elements before the marker are shifted right one at a time until encountering one smaller than the current one. +// It is then inserted at the spot. Now the marker can move forward. plexSort: { .label nxt_idx = 4 .label nxt_y = 5 @@ -3700,6 +3726,7 @@ plexSort: { jmp b5 } //SEG150 init +// Initialize the program init: { .label xp = 7 //SEG151 [81] *((const byte*) D011#0) ← (const byte) VIC_DEN#0|(const byte) VIC_RSEL#0|(byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2 @@ -3783,6 +3810,7 @@ init: { rts } //SEG179 plexInit +// Initialize the multiplexer data structures plexInit: { //SEG180 [97] phi from plexInit to plexInit::plexSetScreen1 [phi:plexInit->plexInit::plexSetScreen1] plexSetScreen1_from_plexInit: @@ -4288,6 +4316,7 @@ main: { rts } //SEG20 loop +// The raster loop loop: { .label sin_idx = 2 .label plexFreeNextYpos1_return = 9 @@ -4407,6 +4436,8 @@ loop: { jmp b4 } //SEG78 plexShowSprite +// Show the next sprite. +// plexSort() prepares showing the sprites plexShowSprite: { .label plex_sprite_idx2 = 9 .label xpos_idx = $a @@ -4504,6 +4535,15 @@ plexShowSprite: { jmp b2 } //SEG113 plexSort +// Ensure that the indices in PLEX_SORTED_IDX is sorted based on the y-positions in PLEX_YPOS +// Assumes that the positions are nearly sorted already (as each sprite just moves a bit) +// Uses an insertion sort: +// 1. Moves a marker (m) from the start to end of the array. Every time the marker moves forward all elements before the marker are sorted correctly. +// 2a. If the next element after the marker is larger that the current element +// the marker can be moved forwards (as the sorting is correct). +// 2b. If the next element after the marker is smaller than the current element: +// elements before the marker are shifted right one at a time until encountering one smaller than the current one. +// It is then inserted at the spot. Now the marker can move forward. plexSort: { .label nxt_idx = 4 .label nxt_y = 5 @@ -4588,6 +4628,7 @@ plexSort: { jmp b5 } //SEG150 init +// Initialize the program init: { .label xp = 7 //SEG151 [81] *((const byte*) D011#0) ← (const byte) VIC_DEN#0|(const byte) VIC_RSEL#0|(byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2 @@ -4658,6 +4699,7 @@ init: { rts } //SEG179 plexInit +// Initialize the multiplexer data structures plexInit: { //SEG180 [97] phi from plexInit to plexInit::plexSetScreen1 [phi:plexInit->plexInit::plexSetScreen1] //SEG181 plexInit::plexSetScreen1 diff --git a/src/test/ref/examples/rotate/rotate.asm b/src/test/ref/examples/rotate/rotate.asm index afeab093f..f2ffda505 100644 --- a/src/test/ref/examples/rotate/rotate.asm +++ b/src/test/ref/examples/rotate/rotate.asm @@ -140,6 +140,8 @@ anim: { sta BORDERCOL jmp b4 } +// 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: { .label memA = $fd .label m = 5 @@ -163,6 +165,8 @@ mulf8s_prepared: { 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: { .label resL = $fe .label memB = $ff @@ -186,6 +190,7 @@ mulf8u_prepared: { sta return+1 rts } +// Prepare for fast multiply with an unsigned byte to a word result mulf8u_prepare: { .label memA = $fd sta memA @@ -212,6 +217,7 @@ init: { bne b1 rts } +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label sqr1_hi = 7 .label sqr = 9 diff --git a/src/test/ref/examples/rotate/rotate.log b/src/test/ref/examples/rotate/rotate.log index 5cd7d59ab..e29ea09fb 100644 --- a/src/test/ref/examples/rotate/rotate.log +++ b/src/test/ref/examples/rotate/rotate.log @@ -2647,6 +2647,8 @@ anim: { jmp b1 } //SEG108 mulf8s_prepared +// 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: { .label memA = $fd .label _4 = $41 @@ -2739,6 +2741,8 @@ mulf8s_prepared: { rts } //SEG133 mulf8u_prepared +// 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: { .label resL = $fe .label memB = $ff @@ -2772,6 +2776,7 @@ mulf8u_prepared: { rts } //SEG139 mulf8u_prepare +// Prepare for fast multiply with an unsigned byte to a word result mulf8u_prepare: { .label memA = $fd .label a = 8 @@ -2838,6 +2843,7 @@ init: { rts } //SEG160 mulf_init +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label _2 = $49 .label _5 = $4a @@ -3481,7 +3487,6 @@ anim: { //SEG46 [62] phi (signed byte) mulf8s_prepared::b#4 = (signed byte) mulf8s_prepared::b#0 [phi:anim::@17->mulf8s_prepared#0] -- register_copy jsr mulf8s_prepared //SEG47 [21] (signed word) mulf8s_prepared::return#2 ← (signed word)(word) mulf8s_prepared::m#4 - // (signed word) mulf8s_prepared::return#2 = (signed word)(word) mulf8s_prepared::m#4 // register copy zp ZP_WORD:5 jmp b20 //SEG48 anim::@20 b20: @@ -3501,7 +3506,6 @@ anim: { //SEG54 [62] phi (signed byte) mulf8s_prepared::b#4 = (signed byte) mulf8s_prepared::b#1 [phi:anim::@20->mulf8s_prepared#0] -- register_copy jsr mulf8s_prepared //SEG55 [26] (signed word) mulf8s_prepared::return#3 ← (signed word)(word) mulf8s_prepared::m#4 - // (signed word) mulf8s_prepared::return#3 = (signed word)(word) mulf8s_prepared::m#4 // register copy zp ZP_WORD:5 jmp b21 //SEG56 anim::@21 b21: @@ -3535,12 +3539,10 @@ anim: { //SEG68 [62] phi (signed byte) mulf8s_prepared::b#4 = (signed byte) mulf8s_prepared::b#2 [phi:anim::@18->mulf8s_prepared#0] -- register_copy jsr mulf8s_prepared //SEG69 [33] (signed word) mulf8s_prepared::return#4 ← (signed word)(word) mulf8s_prepared::m#4 - // (signed word) mulf8s_prepared::return#4 = (signed word)(word) mulf8s_prepared::m#4 // register copy zp ZP_WORD:5 jmp b23 //SEG70 anim::@23 b23: //SEG71 [34] (signed word~) anim::$9 ← (signed word) mulf8s_prepared::return#4 - // (signed word~) anim::$9 = (signed word) mulf8s_prepared::return#4 // register copy zp ZP_WORD:5 //SEG72 [35] (signed word~) anim::$10 ← (signed word~) anim::$9 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vwsz1=vwsz1_rol_1 asl _10 rol _10+1 @@ -3560,12 +3562,10 @@ anim: { //SEG77 [62] phi (signed byte) mulf8s_prepared::b#4 = (signed byte) mulf8s_prepared::b#3 [phi:anim::@23->mulf8s_prepared#0] -- register_copy jsr mulf8s_prepared //SEG78 [39] (signed word) mulf8s_prepared::return#10 ← (signed word)(word) mulf8s_prepared::m#4 - // (signed word) mulf8s_prepared::return#10 = (signed word)(word) mulf8s_prepared::m#4 // register copy zp ZP_WORD:5 jmp b24 //SEG79 anim::@24 b24: //SEG80 [40] (signed word~) anim::$11 ← (signed word) mulf8s_prepared::return#10 - // (signed word~) anim::$11 = (signed word) mulf8s_prepared::return#10 // register copy zp ZP_WORD:5 //SEG81 [41] (signed word~) anim::$12 ← (signed word~) anim::$11 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vwsz1=vwsz1_rol_1 asl _12 rol _12+1 @@ -3580,7 +3580,6 @@ anim: { //SEG83 [43] (byte~) anim::$13 ← > (signed word) anim::xr#1 -- vbuaa=_hi_vwsz1 lda xr+1 //SEG84 [44] (signed byte~) anim::$15 ← (signed byte)(byte~) anim::$13 - // (signed byte~) anim::$15 = (signed byte)(byte~) anim::$13 // register copy reg byte a //SEG85 [45] (signed word) anim::xpos#0 ← (signed byte~) anim::$15 + (byte/signed byte/word/signed word/dword/signed dword) 24+(byte/word/signed word/dword/signed dword) 149 -- vwsz1=vbsaa_plus_vbuc1 sta xpos ora #$7f @@ -3656,6 +3655,8 @@ anim: { jmp b1 } //SEG108 mulf8s_prepared +// 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: { .label memA = $fd .label m = 5 @@ -3663,12 +3664,10 @@ mulf8s_prepared: { //SEG109 [63] call mulf8u_prepared jsr mulf8u_prepared //SEG110 [64] (word) mulf8u_prepared::return#2 ← (word) mulf8u_prepared::return#0 - // (word) mulf8u_prepared::return#2 = (word) mulf8u_prepared::return#0 // register copy zp ZP_WORD:5 jmp b6 //SEG111 mulf8s_prepared::@6 b6: //SEG112 [65] (word) mulf8s_prepared::m#0 ← (word) mulf8u_prepared::return#2 - // (word) mulf8s_prepared::m#0 = (word) mulf8u_prepared::return#2 // register copy zp ZP_WORD:5 //SEG113 [66] if(*((const signed byte*) mulf8s_prepared::memA#0)>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mulf8s_prepared::@1 -- _deref_pbsc1_ge_0_then_la1 lda memA cmp #0 @@ -3722,6 +3721,8 @@ mulf8s_prepared: { rts } //SEG133 mulf8u_prepared +// 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: { .label resL = $fe .label memB = $ff @@ -3753,6 +3754,7 @@ mulf8u_prepared: { rts } //SEG139 mulf8u_prepare +// Prepare for fast multiply with an unsigned byte to a word result mulf8u_prepare: { .label memA = $fd //SEG140 [84] *((const byte*) mulf8u_prepare::memA#0) ← (byte) mulf8u_prepare::a#2 -- _deref_pbuc1=vbuaa @@ -3812,6 +3814,7 @@ init: { rts } //SEG160 mulf_init +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label sqr1_hi = 7 .label sqr = 9 @@ -4595,7 +4598,6 @@ anim: { //SEG46 [62] phi (signed byte) mulf8s_prepared::b#4 = (signed byte) mulf8s_prepared::b#0 [phi:anim::@17->mulf8s_prepared#0] -- register_copy jsr mulf8s_prepared //SEG47 [21] (signed word) mulf8s_prepared::return#2 ← (signed word)(word) mulf8s_prepared::m#4 - // (signed word) mulf8s_prepared::return#2 = (signed word)(word) mulf8s_prepared::m#4 // register copy zp ZP_WORD:5 //SEG48 anim::@20 //SEG49 [22] (signed word~) anim::$4 ← (signed word) mulf8s_prepared::return#2 -- vwsz1=vwsz2 lda mulf8s_prepared.return @@ -4612,7 +4614,6 @@ anim: { //SEG54 [62] phi (signed byte) mulf8s_prepared::b#4 = (signed byte) mulf8s_prepared::b#1 [phi:anim::@20->mulf8s_prepared#0] -- register_copy jsr mulf8s_prepared //SEG55 [26] (signed word) mulf8s_prepared::return#3 ← (signed word)(word) mulf8s_prepared::m#4 - // (signed word) mulf8s_prepared::return#3 = (signed word)(word) mulf8s_prepared::m#4 // register copy zp ZP_WORD:5 //SEG56 anim::@21 //SEG57 [27] (signed word~) anim::$6 ← (signed word) mulf8s_prepared::return#3 -- vwsz1=vwsz2 lda mulf8s_prepared.return @@ -4638,10 +4639,8 @@ anim: { //SEG68 [62] phi (signed byte) mulf8s_prepared::b#4 = (signed byte) mulf8s_prepared::b#2 [phi:anim::@18->mulf8s_prepared#0] -- register_copy jsr mulf8s_prepared //SEG69 [33] (signed word) mulf8s_prepared::return#4 ← (signed word)(word) mulf8s_prepared::m#4 - // (signed word) mulf8s_prepared::return#4 = (signed word)(word) mulf8s_prepared::m#4 // register copy zp ZP_WORD:5 //SEG70 anim::@23 //SEG71 [34] (signed word~) anim::$9 ← (signed word) mulf8s_prepared::return#4 - // (signed word~) anim::$9 = (signed word) mulf8s_prepared::return#4 // register copy zp ZP_WORD:5 //SEG72 [35] (signed word~) anim::$10 ← (signed word~) anim::$9 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vwsz1=vwsz1_rol_1 asl _10 rol _10+1 @@ -4660,10 +4659,8 @@ anim: { //SEG77 [62] phi (signed byte) mulf8s_prepared::b#4 = (signed byte) mulf8s_prepared::b#3 [phi:anim::@23->mulf8s_prepared#0] -- register_copy jsr mulf8s_prepared //SEG78 [39] (signed word) mulf8s_prepared::return#10 ← (signed word)(word) mulf8s_prepared::m#4 - // (signed word) mulf8s_prepared::return#10 = (signed word)(word) mulf8s_prepared::m#4 // register copy zp ZP_WORD:5 //SEG79 anim::@24 //SEG80 [40] (signed word~) anim::$11 ← (signed word) mulf8s_prepared::return#10 - // (signed word~) anim::$11 = (signed word) mulf8s_prepared::return#10 // register copy zp ZP_WORD:5 //SEG81 [41] (signed word~) anim::$12 ← (signed word~) anim::$11 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vwsz1=vwsz1_rol_1 asl _12 rol _12+1 @@ -4678,7 +4675,6 @@ anim: { //SEG83 [43] (byte~) anim::$13 ← > (signed word) anim::xr#1 -- vbuaa=_hi_vwsz1 lda xr+1 //SEG84 [44] (signed byte~) anim::$15 ← (signed byte)(byte~) anim::$13 - // (signed byte~) anim::$15 = (signed byte)(byte~) anim::$13 // register copy reg byte a //SEG85 [45] (signed word) anim::xpos#0 ← (signed byte~) anim::$15 + (byte/signed byte/word/signed word/dword/signed dword) 24+(byte/word/signed word/dword/signed dword) 149 -- vwsz1=vbsaa_plus_vbuc1 sta xpos ora #$7f @@ -4747,6 +4743,8 @@ anim: { jmp b4 } //SEG108 mulf8s_prepared +// 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: { .label memA = $fd .label m = 5 @@ -4754,10 +4752,8 @@ mulf8s_prepared: { //SEG109 [63] call mulf8u_prepared jsr mulf8u_prepared //SEG110 [64] (word) mulf8u_prepared::return#2 ← (word) mulf8u_prepared::return#0 - // (word) mulf8u_prepared::return#2 = (word) mulf8u_prepared::return#0 // register copy zp ZP_WORD:5 //SEG111 mulf8s_prepared::@6 //SEG112 [65] (word) mulf8s_prepared::m#0 ← (word) mulf8u_prepared::return#2 - // (word) mulf8s_prepared::m#0 = (word) mulf8u_prepared::return#2 // register copy zp ZP_WORD:5 //SEG113 [66] if(*((const signed byte*) mulf8s_prepared::memA#0)>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mulf8s_prepared::@1 -- _deref_pbsc1_ge_0_then_la1 lda memA cmp #0 @@ -4797,6 +4793,8 @@ mulf8s_prepared: { rts } //SEG133 mulf8u_prepared +// 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: { .label resL = $fe .label memB = $ff @@ -4826,6 +4824,7 @@ mulf8u_prepared: { rts } //SEG139 mulf8u_prepare +// Prepare for fast multiply with an unsigned byte to a word result mulf8u_prepare: { .label memA = $fd //SEG140 [84] *((const byte*) mulf8u_prepare::memA#0) ← (byte) mulf8u_prepare::a#2 -- _deref_pbuc1=vbuaa @@ -4873,6 +4872,7 @@ init: { rts } //SEG160 mulf_init +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label sqr1_hi = 7 .label sqr = 9 diff --git a/src/test/ref/examples/scrollbig/scrollbig.asm b/src/test/ref/examples/scrollbig/scrollbig.asm index 9b7e96d0d..f0a6cbd41 100644 --- a/src/test/ref/examples/scrollbig/scrollbig.asm +++ b/src/test/ref/examples/scrollbig/scrollbig.asm @@ -136,6 +136,7 @@ scroll_hard: { bne b1 rts } +// Find the next char of the scroll text next_char: { ldy #0 lda (nxt),y @@ -153,6 +154,7 @@ next_char: { !: rts } +// Fill the screen with one char fillscreen: { .const fill = $20 .label cursor = 3 diff --git a/src/test/ref/examples/scrollbig/scrollbig.log b/src/test/ref/examples/scrollbig/scrollbig.log index d58c2b5e9..1f79fbf67 100644 --- a/src/test/ref/examples/scrollbig/scrollbig.log +++ b/src/test/ref/examples/scrollbig/scrollbig.log @@ -1927,6 +1927,7 @@ scroll_hard: { rts } //SEG122 next_char +// Find the next char of the scroll text next_char: { .label return = $10 .label c = $d @@ -1973,6 +1974,7 @@ next_char: { rts } //SEG137 fillscreen +// Fill the screen with one char fillscreen: { .const fill = $20 .label cursor = $e @@ -2262,12 +2264,10 @@ scroll_bit: { //SEG57 [22] call next_char jsr next_char //SEG58 [23] (byte) next_char::return#0 ← (byte) next_char::return#1 - // (byte) next_char::return#0 = (byte) next_char::return#1 // register copy reg byte a jmp b8 //SEG59 scroll_bit::@8 b8: //SEG60 [24] (byte~) scroll_bit::$3 ← (byte) next_char::return#0 - // (byte~) scroll_bit::$3 = (byte) next_char::return#0 // register copy reg byte a //SEG61 [25] (word) scroll_bit::c#0 ← ((word)) (byte~) scroll_bit::$3 -- vwuz1=_word_vbuaa sta c lda #0 @@ -2437,6 +2437,7 @@ scroll_hard: { rts } //SEG122 next_char +// Find the next char of the scroll text next_char: { //SEG123 [58] (byte) next_char::c#0 ← *((byte*) nxt#31) -- vbuaa=_deref_pbuz1 ldy #0 @@ -2477,6 +2478,7 @@ next_char: { rts } //SEG137 fillscreen +// Fill the screen with one char fillscreen: { .const fill = $20 .label cursor = 3 @@ -2845,10 +2847,8 @@ scroll_bit: { //SEG57 [22] call next_char jsr next_char //SEG58 [23] (byte) next_char::return#0 ← (byte) next_char::return#1 - // (byte) next_char::return#0 = (byte) next_char::return#1 // register copy reg byte a //SEG59 scroll_bit::@8 //SEG60 [24] (byte~) scroll_bit::$3 ← (byte) next_char::return#0 - // (byte~) scroll_bit::$3 = (byte) next_char::return#0 // register copy reg byte a //SEG61 [25] (word) scroll_bit::c#0 ← ((word)) (byte~) scroll_bit::$3 -- vwuz1=_word_vbuaa sta c lda #0 @@ -2992,6 +2992,7 @@ scroll_hard: { rts } //SEG122 next_char +// Find the next char of the scroll text next_char: { //SEG123 [58] (byte) next_char::c#0 ← *((byte*) nxt#31) -- vbuaa=_deref_pbuz1 ldy #0 @@ -3024,6 +3025,7 @@ next_char: { rts } //SEG137 fillscreen +// Fill the screen with one char fillscreen: { .const fill = $20 .label cursor = 3 diff --git a/src/test/ref/examples/scrolllogo/scrolllogo.asm b/src/test/ref/examples/scrolllogo/scrolllogo.asm index 91e1a3d9e..5f0c31131 100644 --- a/src/test/ref/examples/scrolllogo/scrolllogo.asm +++ b/src/test/ref/examples/scrolllogo/scrolllogo.asm @@ -228,6 +228,9 @@ render_logo: { iny jmp b11 } +// Generate signed word sinus table - with values in the range min-max. +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen2: { .const min = -$140 .const max = $140 @@ -315,6 +318,8 @@ sin16s_gen2: { !: rts } +// Multiply of two signed words to a signed double word +// Fixes offsets introduced by using unsigned multiplication mul16s: { .label _5 = 2 .label _6 = $e @@ -355,6 +360,7 @@ mul16s: { b2: rts } +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label mb = $12 .label a = $10 @@ -406,6 +412,9 @@ mul16u: { rol mb+3 jmp b1 } +// 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: { .label _6 = $a .label x = $a @@ -579,6 +588,8 @@ sin16s: { b3: rts } +// 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: { .label _0 = $a .label _1 = $a @@ -608,6 +619,8 @@ mulu16_sel: { sta return+1 rts } +// 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_lo = $e @@ -639,6 +652,10 @@ div32u16u: { sta return+1 rts } +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 8 @@ -688,6 +705,8 @@ divr16u: { bne b1 rts } +// Simple routines for working with memory +// Fill some memory with a value fill: { .label end = 8 .label addr = 2 diff --git a/src/test/ref/examples/scrolllogo/scrolllogo.log b/src/test/ref/examples/scrolllogo/scrolllogo.log index 0616090b4..b113ed2df 100644 --- a/src/test/ref/examples/scrolllogo/scrolllogo.log +++ b/src/test/ref/examples/scrolllogo/scrolllogo.log @@ -4731,6 +4731,9 @@ render_logo: { jmp b11 } //SEG183 sin16s_gen2 +// Generate signed word sinus table - with values in the range min-max. +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen2: { .const min = -$140 .const max = $140 @@ -4906,6 +4909,8 @@ sin16s_gen2: { rts } //SEG216 mul16s +// Multiply of two signed words to a signed double word +// Fixes offsets introduced by using unsigned multiplication mul16s: { .label _5 = $6c .label _6 = $6e @@ -5005,6 +5010,7 @@ mul16s: { rts } //SEG238 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label _1 = $76 .label mb = $1d @@ -5096,6 +5102,9 @@ mul16u: { jmp b1 } //SEG262 sin16s +// 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: { .label _6 = $77 .label x = $22 @@ -5451,6 +5460,8 @@ sin16s: { jmp b3_from_b15 } //SEG343 mulu16_sel +// 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: { .label _0 = $9b .label _1 = $9f @@ -5531,6 +5542,8 @@ mulu16_sel: { rts } //SEG357 div32u16u +// 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 = $a7 .label quotient_lo = $ab @@ -5607,6 +5620,10 @@ div32u16u: { rts } //SEG376 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label _1 = $b1 .label _2 = $b2 @@ -5727,6 +5744,8 @@ divr16u: { rts } //SEG413 fill +// Simple routines for working with memory +// Fill some memory with a value fill: { .label end = $b5 .label addr = $35 @@ -6438,7 +6457,6 @@ loop: { stx xpos sta xpos+1 //SEG59 [31] (signed word) render_logo::xpos#0 ← (signed word) loop::xpos#0 - // (signed word) render_logo::xpos#0 = (signed word) loop::xpos#0 // register copy zp ZP_WORD:8 //SEG60 [32] call render_logo jsr render_logo jmp b15 @@ -6790,6 +6808,9 @@ render_logo: { jmp b11 } //SEG183 sin16s_gen2 +// Generate signed word sinus table - with values in the range min-max. +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen2: { .const min = -$140 .const max = $140 @@ -6807,12 +6828,10 @@ sin16s_gen2: { div32u16u_from_sin16s_gen2: jsr div32u16u //SEG186 [100] (dword) div32u16u::return#2 ← (dword) div32u16u::return#0 - // (dword) div32u16u::return#2 = (dword) div32u16u::return#0 // register copy zp ZP_DWORD:27 jmp b3 //SEG187 sin16s_gen2::@3 b3: //SEG188 [101] (dword) sin16s_gen2::step#0 ← (dword) div32u16u::return#2 - // (dword) sin16s_gen2::step#0 = (dword) div32u16u::return#2 // register copy zp ZP_DWORD:27 //SEG189 [102] phi from sin16s_gen2::@3 to sin16s_gen2::@1 [phi:sin16s_gen2::@3->sin16s_gen2::@1] b1_from_b3: //SEG190 [102] phi (word) sin16s_gen2::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin16s_gen2::@3->sin16s_gen2::@1#0] -- vwuz1=vbuc1 @@ -6853,21 +6872,17 @@ sin16s_gen2: { //SEG199 [104] call sin16s jsr sin16s //SEG200 [105] (signed word) sin16s::return#0 ← (signed word) sin16s::return#1 - // (signed word) sin16s::return#0 = (signed word) sin16s::return#1 // register copy zp ZP_WORD:23 jmp b4 //SEG201 sin16s_gen2::@4 b4: //SEG202 [106] (signed word) mul16s::a#0 ← (signed word) sin16s::return#0 - // (signed word) mul16s::a#0 = (signed word) sin16s::return#0 // register copy zp ZP_WORD:23 //SEG203 [107] call mul16s jsr mul16s //SEG204 [108] (signed dword) mul16s::return#2 ← (signed dword) mul16s::return#0 - // (signed dword) mul16s::return#2 = (signed dword) mul16s::return#0 // register copy zp ZP_DWORD:10 jmp b5 //SEG205 sin16s_gen2::@5 b5: //SEG206 [109] (signed dword~) sin16s_gen2::$5 ← (signed dword) mul16s::return#2 - // (signed dword~) sin16s_gen2::$5 = (signed dword) mul16s::return#2 // register copy zp ZP_DWORD:10 //SEG207 [110] (word~) sin16s_gen2::$6 ← > (signed dword~) sin16s_gen2::$5 -- vwuz1=_hi_vdsz2 lda _5+2 sta _6 @@ -6931,6 +6946,8 @@ sin16s_gen2: { rts } //SEG216 mul16s +// Multiply of two signed words to a signed double word +// Fixes offsets introduced by using unsigned multiplication mul16s: { .label _5 = 2 .label _6 = $e @@ -6954,12 +6971,10 @@ mul16s: { sta mul16u.b+1 jsr mul16u //SEG222 [120] (dword) mul16u::return#2 ← (dword) mul16u::res#2 - // (dword) mul16u::return#2 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:10 jmp b6 //SEG223 mul16s::@6 b6: //SEG224 [121] (dword) mul16s::m#0 ← (dword) mul16u::return#2 - // (dword) mul16s::m#0 = (dword) mul16u::return#2 // register copy zp ZP_DWORD:10 //SEG225 [122] if((signed word) mul16s::a#0>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mul16s::@1 -- vwsz1_ge_0_then_la1 lda a+1 bpl b1_from_b6 @@ -7007,6 +7022,7 @@ mul16s: { rts } //SEG238 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label mb = $12 .label a = $10 @@ -7094,6 +7110,9 @@ mul16u: { jmp b1 } //SEG262 sin16s +// 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: { .label _6 = $a .label x = $a @@ -7232,7 +7251,6 @@ sin16s: { //SEG287 [181] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#0 [phi:sin16s::@2->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG288 [152] (word) mulu16_sel::return#0 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#0 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:14 jmp b8 //SEG289 sin16s::@8 b8: @@ -7242,7 +7260,6 @@ sin16s: { lda mulu16_sel.return+1 sta x2+1 //SEG291 [154] (word) mulu16_sel::v1#1 ← (word) sin16s::x2#0 - // (word) mulu16_sel::v1#1 = (word) sin16s::x2#0 // register copy zp ZP_WORD:25 //SEG292 [155] (word) mulu16_sel::v2#1 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -7265,9 +7282,7 @@ sin16s: { //SEG299 sin16s::@9 b9: //SEG300 [158] (word) sin16s::x3#0 ← (word) mulu16_sel::return#1 - // (word) sin16s::x3#0 = (word) mulu16_sel::return#1 // register copy zp ZP_WORD:25 //SEG301 [159] (word) mulu16_sel::v1#2 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#2 = (word) sin16s::x3#0 // register copy zp ZP_WORD:25 //SEG302 [160] call mulu16_sel //SEG303 [181] phi from sin16s::@9 to mulu16_sel [phi:sin16s::@9->mulu16_sel] mulu16_sel_from_b9: @@ -7281,12 +7296,10 @@ sin16s: { //SEG306 [181] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#2 [phi:sin16s::@9->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG307 [161] (word) mulu16_sel::return#2 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#2 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:14 jmp b10 //SEG308 sin16s::@10 b10: //SEG309 [162] (word) sin16s::x3_6#0 ← (word) mulu16_sel::return#2 - // (word) sin16s::x3_6#0 = (word) mulu16_sel::return#2 // register copy zp ZP_WORD:14 //SEG310 [163] (word) sin16s::usinx#0 ← (word) sin16s::x1#0 - (word) sin16s::x3_6#0 -- vwuz1=vwuz2_minus_vwuz3 lda x1 sec @@ -7296,7 +7309,6 @@ sin16s: { sbc x3_6+1 sta usinx+1 //SEG311 [164] (word) mulu16_sel::v1#3 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#3 = (word) sin16s::x3#0 // register copy zp ZP_WORD:25 //SEG312 [165] (word) mulu16_sel::v2#3 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -7319,9 +7331,7 @@ sin16s: { //SEG319 sin16s::@11 b11: //SEG320 [168] (word) sin16s::x4#0 ← (word) mulu16_sel::return#10 - // (word) sin16s::x4#0 = (word) mulu16_sel::return#10 // register copy zp ZP_WORD:25 //SEG321 [169] (word) mulu16_sel::v1#4 ← (word) sin16s::x4#0 - // (word) mulu16_sel::v1#4 = (word) sin16s::x4#0 // register copy zp ZP_WORD:25 //SEG322 [170] (word) mulu16_sel::v2#4 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -7336,12 +7346,10 @@ sin16s: { //SEG327 [181] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#4 [phi:sin16s::@11->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG328 [172] (word) mulu16_sel::return#11 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#11 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:14 jmp b12 //SEG329 sin16s::@12 b12: //SEG330 [173] (word) sin16s::x5#0 ← (word) mulu16_sel::return#11 - // (word) sin16s::x5#0 = (word) mulu16_sel::return#11 // register copy zp ZP_WORD:14 //SEG331 [174] (word) sin16s::x5_128#0 ← (word) sin16s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vwuz1=vwuz1_ror_4 ldy #4 !: @@ -7389,10 +7397,11 @@ sin16s: { //SEG341 sin16s::@15 b15: //SEG342 [180] (signed word~) sin16s::return#5 ← (signed word)(word) sin16s::usinx#1 - // (signed word~) sin16s::return#5 = (signed word)(word) sin16s::usinx#1 // register copy zp ZP_WORD:23 jmp b3_from_b15 } //SEG343 mulu16_sel +// 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: { .label _0 = $a .label _1 = $a @@ -7407,7 +7416,6 @@ mulu16_sel: { lda v1+1 sta mul16u.a+1 //SEG345 [183] (word) mul16u::b#1 ← (word) mulu16_sel::v2#5 - // (word) mul16u::b#1 = (word) mulu16_sel::v2#5 // register copy zp ZP_WORD:14 //SEG346 [184] call mul16u //SEG347 [130] phi from mulu16_sel to mul16u [phi:mulu16_sel->mul16u] mul16u_from_mulu16_sel: @@ -7415,12 +7423,10 @@ mulu16_sel: { //SEG349 [130] phi (word) mul16u::b#2 = (word) mul16u::b#1 [phi:mulu16_sel->mul16u#1] -- register_copy jsr mul16u //SEG350 [185] (dword) mul16u::return#3 ← (dword) mul16u::res#2 - // (dword) mul16u::return#3 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:10 jmp b2 //SEG351 mulu16_sel::@2 b2: //SEG352 [186] (dword~) mulu16_sel::$0 ← (dword) mul16u::return#3 - // (dword~) mulu16_sel::$0 = (dword) mul16u::return#3 // register copy zp ZP_DWORD:10 //SEG353 [187] (dword~) mulu16_sel::$1 ← (dword~) mulu16_sel::$0 << (byte) mulu16_sel::select#5 -- vduz1=vduz1_rol_vbuxx cpx #0 beq !e+ @@ -7444,6 +7450,8 @@ mulu16_sel: { rts } //SEG357 div32u16u +// 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_lo = $e @@ -7463,7 +7471,6 @@ div32u16u: { sta divr16u.rem+1 jsr divr16u //SEG362 [192] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:14 jmp b2 //SEG363 div32u16u::@2 b2: @@ -7473,7 +7480,6 @@ div32u16u: { lda divr16u.return+1 sta quotient_hi+1 //SEG365 [194] (word) divr16u::rem#4 ← (word) rem16u#1 - // (word) divr16u::rem#4 = (word) rem16u#1 // register copy zp ZP_WORD:2 //SEG366 [195] call divr16u //SEG367 [200] phi from div32u16u::@2 to divr16u [phi:div32u16u::@2->divr16u] divr16u_from_b2: @@ -7485,12 +7491,10 @@ div32u16u: { //SEG369 [200] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:div32u16u::@2->divr16u#1] -- register_copy jsr divr16u //SEG370 [196] (word) divr16u::return#3 ← (word) divr16u::return#0 - // (word) divr16u::return#3 = (word) divr16u::return#0 // register copy zp ZP_WORD:14 jmp b3 //SEG371 div32u16u::@3 b3: //SEG372 [197] (word) div32u16u::quotient_lo#0 ← (word) divr16u::return#3 - // (word) div32u16u::quotient_lo#0 = (word) divr16u::return#3 // register copy zp ZP_WORD:14 //SEG373 [198] (dword) div32u16u::return#0 ← (word) div32u16u::quotient_hi#0 dw= (word) div32u16u::quotient_lo#0 -- vduz1=vwuz2_dword_vwuz3 lda quotient_hi sta return+2 @@ -7507,6 +7511,10 @@ div32u16u: { rts } //SEG376 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 8 @@ -7605,7 +7613,6 @@ divr16u: { //SEG409 divr16u::@6 b6: //SEG410 [216] (word) rem16u#1 ← (word) divr16u::rem#11 - // (word) rem16u#1 = (word) divr16u::rem#11 // register copy zp ZP_WORD:2 jmp breturn //SEG411 divr16u::@return breturn: @@ -7613,6 +7620,8 @@ divr16u: { rts } //SEG413 fill +// Simple routines for working with memory +// Fill some memory with a value fill: { .label end = 8 .label addr = 2 @@ -7798,6 +7807,7 @@ Removing instruction b16_from_b15: Removing instruction b7_from_b16: Removing instruction b15_from_b11: Removing instruction b15_from_b35: +Removing instruction b1_from_b3: Removing instruction b1_from_b5: Removing instruction b1_from_b3: Removing instruction b1_from_b6: @@ -7807,6 +7817,7 @@ Removing instruction b4_from_b2: Removing instruction b4_from_b7: Removing instruction b2_from_b1: Removing instruction b2_from_b5: +Removing instruction mulu16_sel_from_b9: Removing instruction b3_from_b15: Removing instruction b3_from_b6: Removing instruction breturn: @@ -7815,6 +7826,7 @@ Removing instruction b2_from_b1: Removing instruction b2_from_b4: Removing instruction b3_from_b2: Removing instruction b3_from_b5: +Removing instruction breturn: Removing instruction b1_from_fill: Removing instruction b1_from_b1: Succesful ASM optimization Pass5RedundantLabelElimination @@ -7863,7 +7875,6 @@ Removing instruction b31: Removing instruction b11_from_b31: Removing instruction div32u16u_from_sin16s_gen2: Removing instruction b3: -Removing instruction b1_from_b3: Removing instruction b4: Removing instruction b5: Removing instruction breturn: @@ -7881,7 +7892,6 @@ Removing instruction mulu16_sel_from_b2: Removing instruction b8: Removing instruction mulu16_sel_from_b8: Removing instruction b9: -Removing instruction mulu16_sel_from_b9: Removing instruction b10: Removing instruction mulu16_sel_from_b10: Removing instruction b11: @@ -7901,7 +7911,6 @@ Removing instruction b4: Removing instruction b5: Removing instruction b6: Removing instruction breturn: -Removing instruction breturn: Succesful ASM optimization Pass5UnusedLabelElimination Updating BasicUpstart to call main directly Removing instruction jsr main @@ -8565,7 +8574,6 @@ loop: { stx xpos sta xpos+1 //SEG59 [31] (signed word) render_logo::xpos#0 ← (signed word) loop::xpos#0 - // (signed word) render_logo::xpos#0 = (signed word) loop::xpos#0 // register copy zp ZP_WORD:8 //SEG60 [32] call render_logo jsr render_logo //SEG61 loop::@15 @@ -8835,6 +8843,9 @@ render_logo: { jmp b11 } //SEG183 sin16s_gen2 +// Generate signed word sinus table - with values in the range min-max. +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen2: { .const min = -$140 .const max = $140 @@ -8851,10 +8862,8 @@ sin16s_gen2: { //SEG185 [190] phi from sin16s_gen2 to div32u16u [phi:sin16s_gen2->div32u16u] jsr div32u16u //SEG186 [100] (dword) div32u16u::return#2 ← (dword) div32u16u::return#0 - // (dword) div32u16u::return#2 = (dword) div32u16u::return#0 // register copy zp ZP_DWORD:27 //SEG187 sin16s_gen2::@3 //SEG188 [101] (dword) sin16s_gen2::step#0 ← (dword) div32u16u::return#2 - // (dword) sin16s_gen2::step#0 = (dword) div32u16u::return#2 // register copy zp ZP_DWORD:27 //SEG189 [102] phi from sin16s_gen2::@3 to sin16s_gen2::@1 [phi:sin16s_gen2::@3->sin16s_gen2::@1] //SEG190 [102] phi (word) sin16s_gen2::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin16s_gen2::@3->sin16s_gen2::@1#0] -- vwuz1=vbuc1 lda #<0 @@ -8889,17 +8898,13 @@ sin16s_gen2: { //SEG199 [104] call sin16s jsr sin16s //SEG200 [105] (signed word) sin16s::return#0 ← (signed word) sin16s::return#1 - // (signed word) sin16s::return#0 = (signed word) sin16s::return#1 // register copy zp ZP_WORD:23 //SEG201 sin16s_gen2::@4 //SEG202 [106] (signed word) mul16s::a#0 ← (signed word) sin16s::return#0 - // (signed word) mul16s::a#0 = (signed word) sin16s::return#0 // register copy zp ZP_WORD:23 //SEG203 [107] call mul16s jsr mul16s //SEG204 [108] (signed dword) mul16s::return#2 ← (signed dword) mul16s::return#0 - // (signed dword) mul16s::return#2 = (signed dword) mul16s::return#0 // register copy zp ZP_DWORD:10 //SEG205 sin16s_gen2::@5 //SEG206 [109] (signed dword~) sin16s_gen2::$5 ← (signed dword) mul16s::return#2 - // (signed dword~) sin16s_gen2::$5 = (signed dword) mul16s::return#2 // register copy zp ZP_DWORD:10 //SEG207 [110] (word~) sin16s_gen2::$6 ← > (signed dword~) sin16s_gen2::$5 -- vwuz1=_hi_vdsz2 lda _5+2 sta _6 @@ -8961,6 +8966,8 @@ sin16s_gen2: { rts } //SEG216 mul16s +// Multiply of two signed words to a signed double word +// Fixes offsets introduced by using unsigned multiplication mul16s: { .label _5 = 2 .label _6 = $e @@ -8983,10 +8990,8 @@ mul16s: { sta mul16u.b+1 jsr mul16u //SEG222 [120] (dword) mul16u::return#2 ← (dword) mul16u::res#2 - // (dword) mul16u::return#2 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:10 //SEG223 mul16s::@6 //SEG224 [121] (dword) mul16s::m#0 ← (dword) mul16u::return#2 - // (dword) mul16s::m#0 = (dword) mul16u::return#2 // register copy zp ZP_DWORD:10 //SEG225 [122] if((signed word) mul16s::a#0>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mul16s::@1 -- vwsz1_ge_0_then_la1 lda a+1 bpl b2 @@ -9025,6 +9030,7 @@ mul16s: { rts } //SEG238 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label mb = $12 .label a = $10 @@ -9100,6 +9106,9 @@ mul16u: { jmp b1 } //SEG262 sin16s +// 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: { .label _6 = $a .label x = $a @@ -9228,7 +9237,6 @@ sin16s: { //SEG287 [181] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#0 [phi:sin16s::@2->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG288 [152] (word) mulu16_sel::return#0 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#0 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:14 //SEG289 sin16s::@8 //SEG290 [153] (word) sin16s::x2#0 ← (word) mulu16_sel::return#0 -- vwuz1=vwuz2 lda mulu16_sel.return @@ -9236,7 +9244,6 @@ sin16s: { lda mulu16_sel.return+1 sta x2+1 //SEG291 [154] (word) mulu16_sel::v1#1 ← (word) sin16s::x2#0 - // (word) mulu16_sel::v1#1 = (word) sin16s::x2#0 // register copy zp ZP_WORD:25 //SEG292 [155] (word) mulu16_sel::v2#1 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -9256,9 +9263,7 @@ sin16s: { sta mulu16_sel.return_1+1 //SEG299 sin16s::@9 //SEG300 [158] (word) sin16s::x3#0 ← (word) mulu16_sel::return#1 - // (word) sin16s::x3#0 = (word) mulu16_sel::return#1 // register copy zp ZP_WORD:25 //SEG301 [159] (word) mulu16_sel::v1#2 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#2 = (word) sin16s::x3#0 // register copy zp ZP_WORD:25 //SEG302 [160] call mulu16_sel //SEG303 [181] phi from sin16s::@9 to mulu16_sel [phi:sin16s::@9->mulu16_sel] //SEG304 [181] phi (byte) mulu16_sel::select#5 = (byte/signed byte/word/signed word/dword/signed dword) 1 [phi:sin16s::@9->mulu16_sel#0] -- vbuxx=vbuc1 @@ -9271,10 +9276,8 @@ sin16s: { //SEG306 [181] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#2 [phi:sin16s::@9->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG307 [161] (word) mulu16_sel::return#2 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#2 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:14 //SEG308 sin16s::@10 //SEG309 [162] (word) sin16s::x3_6#0 ← (word) mulu16_sel::return#2 - // (word) sin16s::x3_6#0 = (word) mulu16_sel::return#2 // register copy zp ZP_WORD:14 //SEG310 [163] (word) sin16s::usinx#0 ← (word) sin16s::x1#0 - (word) sin16s::x3_6#0 -- vwuz1=vwuz2_minus_vwuz3 lda x1 sec @@ -9284,7 +9287,6 @@ sin16s: { sbc x3_6+1 sta usinx+1 //SEG311 [164] (word) mulu16_sel::v1#3 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#3 = (word) sin16s::x3#0 // register copy zp ZP_WORD:25 //SEG312 [165] (word) mulu16_sel::v2#3 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -9304,9 +9306,7 @@ sin16s: { sta mulu16_sel.return_10+1 //SEG319 sin16s::@11 //SEG320 [168] (word) sin16s::x4#0 ← (word) mulu16_sel::return#10 - // (word) sin16s::x4#0 = (word) mulu16_sel::return#10 // register copy zp ZP_WORD:25 //SEG321 [169] (word) mulu16_sel::v1#4 ← (word) sin16s::x4#0 - // (word) mulu16_sel::v1#4 = (word) sin16s::x4#0 // register copy zp ZP_WORD:25 //SEG322 [170] (word) mulu16_sel::v2#4 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -9320,10 +9320,8 @@ sin16s: { //SEG327 [181] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#4 [phi:sin16s::@11->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG328 [172] (word) mulu16_sel::return#11 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#11 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:14 //SEG329 sin16s::@12 //SEG330 [173] (word) sin16s::x5#0 ← (word) mulu16_sel::return#11 - // (word) sin16s::x5#0 = (word) mulu16_sel::return#11 // register copy zp ZP_WORD:14 //SEG331 [174] (word) sin16s::x5_128#0 ← (word) sin16s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vwuz1=vwuz1_ror_4 ldy #4 !: @@ -9363,9 +9361,10 @@ sin16s: { rts //SEG341 sin16s::@15 //SEG342 [180] (signed word~) sin16s::return#5 ← (signed word)(word) sin16s::usinx#1 - // (signed word~) sin16s::return#5 = (signed word)(word) sin16s::usinx#1 // register copy zp ZP_WORD:23 } //SEG343 mulu16_sel +// 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: { .label _0 = $a .label _1 = $a @@ -9380,17 +9379,14 @@ mulu16_sel: { lda v1+1 sta mul16u.a+1 //SEG345 [183] (word) mul16u::b#1 ← (word) mulu16_sel::v2#5 - // (word) mul16u::b#1 = (word) mulu16_sel::v2#5 // register copy zp ZP_WORD:14 //SEG346 [184] call mul16u //SEG347 [130] phi from mulu16_sel to mul16u [phi:mulu16_sel->mul16u] //SEG348 [130] phi (word) mul16u::a#6 = (word) mul16u::a#2 [phi:mulu16_sel->mul16u#0] -- register_copy //SEG349 [130] phi (word) mul16u::b#2 = (word) mul16u::b#1 [phi:mulu16_sel->mul16u#1] -- register_copy jsr mul16u //SEG350 [185] (dword) mul16u::return#3 ← (dword) mul16u::res#2 - // (dword) mul16u::return#3 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:10 //SEG351 mulu16_sel::@2 //SEG352 [186] (dword~) mulu16_sel::$0 ← (dword) mul16u::return#3 - // (dword~) mulu16_sel::$0 = (dword) mul16u::return#3 // register copy zp ZP_DWORD:10 //SEG353 [187] (dword~) mulu16_sel::$1 ← (dword~) mulu16_sel::$0 << (byte) mulu16_sel::select#5 -- vduz1=vduz1_rol_vbuxx cpx #0 beq !e+ @@ -9412,6 +9408,8 @@ mulu16_sel: { rts } //SEG357 div32u16u +// 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_lo = $e @@ -9429,7 +9427,6 @@ div32u16u: { sta divr16u.rem+1 jsr divr16u //SEG362 [192] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:14 //SEG363 div32u16u::@2 //SEG364 [193] (word) div32u16u::quotient_hi#0 ← (word) divr16u::return#2 -- vwuz1=vwuz2 lda divr16u.return @@ -9437,7 +9434,6 @@ div32u16u: { lda divr16u.return+1 sta quotient_hi+1 //SEG365 [194] (word) divr16u::rem#4 ← (word) rem16u#1 - // (word) divr16u::rem#4 = (word) rem16u#1 // register copy zp ZP_WORD:2 //SEG366 [195] call divr16u //SEG367 [200] phi from div32u16u::@2 to divr16u [phi:div32u16u::@2->divr16u] //SEG368 [200] phi (word) divr16u::dividend#5 = <(const dword) PI2_u4f28#0 [phi:div32u16u::@2->divr16u#0] -- vwuz1=vwuc1 @@ -9448,10 +9444,8 @@ div32u16u: { //SEG369 [200] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:div32u16u::@2->divr16u#1] -- register_copy jsr divr16u //SEG370 [196] (word) divr16u::return#3 ← (word) divr16u::return#0 - // (word) divr16u::return#3 = (word) divr16u::return#0 // register copy zp ZP_WORD:14 //SEG371 div32u16u::@3 //SEG372 [197] (word) div32u16u::quotient_lo#0 ← (word) divr16u::return#3 - // (word) div32u16u::quotient_lo#0 = (word) divr16u::return#3 // register copy zp ZP_WORD:14 //SEG373 [198] (dword) div32u16u::return#0 ← (word) div32u16u::quotient_hi#0 dw= (word) div32u16u::quotient_lo#0 -- vduz1=vwuz2_dword_vwuz3 lda quotient_hi sta return+2 @@ -9466,6 +9460,10 @@ div32u16u: { rts } //SEG376 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 8 @@ -9547,12 +9545,13 @@ divr16u: { bne b1 //SEG409 divr16u::@6 //SEG410 [216] (word) rem16u#1 ← (word) divr16u::rem#11 - // (word) rem16u#1 = (word) divr16u::rem#11 // register copy zp ZP_WORD:2 //SEG411 divr16u::@return //SEG412 [217] return rts } //SEG413 fill +// Simple routines for working with memory +// Fill some memory with a value fill: { .label end = 8 .label addr = 2 diff --git a/src/test/ref/examples/showlogo/showlogo.asm b/src/test/ref/examples/showlogo/showlogo.asm index 09efadfcd..06c30bd32 100644 --- a/src/test/ref/examples/showlogo/showlogo.asm +++ b/src/test/ref/examples/showlogo/showlogo.asm @@ -60,6 +60,7 @@ main: { inc $d020 jmp b3 } +// Fill some memory with a value fill: { .label end = 2 .label addr = 4 diff --git a/src/test/ref/examples/showlogo/showlogo.log b/src/test/ref/examples/showlogo/showlogo.log index c58161733..8e7d363a4 100644 --- a/src/test/ref/examples/showlogo/showlogo.log +++ b/src/test/ref/examples/showlogo/showlogo.log @@ -998,6 +998,7 @@ main: { jmp b3 } //SEG43 fill +// Fill some memory with a value fill: { .label end = 8 .label addr = 6 @@ -1220,6 +1221,7 @@ main: { jmp b3 } //SEG43 fill +// Fill some memory with a value fill: { .label end = 2 .label addr = 4 @@ -1565,6 +1567,7 @@ main: { jmp b3 } //SEG43 fill +// Fill some memory with a value fill: { .label end = 2 .label addr = 4 diff --git a/src/test/ref/examples/sinplotter/sine-plotter.asm b/src/test/ref/examples/sinplotter/sine-plotter.asm index 4c1fdf092..855d917bd 100644 --- a/src/test/ref/examples/sinplotter/sine-plotter.asm +++ b/src/test/ref/examples/sinplotter/sine-plotter.asm @@ -151,6 +151,7 @@ render_sine: { !: rts } +// Plot a single dot in the bitmap bitmap_plot: { .label _1 = $10 .label plotter = 6 @@ -216,6 +217,9 @@ wrap_y: { sta y+1 jmp b1 } +// Generate signed word sinus table - with values in the range min-max. +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen2: { .const min = -$140 .const max = $140 @@ -303,6 +307,8 @@ sin16s_gen2: { !: rts } +// Multiply of two signed words to a signed double word +// Fixes offsets introduced by using unsigned multiplication mul16s: { .label _5 = 2 .label _6 = 6 @@ -343,6 +349,7 @@ mul16s: { b2: rts } +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label mb = $12 .label a = $10 @@ -394,6 +401,9 @@ mul16u: { rol mb+3 jmp b1 } +// 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: { .label _6 = $c .label x = $c @@ -567,6 +577,8 @@ sin16s: { b3: rts } +// 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: { .label _0 = $c .label _1 = $c @@ -596,6 +608,8 @@ mulu16_sel: { sta return+1 rts } +// 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_lo = 6 @@ -627,6 +641,10 @@ div32u16u: { sta return+1 rts } +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 4 @@ -676,6 +694,7 @@ divr16u: { bne b1 rts } +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = 2 .label y = $16 @@ -705,6 +724,7 @@ bitmap_clear: { bne b1 rts } +// Initialize bitmap plotting tables bitmap_init: { .label _3 = $16 .label yoffs = 2 @@ -751,6 +771,8 @@ bitmap_init: { bne b3 rts } +// Simple routines for working with memory +// Fill some memory with a value fill: { .const size = $3e8 .label end = SCREEN+size diff --git a/src/test/ref/examples/sinplotter/sine-plotter.log b/src/test/ref/examples/sinplotter/sine-plotter.log index 6cbbd1ed4..921d871c3 100644 --- a/src/test/ref/examples/sinplotter/sine-plotter.log +++ b/src/test/ref/examples/sinplotter/sine-plotter.log @@ -4070,6 +4070,7 @@ render_sine: { jmp b2 } //SEG101 bitmap_plot +// Plot a single dot in the bitmap bitmap_plot: { .label _1 = $53 .label _2 = $57 @@ -4181,6 +4182,9 @@ wrap_y: { jmp b1_from_b2 } //SEG126 sin16s_gen2 +// Generate signed word sinus table - with values in the range min-max. +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen2: { .const min = -$140 .const max = $140 @@ -4356,6 +4360,8 @@ sin16s_gen2: { rts } //SEG159 mul16s +// Multiply of two signed words to a signed double word +// Fixes offsets introduced by using unsigned multiplication mul16s: { .label _5 = $75 .label _6 = $77 @@ -4455,6 +4461,7 @@ mul16s: { rts } //SEG181 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label _1 = $7f .label mb = $1f @@ -4546,6 +4553,9 @@ mul16u: { jmp b1 } //SEG205 sin16s +// 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: { .label _6 = $80 .label x = $24 @@ -4901,6 +4911,8 @@ sin16s: { jmp b3_from_b15 } //SEG286 mulu16_sel +// 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: { .label _0 = $a4 .label _1 = $a8 @@ -4981,6 +4993,8 @@ mulu16_sel: { rts } //SEG300 div32u16u +// 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 = $b0 .label quotient_lo = $b4 @@ -5057,6 +5071,10 @@ div32u16u: { rts } //SEG319 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label _1 = $ba .label _2 = $bb @@ -5177,6 +5195,7 @@ divr16u: { rts } //SEG356 bitmap_clear +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = $37 .label x = $39 @@ -5251,6 +5270,7 @@ bitmap_clear: { rts } //SEG382 bitmap_init +// Initialize bitmap plotting tables bitmap_init: { .label _3 = $c0 .label _4 = $c1 @@ -5389,6 +5409,8 @@ bitmap_init: { jmp b2 } //SEG426 fill +// Simple routines for working with memory +// Fill some memory with a value fill: { .const size = $3e8 .label end = SCREEN+size @@ -6081,23 +6103,19 @@ render_sine: { stx sin_val sta sin_val+1 //SEG57 [30] (signed word) wrap_y::y#0 ← (signed word) render_sine::sin_val#0 - // (signed word) wrap_y::y#0 = (signed word) render_sine::sin_val#0 // register copy zp ZP_WORD:6 //SEG58 [31] call wrap_y //SEG59 [61] phi from render_sine::@1 to wrap_y [phi:render_sine::@1->wrap_y] wrap_y_from_b1: //SEG60 [61] phi (signed word) wrap_y::y#9 = (signed word) wrap_y::y#0 [phi:render_sine::@1->wrap_y#0] -- register_copy jsr wrap_y //SEG61 [32] (byte) wrap_y::return#0 ← (byte) wrap_y::return#2 - // (byte) wrap_y::return#0 = (byte) wrap_y::return#2 // register copy reg byte a jmp b5 //SEG62 render_sine::@5 b5: //SEG63 [33] (byte) render_sine::ypos#0 ← (byte) wrap_y::return#0 -- vbuxx=vbuaa tax //SEG64 [34] (word) bitmap_plot::x#0 ← (word) render_sine::xpos#3 - // (word) bitmap_plot::x#0 = (word) render_sine::xpos#3 // register copy zp ZP_WORD:4 //SEG65 [35] (byte) bitmap_plot::y#0 ← (byte) render_sine::ypos#0 - // (byte) bitmap_plot::y#0 = (byte) render_sine::ypos#0 // register copy reg byte x //SEG66 [36] call bitmap_plot //SEG67 [54] phi from render_sine::@5 to bitmap_plot [phi:render_sine::@5->bitmap_plot] bitmap_plot_from_b5: @@ -6144,16 +6162,13 @@ render_sine: { //SEG77 [61] phi (signed word) wrap_y::y#9 = (signed word) wrap_y::y#1 [phi:render_sine::@6->wrap_y#0] -- register_copy jsr wrap_y //SEG78 [42] (byte) wrap_y::return#1 ← (byte) wrap_y::return#2 - // (byte) wrap_y::return#1 = (byte) wrap_y::return#2 // register copy reg byte a jmp b7 //SEG79 render_sine::@7 b7: //SEG80 [43] (byte) render_sine::ypos2#0 ← (byte) wrap_y::return#1 -- vbuxx=vbuaa tax //SEG81 [44] (word) bitmap_plot::x#1 ← (word) render_sine::xpos#3 - // (word) bitmap_plot::x#1 = (word) render_sine::xpos#3 // register copy zp ZP_WORD:4 //SEG82 [45] (byte) bitmap_plot::y#1 ← (byte) render_sine::ypos2#0 - // (byte) bitmap_plot::y#1 = (byte) render_sine::ypos2#0 // register copy reg byte x //SEG83 [46] call bitmap_plot //SEG84 [54] phi from render_sine::@7 to bitmap_plot [phi:render_sine::@7->bitmap_plot] bitmap_plot_from_b7: @@ -6215,6 +6230,7 @@ render_sine: { jmp b2 } //SEG101 bitmap_plot +// Plot a single dot in the bitmap bitmap_plot: { .label _1 = $10 .label plotter = 6 @@ -6318,6 +6334,9 @@ wrap_y: { jmp b1_from_b2 } //SEG126 sin16s_gen2 +// Generate signed word sinus table - with values in the range min-max. +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen2: { .const min = -$140 .const max = $140 @@ -6335,12 +6354,10 @@ sin16s_gen2: { div32u16u_from_sin16s_gen2: jsr div32u16u //SEG129 [72] (dword) div32u16u::return#2 ← (dword) div32u16u::return#0 - // (dword) div32u16u::return#2 = (dword) div32u16u::return#0 // register copy zp ZP_DWORD:27 jmp b3 //SEG130 sin16s_gen2::@3 b3: //SEG131 [73] (dword) sin16s_gen2::step#0 ← (dword) div32u16u::return#2 - // (dword) sin16s_gen2::step#0 = (dword) div32u16u::return#2 // register copy zp ZP_DWORD:27 //SEG132 [74] phi from sin16s_gen2::@3 to sin16s_gen2::@1 [phi:sin16s_gen2::@3->sin16s_gen2::@1] b1_from_b3: //SEG133 [74] phi (word) sin16s_gen2::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin16s_gen2::@3->sin16s_gen2::@1#0] -- vwuz1=vbuc1 @@ -6381,21 +6398,17 @@ sin16s_gen2: { //SEG142 [76] call sin16s jsr sin16s //SEG143 [77] (signed word) sin16s::return#0 ← (signed word) sin16s::return#1 - // (signed word) sin16s::return#0 = (signed word) sin16s::return#1 // register copy zp ZP_WORD:23 jmp b4 //SEG144 sin16s_gen2::@4 b4: //SEG145 [78] (signed word) mul16s::a#0 ← (signed word) sin16s::return#0 - // (signed word) mul16s::a#0 = (signed word) sin16s::return#0 // register copy zp ZP_WORD:23 //SEG146 [79] call mul16s jsr mul16s //SEG147 [80] (signed dword) mul16s::return#2 ← (signed dword) mul16s::return#0 - // (signed dword) mul16s::return#2 = (signed dword) mul16s::return#0 // register copy zp ZP_DWORD:12 jmp b5 //SEG148 sin16s_gen2::@5 b5: //SEG149 [81] (signed dword~) sin16s_gen2::$5 ← (signed dword) mul16s::return#2 - // (signed dword~) sin16s_gen2::$5 = (signed dword) mul16s::return#2 // register copy zp ZP_DWORD:12 //SEG150 [82] (word~) sin16s_gen2::$6 ← > (signed dword~) sin16s_gen2::$5 -- vwuz1=_hi_vdsz2 lda _5+2 sta _6 @@ -6459,6 +6472,8 @@ sin16s_gen2: { rts } //SEG159 mul16s +// Multiply of two signed words to a signed double word +// Fixes offsets introduced by using unsigned multiplication mul16s: { .label _5 = 2 .label _6 = 6 @@ -6482,12 +6497,10 @@ mul16s: { sta mul16u.b+1 jsr mul16u //SEG165 [92] (dword) mul16u::return#2 ← (dword) mul16u::res#2 - // (dword) mul16u::return#2 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:12 jmp b6 //SEG166 mul16s::@6 b6: //SEG167 [93] (dword) mul16s::m#0 ← (dword) mul16u::return#2 - // (dword) mul16s::m#0 = (dword) mul16u::return#2 // register copy zp ZP_DWORD:12 //SEG168 [94] if((signed word) mul16s::a#0>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mul16s::@1 -- vwsz1_ge_0_then_la1 lda a+1 bpl b1_from_b6 @@ -6535,6 +6548,7 @@ mul16s: { rts } //SEG181 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label mb = $12 .label a = $10 @@ -6622,6 +6636,9 @@ mul16u: { jmp b1 } //SEG205 sin16s +// 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: { .label _6 = $c .label x = $c @@ -6760,7 +6777,6 @@ sin16s: { //SEG230 [153] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#0 [phi:sin16s::@2->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG231 [124] (word) mulu16_sel::return#0 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#0 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:6 jmp b8 //SEG232 sin16s::@8 b8: @@ -6770,7 +6786,6 @@ sin16s: { lda mulu16_sel.return+1 sta x2+1 //SEG234 [126] (word) mulu16_sel::v1#1 ← (word) sin16s::x2#0 - // (word) mulu16_sel::v1#1 = (word) sin16s::x2#0 // register copy zp ZP_WORD:25 //SEG235 [127] (word) mulu16_sel::v2#1 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -6793,9 +6808,7 @@ sin16s: { //SEG242 sin16s::@9 b9: //SEG243 [130] (word) sin16s::x3#0 ← (word) mulu16_sel::return#1 - // (word) sin16s::x3#0 = (word) mulu16_sel::return#1 // register copy zp ZP_WORD:25 //SEG244 [131] (word) mulu16_sel::v1#2 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#2 = (word) sin16s::x3#0 // register copy zp ZP_WORD:25 //SEG245 [132] call mulu16_sel //SEG246 [153] phi from sin16s::@9 to mulu16_sel [phi:sin16s::@9->mulu16_sel] mulu16_sel_from_b9: @@ -6809,12 +6822,10 @@ sin16s: { //SEG249 [153] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#2 [phi:sin16s::@9->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG250 [133] (word) mulu16_sel::return#2 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#2 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:6 jmp b10 //SEG251 sin16s::@10 b10: //SEG252 [134] (word) sin16s::x3_6#0 ← (word) mulu16_sel::return#2 - // (word) sin16s::x3_6#0 = (word) mulu16_sel::return#2 // register copy zp ZP_WORD:6 //SEG253 [135] (word) sin16s::usinx#0 ← (word) sin16s::x1#0 - (word) sin16s::x3_6#0 -- vwuz1=vwuz2_minus_vwuz3 lda x1 sec @@ -6824,7 +6835,6 @@ sin16s: { sbc x3_6+1 sta usinx+1 //SEG254 [136] (word) mulu16_sel::v1#3 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#3 = (word) sin16s::x3#0 // register copy zp ZP_WORD:25 //SEG255 [137] (word) mulu16_sel::v2#3 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -6847,9 +6857,7 @@ sin16s: { //SEG262 sin16s::@11 b11: //SEG263 [140] (word) sin16s::x4#0 ← (word) mulu16_sel::return#10 - // (word) sin16s::x4#0 = (word) mulu16_sel::return#10 // register copy zp ZP_WORD:25 //SEG264 [141] (word) mulu16_sel::v1#4 ← (word) sin16s::x4#0 - // (word) mulu16_sel::v1#4 = (word) sin16s::x4#0 // register copy zp ZP_WORD:25 //SEG265 [142] (word) mulu16_sel::v2#4 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -6864,12 +6872,10 @@ sin16s: { //SEG270 [153] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#4 [phi:sin16s::@11->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG271 [144] (word) mulu16_sel::return#11 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#11 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:6 jmp b12 //SEG272 sin16s::@12 b12: //SEG273 [145] (word) sin16s::x5#0 ← (word) mulu16_sel::return#11 - // (word) sin16s::x5#0 = (word) mulu16_sel::return#11 // register copy zp ZP_WORD:6 //SEG274 [146] (word) sin16s::x5_128#0 ← (word) sin16s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vwuz1=vwuz1_ror_4 ldy #4 !: @@ -6917,10 +6923,11 @@ sin16s: { //SEG284 sin16s::@15 b15: //SEG285 [152] (signed word~) sin16s::return#5 ← (signed word)(word) sin16s::usinx#1 - // (signed word~) sin16s::return#5 = (signed word)(word) sin16s::usinx#1 // register copy zp ZP_WORD:23 jmp b3_from_b15 } //SEG286 mulu16_sel +// 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: { .label _0 = $c .label _1 = $c @@ -6935,7 +6942,6 @@ mulu16_sel: { lda v1+1 sta mul16u.a+1 //SEG288 [155] (word) mul16u::b#1 ← (word) mulu16_sel::v2#5 - // (word) mul16u::b#1 = (word) mulu16_sel::v2#5 // register copy zp ZP_WORD:6 //SEG289 [156] call mul16u //SEG290 [102] phi from mulu16_sel to mul16u [phi:mulu16_sel->mul16u] mul16u_from_mulu16_sel: @@ -6943,12 +6949,10 @@ mulu16_sel: { //SEG292 [102] phi (word) mul16u::b#2 = (word) mul16u::b#1 [phi:mulu16_sel->mul16u#1] -- register_copy jsr mul16u //SEG293 [157] (dword) mul16u::return#3 ← (dword) mul16u::res#2 - // (dword) mul16u::return#3 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:12 jmp b2 //SEG294 mulu16_sel::@2 b2: //SEG295 [158] (dword~) mulu16_sel::$0 ← (dword) mul16u::return#3 - // (dword~) mulu16_sel::$0 = (dword) mul16u::return#3 // register copy zp ZP_DWORD:12 //SEG296 [159] (dword~) mulu16_sel::$1 ← (dword~) mulu16_sel::$0 << (byte) mulu16_sel::select#5 -- vduz1=vduz1_rol_vbuxx cpx #0 beq !e+ @@ -6972,6 +6976,8 @@ mulu16_sel: { rts } //SEG300 div32u16u +// 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_lo = 6 @@ -6991,7 +6997,6 @@ div32u16u: { sta divr16u.rem+1 jsr divr16u //SEG305 [164] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:6 jmp b2 //SEG306 div32u16u::@2 b2: @@ -7001,7 +7006,6 @@ div32u16u: { lda divr16u.return+1 sta quotient_hi+1 //SEG308 [166] (word) divr16u::rem#4 ← (word) rem16u#1 - // (word) divr16u::rem#4 = (word) rem16u#1 // register copy zp ZP_WORD:2 //SEG309 [167] call divr16u //SEG310 [172] phi from div32u16u::@2 to divr16u [phi:div32u16u::@2->divr16u] divr16u_from_b2: @@ -7013,12 +7017,10 @@ div32u16u: { //SEG312 [172] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:div32u16u::@2->divr16u#1] -- register_copy jsr divr16u //SEG313 [168] (word) divr16u::return#3 ← (word) divr16u::return#0 - // (word) divr16u::return#3 = (word) divr16u::return#0 // register copy zp ZP_WORD:6 jmp b3 //SEG314 div32u16u::@3 b3: //SEG315 [169] (word) div32u16u::quotient_lo#0 ← (word) divr16u::return#3 - // (word) div32u16u::quotient_lo#0 = (word) divr16u::return#3 // register copy zp ZP_WORD:6 //SEG316 [170] (dword) div32u16u::return#0 ← (word) div32u16u::quotient_hi#0 dw= (word) div32u16u::quotient_lo#0 -- vduz1=vwuz2_dword_vwuz3 lda quotient_hi sta return+2 @@ -7035,6 +7037,10 @@ div32u16u: { rts } //SEG319 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 4 @@ -7133,7 +7139,6 @@ divr16u: { //SEG352 divr16u::@6 b6: //SEG353 [188] (word) rem16u#1 ← (word) divr16u::rem#11 - // (word) rem16u#1 = (word) divr16u::rem#11 // register copy zp ZP_WORD:2 jmp breturn //SEG354 divr16u::@return breturn: @@ -7141,6 +7146,7 @@ divr16u: { rts } //SEG356 bitmap_clear +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = 2 .label y = $16 @@ -7151,7 +7157,6 @@ bitmap_clear: { lda bitmap_plot_yhi sta _3+1 //SEG358 [191] (byte*~) bitmap_clear::bitmap#5 ← (byte*)(word~) bitmap_clear::$3 - // (byte*~) bitmap_clear::bitmap#5 = (byte*)(word~) bitmap_clear::$3 // register copy zp ZP_WORD:2 //SEG359 [192] phi from bitmap_clear to bitmap_clear::@1 [phi:bitmap_clear->bitmap_clear::@1] b1_from_bitmap_clear: //SEG360 [192] phi (byte) bitmap_clear::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:bitmap_clear->bitmap_clear::@1#0] -- vbuz1=vbuc1 @@ -7209,6 +7214,7 @@ bitmap_clear: { rts } //SEG382 bitmap_init +// Initialize bitmap plotting tables bitmap_init: { .label _3 = $16 .label yoffs = 2 @@ -7321,6 +7327,8 @@ bitmap_init: { jmp b2 } //SEG426 fill +// Simple routines for working with memory +// Fill some memory with a value fill: { .const size = $3e8 .label end = SCREEN+size @@ -7514,6 +7522,7 @@ Removing instruction b1_from_wrap_y: Removing instruction b1_from_b2: Removing instruction b4_from_b1: Removing instruction b4_from_b5: +Removing instruction b1_from_b3: Removing instruction b1_from_b5: Removing instruction b1_from_b3: Removing instruction b1_from_b6: @@ -7523,6 +7532,7 @@ Removing instruction b4_from_b2: Removing instruction b4_from_b7: Removing instruction b2_from_b1: Removing instruction b2_from_b5: +Removing instruction mulu16_sel_from_b9: Removing instruction b3_from_b15: Removing instruction b3_from_b6: Removing instruction breturn: @@ -7531,6 +7541,7 @@ Removing instruction b2_from_b1: Removing instruction b2_from_b4: Removing instruction b3_from_b2: Removing instruction b3_from_b5: +Removing instruction breturn: Removing instruction b1_from_b3: Removing instruction b2_from_b1: Removing instruction b2_from_b2: @@ -7568,7 +7579,6 @@ Removing instruction b6: Removing instruction breturn: Removing instruction div32u16u_from_sin16s_gen2: Removing instruction b3: -Removing instruction b1_from_b3: Removing instruction b4: Removing instruction b5: Removing instruction breturn: @@ -7586,7 +7596,6 @@ Removing instruction mulu16_sel_from_b2: Removing instruction b8: Removing instruction mulu16_sel_from_b8: Removing instruction b9: -Removing instruction mulu16_sel_from_b9: Removing instruction b10: Removing instruction mulu16_sel_from_b10: Removing instruction b11: @@ -7605,7 +7614,6 @@ Removing instruction b1_from_divr16u: Removing instruction b4: Removing instruction b5: Removing instruction b6: -Removing instruction breturn: Removing instruction b1_from_bitmap_clear: Removing instruction b3: Removing instruction breturn: @@ -8313,20 +8321,16 @@ render_sine: { stx sin_val sta sin_val+1 //SEG57 [30] (signed word) wrap_y::y#0 ← (signed word) render_sine::sin_val#0 - // (signed word) wrap_y::y#0 = (signed word) render_sine::sin_val#0 // register copy zp ZP_WORD:6 //SEG58 [31] call wrap_y //SEG59 [61] phi from render_sine::@1 to wrap_y [phi:render_sine::@1->wrap_y] //SEG60 [61] phi (signed word) wrap_y::y#9 = (signed word) wrap_y::y#0 [phi:render_sine::@1->wrap_y#0] -- register_copy jsr wrap_y //SEG61 [32] (byte) wrap_y::return#0 ← (byte) wrap_y::return#2 - // (byte) wrap_y::return#0 = (byte) wrap_y::return#2 // register copy reg byte a //SEG62 render_sine::@5 //SEG63 [33] (byte) render_sine::ypos#0 ← (byte) wrap_y::return#0 -- vbuxx=vbuaa tax //SEG64 [34] (word) bitmap_plot::x#0 ← (word) render_sine::xpos#3 - // (word) bitmap_plot::x#0 = (word) render_sine::xpos#3 // register copy zp ZP_WORD:4 //SEG65 [35] (byte) bitmap_plot::y#0 ← (byte) render_sine::ypos#0 - // (byte) bitmap_plot::y#0 = (byte) render_sine::ypos#0 // register copy reg byte x //SEG66 [36] call bitmap_plot //SEG67 [54] phi from render_sine::@5 to bitmap_plot [phi:render_sine::@5->bitmap_plot] //SEG68 [54] phi (word) bitmap_plot::x#2 = (word) bitmap_plot::x#0 [phi:render_sine::@5->bitmap_plot#0] -- register_copy @@ -8369,14 +8373,11 @@ render_sine: { //SEG77 [61] phi (signed word) wrap_y::y#9 = (signed word) wrap_y::y#1 [phi:render_sine::@6->wrap_y#0] -- register_copy jsr wrap_y //SEG78 [42] (byte) wrap_y::return#1 ← (byte) wrap_y::return#2 - // (byte) wrap_y::return#1 = (byte) wrap_y::return#2 // register copy reg byte a //SEG79 render_sine::@7 //SEG80 [43] (byte) render_sine::ypos2#0 ← (byte) wrap_y::return#1 -- vbuxx=vbuaa tax //SEG81 [44] (word) bitmap_plot::x#1 ← (word) render_sine::xpos#3 - // (word) bitmap_plot::x#1 = (word) render_sine::xpos#3 // register copy zp ZP_WORD:4 //SEG82 [45] (byte) bitmap_plot::y#1 ← (byte) render_sine::ypos2#0 - // (byte) bitmap_plot::y#1 = (byte) render_sine::ypos2#0 // register copy reg byte x //SEG83 [46] call bitmap_plot //SEG84 [54] phi from render_sine::@7 to bitmap_plot [phi:render_sine::@7->bitmap_plot] //SEG85 [54] phi (word) bitmap_plot::x#2 = (word) bitmap_plot::x#1 [phi:render_sine::@7->bitmap_plot#0] -- register_copy @@ -8429,6 +8430,7 @@ render_sine: { //SEG100 [49] phi (word) render_sine::xpos#8 = (word) render_sine::xpos#1 [phi:render_sine::@10->render_sine::@2#0] -- register_copy } //SEG101 bitmap_plot +// Plot a single dot in the bitmap bitmap_plot: { .label _1 = $10 .label plotter = 6 @@ -8519,6 +8521,9 @@ wrap_y: { jmp b1 } //SEG126 sin16s_gen2 +// Generate signed word sinus table - with values in the range min-max. +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen2: { .const min = -$140 .const max = $140 @@ -8535,10 +8540,8 @@ sin16s_gen2: { //SEG128 [162] phi from sin16s_gen2 to div32u16u [phi:sin16s_gen2->div32u16u] jsr div32u16u //SEG129 [72] (dword) div32u16u::return#2 ← (dword) div32u16u::return#0 - // (dword) div32u16u::return#2 = (dword) div32u16u::return#0 // register copy zp ZP_DWORD:27 //SEG130 sin16s_gen2::@3 //SEG131 [73] (dword) sin16s_gen2::step#0 ← (dword) div32u16u::return#2 - // (dword) sin16s_gen2::step#0 = (dword) div32u16u::return#2 // register copy zp ZP_DWORD:27 //SEG132 [74] phi from sin16s_gen2::@3 to sin16s_gen2::@1 [phi:sin16s_gen2::@3->sin16s_gen2::@1] //SEG133 [74] phi (word) sin16s_gen2::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin16s_gen2::@3->sin16s_gen2::@1#0] -- vwuz1=vbuc1 lda #<0 @@ -8573,17 +8576,13 @@ sin16s_gen2: { //SEG142 [76] call sin16s jsr sin16s //SEG143 [77] (signed word) sin16s::return#0 ← (signed word) sin16s::return#1 - // (signed word) sin16s::return#0 = (signed word) sin16s::return#1 // register copy zp ZP_WORD:23 //SEG144 sin16s_gen2::@4 //SEG145 [78] (signed word) mul16s::a#0 ← (signed word) sin16s::return#0 - // (signed word) mul16s::a#0 = (signed word) sin16s::return#0 // register copy zp ZP_WORD:23 //SEG146 [79] call mul16s jsr mul16s //SEG147 [80] (signed dword) mul16s::return#2 ← (signed dword) mul16s::return#0 - // (signed dword) mul16s::return#2 = (signed dword) mul16s::return#0 // register copy zp ZP_DWORD:12 //SEG148 sin16s_gen2::@5 //SEG149 [81] (signed dword~) sin16s_gen2::$5 ← (signed dword) mul16s::return#2 - // (signed dword~) sin16s_gen2::$5 = (signed dword) mul16s::return#2 // register copy zp ZP_DWORD:12 //SEG150 [82] (word~) sin16s_gen2::$6 ← > (signed dword~) sin16s_gen2::$5 -- vwuz1=_hi_vdsz2 lda _5+2 sta _6 @@ -8645,6 +8644,8 @@ sin16s_gen2: { rts } //SEG159 mul16s +// Multiply of two signed words to a signed double word +// Fixes offsets introduced by using unsigned multiplication mul16s: { .label _5 = 2 .label _6 = 6 @@ -8667,10 +8668,8 @@ mul16s: { sta mul16u.b+1 jsr mul16u //SEG165 [92] (dword) mul16u::return#2 ← (dword) mul16u::res#2 - // (dword) mul16u::return#2 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:12 //SEG166 mul16s::@6 //SEG167 [93] (dword) mul16s::m#0 ← (dword) mul16u::return#2 - // (dword) mul16s::m#0 = (dword) mul16u::return#2 // register copy zp ZP_DWORD:12 //SEG168 [94] if((signed word) mul16s::a#0>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mul16s::@1 -- vwsz1_ge_0_then_la1 lda a+1 bpl b2 @@ -8709,6 +8708,7 @@ mul16s: { rts } //SEG181 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label mb = $12 .label a = $10 @@ -8784,6 +8784,9 @@ mul16u: { jmp b1 } //SEG205 sin16s +// 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: { .label _6 = $c .label x = $c @@ -8912,7 +8915,6 @@ sin16s: { //SEG230 [153] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#0 [phi:sin16s::@2->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG231 [124] (word) mulu16_sel::return#0 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#0 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:6 //SEG232 sin16s::@8 //SEG233 [125] (word) sin16s::x2#0 ← (word) mulu16_sel::return#0 -- vwuz1=vwuz2 lda mulu16_sel.return @@ -8920,7 +8922,6 @@ sin16s: { lda mulu16_sel.return+1 sta x2+1 //SEG234 [126] (word) mulu16_sel::v1#1 ← (word) sin16s::x2#0 - // (word) mulu16_sel::v1#1 = (word) sin16s::x2#0 // register copy zp ZP_WORD:25 //SEG235 [127] (word) mulu16_sel::v2#1 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -8940,9 +8941,7 @@ sin16s: { sta mulu16_sel.return_1+1 //SEG242 sin16s::@9 //SEG243 [130] (word) sin16s::x3#0 ← (word) mulu16_sel::return#1 - // (word) sin16s::x3#0 = (word) mulu16_sel::return#1 // register copy zp ZP_WORD:25 //SEG244 [131] (word) mulu16_sel::v1#2 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#2 = (word) sin16s::x3#0 // register copy zp ZP_WORD:25 //SEG245 [132] call mulu16_sel //SEG246 [153] phi from sin16s::@9 to mulu16_sel [phi:sin16s::@9->mulu16_sel] //SEG247 [153] phi (byte) mulu16_sel::select#5 = (byte/signed byte/word/signed word/dword/signed dword) 1 [phi:sin16s::@9->mulu16_sel#0] -- vbuxx=vbuc1 @@ -8955,10 +8954,8 @@ sin16s: { //SEG249 [153] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#2 [phi:sin16s::@9->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG250 [133] (word) mulu16_sel::return#2 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#2 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:6 //SEG251 sin16s::@10 //SEG252 [134] (word) sin16s::x3_6#0 ← (word) mulu16_sel::return#2 - // (word) sin16s::x3_6#0 = (word) mulu16_sel::return#2 // register copy zp ZP_WORD:6 //SEG253 [135] (word) sin16s::usinx#0 ← (word) sin16s::x1#0 - (word) sin16s::x3_6#0 -- vwuz1=vwuz2_minus_vwuz3 lda x1 sec @@ -8968,7 +8965,6 @@ sin16s: { sbc x3_6+1 sta usinx+1 //SEG254 [136] (word) mulu16_sel::v1#3 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#3 = (word) sin16s::x3#0 // register copy zp ZP_WORD:25 //SEG255 [137] (word) mulu16_sel::v2#3 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -8988,9 +8984,7 @@ sin16s: { sta mulu16_sel.return_10+1 //SEG262 sin16s::@11 //SEG263 [140] (word) sin16s::x4#0 ← (word) mulu16_sel::return#10 - // (word) sin16s::x4#0 = (word) mulu16_sel::return#10 // register copy zp ZP_WORD:25 //SEG264 [141] (word) mulu16_sel::v1#4 ← (word) sin16s::x4#0 - // (word) mulu16_sel::v1#4 = (word) sin16s::x4#0 // register copy zp ZP_WORD:25 //SEG265 [142] (word) mulu16_sel::v2#4 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -9004,10 +8998,8 @@ sin16s: { //SEG270 [153] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#4 [phi:sin16s::@11->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG271 [144] (word) mulu16_sel::return#11 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#11 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:6 //SEG272 sin16s::@12 //SEG273 [145] (word) sin16s::x5#0 ← (word) mulu16_sel::return#11 - // (word) sin16s::x5#0 = (word) mulu16_sel::return#11 // register copy zp ZP_WORD:6 //SEG274 [146] (word) sin16s::x5_128#0 ← (word) sin16s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vwuz1=vwuz1_ror_4 ldy #4 !: @@ -9047,9 +9039,10 @@ sin16s: { rts //SEG284 sin16s::@15 //SEG285 [152] (signed word~) sin16s::return#5 ← (signed word)(word) sin16s::usinx#1 - // (signed word~) sin16s::return#5 = (signed word)(word) sin16s::usinx#1 // register copy zp ZP_WORD:23 } //SEG286 mulu16_sel +// 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: { .label _0 = $c .label _1 = $c @@ -9064,17 +9057,14 @@ mulu16_sel: { lda v1+1 sta mul16u.a+1 //SEG288 [155] (word) mul16u::b#1 ← (word) mulu16_sel::v2#5 - // (word) mul16u::b#1 = (word) mulu16_sel::v2#5 // register copy zp ZP_WORD:6 //SEG289 [156] call mul16u //SEG290 [102] phi from mulu16_sel to mul16u [phi:mulu16_sel->mul16u] //SEG291 [102] phi (word) mul16u::a#6 = (word) mul16u::a#2 [phi:mulu16_sel->mul16u#0] -- register_copy //SEG292 [102] phi (word) mul16u::b#2 = (word) mul16u::b#1 [phi:mulu16_sel->mul16u#1] -- register_copy jsr mul16u //SEG293 [157] (dword) mul16u::return#3 ← (dword) mul16u::res#2 - // (dword) mul16u::return#3 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:12 //SEG294 mulu16_sel::@2 //SEG295 [158] (dword~) mulu16_sel::$0 ← (dword) mul16u::return#3 - // (dword~) mulu16_sel::$0 = (dword) mul16u::return#3 // register copy zp ZP_DWORD:12 //SEG296 [159] (dword~) mulu16_sel::$1 ← (dword~) mulu16_sel::$0 << (byte) mulu16_sel::select#5 -- vduz1=vduz1_rol_vbuxx cpx #0 beq !e+ @@ -9096,6 +9086,8 @@ mulu16_sel: { rts } //SEG300 div32u16u +// 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_lo = 6 @@ -9113,7 +9105,6 @@ div32u16u: { sta divr16u.rem+1 jsr divr16u //SEG305 [164] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:6 //SEG306 div32u16u::@2 //SEG307 [165] (word) div32u16u::quotient_hi#0 ← (word) divr16u::return#2 -- vwuz1=vwuz2 lda divr16u.return @@ -9121,7 +9112,6 @@ div32u16u: { lda divr16u.return+1 sta quotient_hi+1 //SEG308 [166] (word) divr16u::rem#4 ← (word) rem16u#1 - // (word) divr16u::rem#4 = (word) rem16u#1 // register copy zp ZP_WORD:2 //SEG309 [167] call divr16u //SEG310 [172] phi from div32u16u::@2 to divr16u [phi:div32u16u::@2->divr16u] //SEG311 [172] phi (word) divr16u::dividend#5 = <(const dword) PI2_u4f28#0 [phi:div32u16u::@2->divr16u#0] -- vwuz1=vwuc1 @@ -9132,10 +9122,8 @@ div32u16u: { //SEG312 [172] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:div32u16u::@2->divr16u#1] -- register_copy jsr divr16u //SEG313 [168] (word) divr16u::return#3 ← (word) divr16u::return#0 - // (word) divr16u::return#3 = (word) divr16u::return#0 // register copy zp ZP_WORD:6 //SEG314 div32u16u::@3 //SEG315 [169] (word) div32u16u::quotient_lo#0 ← (word) divr16u::return#3 - // (word) div32u16u::quotient_lo#0 = (word) divr16u::return#3 // register copy zp ZP_WORD:6 //SEG316 [170] (dword) div32u16u::return#0 ← (word) div32u16u::quotient_hi#0 dw= (word) div32u16u::quotient_lo#0 -- vduz1=vwuz2_dword_vwuz3 lda quotient_hi sta return+2 @@ -9150,6 +9138,10 @@ div32u16u: { rts } //SEG319 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 4 @@ -9231,12 +9223,12 @@ divr16u: { bne b1 //SEG352 divr16u::@6 //SEG353 [188] (word) rem16u#1 ← (word) divr16u::rem#11 - // (word) rem16u#1 = (word) divr16u::rem#11 // register copy zp ZP_WORD:2 //SEG354 divr16u::@return //SEG355 [189] return rts } //SEG356 bitmap_clear +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = 2 .label y = $16 @@ -9247,7 +9239,6 @@ bitmap_clear: { lda bitmap_plot_yhi sta _3+1 //SEG358 [191] (byte*~) bitmap_clear::bitmap#5 ← (byte*)(word~) bitmap_clear::$3 - // (byte*~) bitmap_clear::bitmap#5 = (byte*)(word~) bitmap_clear::$3 // register copy zp ZP_WORD:2 //SEG359 [192] phi from bitmap_clear to bitmap_clear::@1 [phi:bitmap_clear->bitmap_clear::@1] //SEG360 [192] phi (byte) bitmap_clear::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:bitmap_clear->bitmap_clear::@1#0] -- vbuz1=vbuc1 lda #0 @@ -9293,6 +9284,7 @@ bitmap_clear: { rts } //SEG382 bitmap_init +// Initialize bitmap plotting tables bitmap_init: { .label _3 = $16 .label yoffs = 2 @@ -9383,6 +9375,8 @@ bitmap_init: { //SEG425 [206] phi (byte) bitmap_init::bits#4 = (byte) bitmap_init::bits#1 [phi:bitmap_init::@10->bitmap_init::@2#0] -- register_copy } //SEG426 fill +// Simple routines for working with memory +// Fill some memory with a value fill: { .const size = $3e8 .label end = SCREEN+size diff --git a/src/test/ref/examples/sinsprites/sinus-sprites.asm b/src/test/ref/examples/sinsprites/sinus-sprites.asm index c78f53fdb..5102b65be 100644 --- a/src/test/ref/examples/sinsprites/sinus-sprites.asm +++ b/src/test/ref/examples/sinsprites/sinus-sprites.asm @@ -185,6 +185,11 @@ clear_screen: { !: rts } +// Generate a sinus table using BASIC floats +// - sintab is a pointer to the table to fill +// - length is the length of the sine table +// - min is the minimum value of the generated sinus +// - max is the maximum value of the generated sinus gen_sintab: { .label f_2pi = $e2e5 .label _23 = $c @@ -288,6 +293,8 @@ gen_sintab: { f_min: .byte 0, 0, 0, 0, 0 f_amp: .byte 0, 0, 0, 0, 0 } +// Increase PETSCII progress one bit +// Done by increasing the character until the idx is 8 and then moving to the next char progress_inc: { inc progress_idx lda progress_idx @@ -310,6 +317,9 @@ progress_inc: { rts progress_chars: .byte $20, $65, $74, $75, $61, $f6, $e7, $ea, $e0 } +// word = FAC +// Get the value of the FAC (floating point accumulator) as an integer 16bit word +// Destroys the value in the FAC in the process getFAC: { .label return = $c jsr $b1aa @@ -321,6 +331,9 @@ getFAC: { sta return+1 rts } +// FAC = MEM+FAC +// Set FAC to MEM (float saved in memory) plus FAC (float accumulator) +// Reads 5 bytes from memory addMEMtoFAC: { lda #prepareMEM] @@ -4343,6 +4356,7 @@ addMEMtoFAC: { rts } //SEG289 prepareMEM +// Prepare MEM pointers for operations using MEM prepareMEM: { .label _0 = $3c .label _1 = $3d @@ -4366,6 +4380,9 @@ prepareMEM: { rts } //SEG296 mulFACbyMEM +// FAC = MEM*FAC +// Set FAC to MEM (float saved in memory) multiplied by FAC (float accumulator) +// Reads 5 bytes from memory mulFACbyMEM: { .label mem = $17 //SEG297 [143] (byte*) prepareMEM::mem#4 ← (byte*) mulFACbyMEM::mem#2 -- pbuz1=pbuz2 @@ -4392,6 +4409,9 @@ mulFACbyMEM: { rts } //SEG305 sinFAC +// FAC = sin(FAC) +// Set FAC to sinus of the FAC - sin(FAC) +// Sinus is calculated on radians (0-2*PI) sinFAC: { //SEG306 asm { jsr$e26b } jsr $e26b @@ -4402,6 +4422,9 @@ sinFAC: { rts } //SEG309 divMEMbyFAC +// FAC = MEM/FAC +// Set FAC to MEM (float saved in memory) divided by FAC (float accumulator) +// Reads 5 bytes from memory divMEMbyFAC: { .label mem = $19 //SEG310 [150] (byte*) prepareMEM::mem#3 ← (byte*) divMEMbyFAC::mem#2 -- pbuz1=pbuz2 @@ -4428,6 +4451,8 @@ divMEMbyFAC: { rts } //SEG318 setFAC +// FAC = word +// Set the FAC (floating point accumulator) to the integer value of a 16bit word setFAC: { .label w = $1b //SEG319 [155] (byte*~) prepareMEM::mem#8 ← (byte*)(word) setFAC::w#5 -- pbuz1=pbuz2 @@ -4454,6 +4479,9 @@ setFAC: { rts } //SEG327 setMEMtoFAC +// MEM = FAC +// Stores the value of the FAC to memory +// Stores 5 bytes (means it is necessary to allocate 5 bytes to avoid clobbering other data using eg. byte[] mem = {0, 0, 0, 0, 0};) setMEMtoFAC: { .label mem = $1d //SEG328 [160] (byte*) prepareMEM::mem#1 ← (byte*) setMEMtoFAC::mem#5 -- pbuz1=pbuz2 @@ -4480,6 +4508,8 @@ setMEMtoFAC: { rts } //SEG336 subFACfromARG +// FAC = ARG-FAC +// Set FAC to ARG minus FAC subFACfromARG: { //SEG337 asm { jsr$b853 } jsr $b853 @@ -4490,6 +4520,8 @@ subFACfromARG: { rts } //SEG340 setARGtoFAC +// ARG = FAC +// Set the ARG (floating point argument) to the value of the FAC (floating point accumulator) setARGtoFAC: { //SEG341 asm { jsr$bc0f } jsr $bc0f @@ -4500,6 +4532,7 @@ setARGtoFAC: { rts } //SEG344 progress_init +// Initialize the PETSCII progress bar progress_init: { .label line = $13 jmp breturn @@ -4566,6 +4599,9 @@ gen_sprites: { cml: .text "camelot" } //SEG364 gen_chargen_sprite +// Generate a sprite from a C64 CHARGEN character (by making each pixel 3x3 pixels large) +// - c is the character to generate +// - sprite is a pointer to the position of the sprite to generate gen_chargen_sprite: { .label _0 = $3f .label _1 = $41 @@ -5660,6 +5696,11 @@ clear_screen: { rts } //SEG150 gen_sintab +// Generate a sinus table using BASIC floats +// - sintab is a pointer to the table to fill +// - length is the length of the sine table +// - min is the minimum value of the generated sinus +// - max is the maximum value of the generated sinus gen_sintab: { .label f_2pi = $e2e5 .label _23 = $c @@ -5922,12 +5963,10 @@ gen_sintab: { //SEG248 [113] call getFAC jsr getFAC //SEG249 [114] (word) getFAC::return#2 ← (word) getFAC::return#0 - // (word) getFAC::return#2 = (word) getFAC::return#0 // register copy zp ZP_WORD:12 jmp b22 //SEG250 gen_sintab::@22 b22: //SEG251 [115] (word~) gen_sintab::$23 ← (word) getFAC::return#2 - // (word~) gen_sintab::$23 = (word) getFAC::return#2 // register copy zp ZP_WORD:12 //SEG252 [116] (byte~) gen_sintab::$24 ← ((byte)) (word~) gen_sintab::$23 -- vbuaa=_byte_vwuz1 lda _23 //SEG253 [117] *((byte*) gen_sintab::sintab#12 + (byte) gen_sintab::i#10) ← (byte~) gen_sintab::$24 -- pbuz1_derefidx_vbuz2=vbuaa @@ -5954,6 +5993,8 @@ gen_sintab: { f_amp: .byte 0, 0, 0, 0, 0 } //SEG260 progress_inc +// Increase PETSCII progress one bit +// Done by increasing the character until the idx is 8 and then moving to the next char progress_inc: { //SEG261 [122] (byte) progress_idx#10 ← ++ (byte) progress_idx#34 -- vbuz1=_inc_vbuz1 inc progress_idx @@ -6000,6 +6041,9 @@ progress_inc: { progress_chars: .byte $20, $65, $74, $75, $61, $f6, $e7, $ea, $e0 } //SEG276 getFAC +// word = FAC +// Get the value of the FAC (floating point accumulator) as an integer 16bit word +// Destroys the value in the FAC in the process getFAC: { .label return = $c //SEG277 asm { jsr$b1aa sty$fe sta$ff } @@ -6018,6 +6062,9 @@ getFAC: { rts } //SEG281 addMEMtoFAC +// FAC = MEM+FAC +// Set FAC to MEM (float saved in memory) plus FAC (float accumulator) +// Reads 5 bytes from memory addMEMtoFAC: { //SEG282 [133] call prepareMEM //SEG283 [136] phi from addMEMtoFAC to prepareMEM [phi:addMEMtoFAC->prepareMEM] @@ -6042,6 +6089,7 @@ addMEMtoFAC: { rts } //SEG289 prepareMEM +// Prepare MEM pointers for operations using MEM prepareMEM: { .label mem = $c //SEG290 [137] (byte~) prepareMEM::$0 ← < (byte*) prepareMEM::mem#5 -- vbuaa=_lo_pbuz1 @@ -6059,10 +6107,12 @@ prepareMEM: { rts } //SEG296 mulFACbyMEM +// FAC = MEM*FAC +// Set FAC to MEM (float saved in memory) multiplied by FAC (float accumulator) +// Reads 5 bytes from memory mulFACbyMEM: { .label mem = $c //SEG297 [143] (byte*) prepareMEM::mem#4 ← (byte*) mulFACbyMEM::mem#2 - // (byte*) prepareMEM::mem#4 = (byte*) mulFACbyMEM::mem#2 // register copy zp ZP_WORD:12 //SEG298 [144] call prepareMEM //SEG299 [136] phi from mulFACbyMEM to prepareMEM [phi:mulFACbyMEM->prepareMEM] prepareMEM_from_mulFACbyMEM: @@ -6082,6 +6132,9 @@ mulFACbyMEM: { rts } //SEG305 sinFAC +// FAC = sin(FAC) +// Set FAC to sinus of the FAC - sin(FAC) +// Sinus is calculated on radians (0-2*PI) sinFAC: { //SEG306 asm { jsr$e26b } jsr $e26b @@ -6092,10 +6145,12 @@ sinFAC: { rts } //SEG309 divMEMbyFAC +// FAC = MEM/FAC +// Set FAC to MEM (float saved in memory) divided by FAC (float accumulator) +// Reads 5 bytes from memory divMEMbyFAC: { .label mem = $c //SEG310 [150] (byte*) prepareMEM::mem#3 ← (byte*) divMEMbyFAC::mem#2 - // (byte*) prepareMEM::mem#3 = (byte*) divMEMbyFAC::mem#2 // register copy zp ZP_WORD:12 //SEG311 [151] call prepareMEM //SEG312 [136] phi from divMEMbyFAC to prepareMEM [phi:divMEMbyFAC->prepareMEM] prepareMEM_from_divMEMbyFAC: @@ -6115,10 +6170,11 @@ divMEMbyFAC: { rts } //SEG318 setFAC +// FAC = word +// Set the FAC (floating point accumulator) to the integer value of a 16bit word setFAC: { .label w = $c //SEG319 [155] (byte*~) prepareMEM::mem#8 ← (byte*)(word) setFAC::w#5 - // (byte*~) prepareMEM::mem#8 = (byte*)(word) setFAC::w#5 // register copy zp ZP_WORD:12 //SEG320 [156] call prepareMEM //SEG321 [136] phi from setFAC to prepareMEM [phi:setFAC->prepareMEM] prepareMEM_from_setFAC: @@ -6138,10 +6194,12 @@ setFAC: { rts } //SEG327 setMEMtoFAC +// MEM = FAC +// Stores the value of the FAC to memory +// Stores 5 bytes (means it is necessary to allocate 5 bytes to avoid clobbering other data using eg. byte[] mem = {0, 0, 0, 0, 0};) setMEMtoFAC: { .label mem = $c //SEG328 [160] (byte*) prepareMEM::mem#1 ← (byte*) setMEMtoFAC::mem#5 - // (byte*) prepareMEM::mem#1 = (byte*) setMEMtoFAC::mem#5 // register copy zp ZP_WORD:12 //SEG329 [161] call prepareMEM //SEG330 [136] phi from setMEMtoFAC to prepareMEM [phi:setMEMtoFAC->prepareMEM] prepareMEM_from_setMEMtoFAC: @@ -6161,6 +6219,8 @@ setMEMtoFAC: { rts } //SEG336 subFACfromARG +// FAC = ARG-FAC +// Set FAC to ARG minus FAC subFACfromARG: { //SEG337 asm { jsr$b853 } jsr $b853 @@ -6171,6 +6231,8 @@ subFACfromARG: { rts } //SEG340 setARGtoFAC +// ARG = FAC +// Set the ARG (floating point argument) to the value of the FAC (floating point accumulator) setARGtoFAC: { //SEG341 asm { jsr$bc0f } jsr $bc0f @@ -6181,6 +6243,7 @@ setARGtoFAC: { rts } //SEG344 progress_init +// Initialize the PETSCII progress bar progress_init: { .label line = $a jmp breturn @@ -6246,6 +6309,9 @@ gen_sprites: { cml: .text "camelot" } //SEG364 gen_chargen_sprite +// Generate a sprite from a C64 CHARGEN character (by making each pixel 3x3 pixels large) +// - c is the character to generate +// - sprite is a pointer to the position of the sprite to generate gen_chargen_sprite: { .label _0 = $c .label _1 = $c @@ -7600,6 +7666,11 @@ clear_screen: { rts } //SEG150 gen_sintab +// Generate a sinus table using BASIC floats +// - sintab is a pointer to the table to fill +// - length is the length of the sine table +// - min is the minimum value of the generated sinus +// - max is the maximum value of the generated sinus gen_sintab: { .label f_2pi = $e2e5 .label _23 = $c @@ -7789,10 +7860,8 @@ gen_sintab: { //SEG248 [113] call getFAC jsr getFAC //SEG249 [114] (word) getFAC::return#2 ← (word) getFAC::return#0 - // (word) getFAC::return#2 = (word) getFAC::return#0 // register copy zp ZP_WORD:12 //SEG250 gen_sintab::@22 //SEG251 [115] (word~) gen_sintab::$23 ← (word) getFAC::return#2 - // (word~) gen_sintab::$23 = (word) getFAC::return#2 // register copy zp ZP_WORD:12 //SEG252 [116] (byte~) gen_sintab::$24 ← ((byte)) (word~) gen_sintab::$23 -- vbuaa=_byte_vwuz1 lda _23 //SEG253 [117] *((byte*) gen_sintab::sintab#12 + (byte) gen_sintab::i#10) ← (byte~) gen_sintab::$24 -- pbuz1_derefidx_vbuz2=vbuaa @@ -7815,6 +7884,8 @@ gen_sintab: { f_amp: .byte 0, 0, 0, 0, 0 } //SEG260 progress_inc +// Increase PETSCII progress one bit +// Done by increasing the character until the idx is 8 and then moving to the next char progress_inc: { //SEG261 [122] (byte) progress_idx#10 ← ++ (byte) progress_idx#34 -- vbuz1=_inc_vbuz1 inc progress_idx @@ -7853,6 +7924,9 @@ progress_inc: { progress_chars: .byte $20, $65, $74, $75, $61, $f6, $e7, $ea, $e0 } //SEG276 getFAC +// word = FAC +// Get the value of the FAC (floating point accumulator) as an integer 16bit word +// Destroys the value in the FAC in the process getFAC: { .label return = $c //SEG277 asm { jsr$b1aa sty$fe sta$ff } @@ -7869,6 +7943,9 @@ getFAC: { rts } //SEG281 addMEMtoFAC +// FAC = MEM+FAC +// Set FAC to MEM (float saved in memory) plus FAC (float accumulator) +// Reads 5 bytes from memory addMEMtoFAC: { //SEG282 [133] call prepareMEM //SEG283 [136] phi from addMEMtoFAC to prepareMEM [phi:addMEMtoFAC->prepareMEM] @@ -7888,6 +7965,7 @@ addMEMtoFAC: { rts } //SEG289 prepareMEM +// Prepare MEM pointers for operations using MEM prepareMEM: { .label mem = $c //SEG290 [137] (byte~) prepareMEM::$0 ← < (byte*) prepareMEM::mem#5 -- vbuaa=_lo_pbuz1 @@ -7903,10 +7981,12 @@ prepareMEM: { rts } //SEG296 mulFACbyMEM +// FAC = MEM*FAC +// Set FAC to MEM (float saved in memory) multiplied by FAC (float accumulator) +// Reads 5 bytes from memory mulFACbyMEM: { .label mem = $c //SEG297 [143] (byte*) prepareMEM::mem#4 ← (byte*) mulFACbyMEM::mem#2 - // (byte*) prepareMEM::mem#4 = (byte*) mulFACbyMEM::mem#2 // register copy zp ZP_WORD:12 //SEG298 [144] call prepareMEM //SEG299 [136] phi from mulFACbyMEM to prepareMEM [phi:mulFACbyMEM->prepareMEM] //SEG300 [136] phi (byte*) prepareMEM::mem#5 = (byte*) prepareMEM::mem#4 [phi:mulFACbyMEM->prepareMEM#0] -- register_copy @@ -7921,6 +8001,9 @@ mulFACbyMEM: { rts } //SEG305 sinFAC +// FAC = sin(FAC) +// Set FAC to sinus of the FAC - sin(FAC) +// Sinus is calculated on radians (0-2*PI) sinFAC: { //SEG306 asm { jsr$e26b } jsr $e26b @@ -7929,10 +8012,12 @@ sinFAC: { rts } //SEG309 divMEMbyFAC +// FAC = MEM/FAC +// Set FAC to MEM (float saved in memory) divided by FAC (float accumulator) +// Reads 5 bytes from memory divMEMbyFAC: { .label mem = $c //SEG310 [150] (byte*) prepareMEM::mem#3 ← (byte*) divMEMbyFAC::mem#2 - // (byte*) prepareMEM::mem#3 = (byte*) divMEMbyFAC::mem#2 // register copy zp ZP_WORD:12 //SEG311 [151] call prepareMEM //SEG312 [136] phi from divMEMbyFAC to prepareMEM [phi:divMEMbyFAC->prepareMEM] //SEG313 [136] phi (byte*) prepareMEM::mem#5 = (byte*) prepareMEM::mem#3 [phi:divMEMbyFAC->prepareMEM#0] -- register_copy @@ -7947,10 +8032,11 @@ divMEMbyFAC: { rts } //SEG318 setFAC +// FAC = word +// Set the FAC (floating point accumulator) to the integer value of a 16bit word setFAC: { .label w = $c //SEG319 [155] (byte*~) prepareMEM::mem#8 ← (byte*)(word) setFAC::w#5 - // (byte*~) prepareMEM::mem#8 = (byte*)(word) setFAC::w#5 // register copy zp ZP_WORD:12 //SEG320 [156] call prepareMEM //SEG321 [136] phi from setFAC to prepareMEM [phi:setFAC->prepareMEM] //SEG322 [136] phi (byte*) prepareMEM::mem#5 = (byte*~) prepareMEM::mem#8 [phi:setFAC->prepareMEM#0] -- register_copy @@ -7965,10 +8051,12 @@ setFAC: { rts } //SEG327 setMEMtoFAC +// MEM = FAC +// Stores the value of the FAC to memory +// Stores 5 bytes (means it is necessary to allocate 5 bytes to avoid clobbering other data using eg. byte[] mem = {0, 0, 0, 0, 0};) setMEMtoFAC: { .label mem = $c //SEG328 [160] (byte*) prepareMEM::mem#1 ← (byte*) setMEMtoFAC::mem#5 - // (byte*) prepareMEM::mem#1 = (byte*) setMEMtoFAC::mem#5 // register copy zp ZP_WORD:12 //SEG329 [161] call prepareMEM //SEG330 [136] phi from setMEMtoFAC to prepareMEM [phi:setMEMtoFAC->prepareMEM] //SEG331 [136] phi (byte*) prepareMEM::mem#5 = (byte*) prepareMEM::mem#1 [phi:setMEMtoFAC->prepareMEM#0] -- register_copy @@ -7983,6 +8071,8 @@ setMEMtoFAC: { rts } //SEG336 subFACfromARG +// FAC = ARG-FAC +// Set FAC to ARG minus FAC subFACfromARG: { //SEG337 asm { jsr$b853 } jsr $b853 @@ -7991,6 +8081,8 @@ subFACfromARG: { rts } //SEG340 setARGtoFAC +// ARG = FAC +// Set the ARG (floating point argument) to the value of the FAC (floating point accumulator) setARGtoFAC: { //SEG341 asm { jsr$bc0f } jsr $bc0f @@ -7999,6 +8091,7 @@ setARGtoFAC: { rts } //SEG344 progress_init +// Initialize the PETSCII progress bar progress_init: { .label line = $a //SEG345 progress_init::@return @@ -8054,6 +8147,9 @@ gen_sprites: { cml: .text "camelot" } //SEG364 gen_chargen_sprite +// Generate a sprite from a C64 CHARGEN character (by making each pixel 3x3 pixels large) +// - c is the character to generate +// - sprite is a pointer to the position of the sprite to generate gen_chargen_sprite: { .label _0 = $c .label _1 = $c diff --git a/src/test/ref/fillscreen.log b/src/test/ref/fillscreen.log index 1de5c4890..21495c4c6 100644 --- a/src/test/ref/fillscreen.log +++ b/src/test/ref/fillscreen.log @@ -325,7 +325,6 @@ main: { //SEG9 [4] (byte) main::c#0 ← *((const byte*) SCREEN#0) -- vbuaa=_deref_pbuc1 lda SCREEN //SEG10 [5] (byte) fillscreen::c#0 ← (byte) main::c#0 - // (byte) fillscreen::c#0 = (byte) main::c#0 // register copy reg byte a //SEG11 [6] call fillscreen //SEG12 [8] phi from main to fillscreen [phi:main->fillscreen] fillscreen_from_main: @@ -449,7 +448,6 @@ main: { //SEG9 [4] (byte) main::c#0 ← *((const byte*) SCREEN#0) -- vbuaa=_deref_pbuc1 lda SCREEN //SEG10 [5] (byte) fillscreen::c#0 ← (byte) main::c#0 - // (byte) fillscreen::c#0 = (byte) main::c#0 // register copy reg byte a //SEG11 [6] call fillscreen //SEG12 [8] phi from main to fillscreen [phi:main->fillscreen] jsr fillscreen diff --git a/src/test/ref/flipper-rex2.asm b/src/test/ref/flipper-rex2.asm index ec80f26af..ddb5d3426 100644 --- a/src/test/ref/flipper-rex2.asm +++ b/src/test/ref/flipper-rex2.asm @@ -22,6 +22,7 @@ main: { jsr plot jmp b1 } +// Plot buffer on screen plot: { .label line = 2 .label y = 4 @@ -54,6 +55,7 @@ plot: { bne b1 rts } +// Flip buffer flip: { .label c = 5 .label r = 4 @@ -90,6 +92,7 @@ flip: { bne b3 rts } +// Prepare buffer prepare: { ldx #0 b1: diff --git a/src/test/ref/flipper-rex2.log b/src/test/ref/flipper-rex2.log index e9992245b..a6488b903 100644 --- a/src/test/ref/flipper-rex2.log +++ b/src/test/ref/flipper-rex2.log @@ -779,6 +779,7 @@ main: { jmp b3_from_b10 } //SEG32 plot +// Plot buffer on screen plot: { .label i = 6 .label x = 7 @@ -857,6 +858,7 @@ plot: { rts } //SEG59 flip +// Flip buffer flip: { .label srcIdx = 9 .label dstIdx = $a @@ -957,6 +959,7 @@ flip: { rts } //SEG97 prepare +// Prepare buffer prepare: { .label i = $d //SEG98 [43] phi from prepare to prepare::@1 [phi:prepare->prepare::@1] @@ -1135,6 +1138,7 @@ main: { jmp b3_from_b10 } //SEG32 plot +// Plot buffer on screen plot: { .label line = 2 .label y = 4 @@ -1206,6 +1210,7 @@ plot: { rts } //SEG59 flip +// Flip buffer flip: { .label c = 5 .label r = 4 @@ -1296,6 +1301,7 @@ flip: { rts } //SEG97 prepare +// Prepare buffer prepare: { //SEG98 [43] phi from prepare to prepare::@1 [phi:prepare->prepare::@1] b1_from_prepare: @@ -1551,6 +1557,7 @@ main: { jmp b1 } //SEG32 plot +// Plot buffer on screen plot: { .label line = 2 .label y = 4 @@ -1610,6 +1617,7 @@ plot: { rts } //SEG59 flip +// Flip buffer flip: { .label c = 5 .label r = 4 @@ -1684,6 +1692,7 @@ flip: { rts } //SEG97 prepare +// Prepare buffer prepare: { //SEG98 [43] phi from prepare to prepare::@1 [phi:prepare->prepare::@1] //SEG99 [43] phi (byte) prepare::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:prepare->prepare::@1#0] -- vbuxx=vbuc1 diff --git a/src/test/ref/forrangesymbolic.asm b/src/test/ref/forrangesymbolic.asm index 455eee70e..c004ba5b4 100644 --- a/src/test/ref/forrangesymbolic.asm +++ b/src/test/ref/forrangesymbolic.asm @@ -1,6 +1,8 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Range-based for does not recognize symbolic constants. +// The following should work but gives a not-constant exception main: { .label BITMAP = $2000 .label b = 2 diff --git a/src/test/ref/forrangesymbolic.log b/src/test/ref/forrangesymbolic.log index 7ae569ba1..61e5dd8d4 100644 --- a/src/test/ref/forrangesymbolic.log +++ b/src/test/ref/forrangesymbolic.log @@ -133,6 +133,8 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Range-based for does not recognize symbolic constants. +// The following should work but gives a not-constant exception main: { .label BITMAP = $2000 .label b = 2 @@ -210,6 +212,8 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Range-based for does not recognize symbolic constants. +// The following should work but gives a not-constant exception main: { .label BITMAP = $2000 .label b = 2 @@ -309,6 +313,8 @@ Score: 511 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Range-based for does not recognize symbolic constants. +// The following should work but gives a not-constant exception main: { .label BITMAP = $2000 .label b = 2 diff --git a/src/test/ref/fragment-synth.asm b/src/test/ref/fragment-synth.asm index fcd4c7d41..768697920 100644 --- a/src/test/ref/fragment-synth.asm +++ b/src/test/ref/fragment-synth.asm @@ -1,6 +1,8 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Tests a sub-optimal fragment synthesis +// vbuaa=vbuxx_band_pbuz1_derefidx_vbuc1 < vbuaa=pbuz1_derefidx_vbuc1_band_vbuxx < vbuaa=pbuz1_derefidx_vbuaa_band_vbuxx < vbuaa=pbuz1_derefidx_vbuyy_band_vbuxx < vbuaa=pbuz1_derefidx_vbuyy_band_vbuaa < vbuaa=vbuaa_band_pbuz1_derefidx_vbuyy - clobber:A Y cycles:11.5 main: { .label screen = $400 lda #$f0 diff --git a/src/test/ref/fragment-synth.log b/src/test/ref/fragment-synth.log index 3e37dc55d..091370e87 100644 --- a/src/test/ref/fragment-synth.log +++ b/src/test/ref/fragment-synth.log @@ -265,6 +265,8 @@ bend_from_b2: //SEG7 @end bend: //SEG8 main +// Tests a sub-optimal fragment synthesis +// vbuaa=vbuxx_band_pbuz1_derefidx_vbuc1 < vbuaa=pbuz1_derefidx_vbuc1_band_vbuxx < vbuaa=pbuz1_derefidx_vbuaa_band_vbuxx < vbuaa=pbuz1_derefidx_vbuyy_band_vbuxx < vbuaa=pbuz1_derefidx_vbuyy_band_vbuaa < vbuaa=vbuaa_band_pbuz1_derefidx_vbuyy - clobber:A Y cycles:11.5 main: { .label screen = $400 .label a1 = 5 @@ -387,6 +389,8 @@ bend_from_b2: //SEG7 @end bend: //SEG8 main +// Tests a sub-optimal fragment synthesis +// vbuaa=vbuxx_band_pbuz1_derefidx_vbuc1 < vbuaa=pbuz1_derefidx_vbuc1_band_vbuxx < vbuaa=pbuz1_derefidx_vbuaa_band_vbuxx < vbuaa=pbuz1_derefidx_vbuyy_band_vbuxx < vbuaa=pbuz1_derefidx_vbuyy_band_vbuaa < vbuaa=vbuaa_band_pbuz1_derefidx_vbuyy - clobber:A Y cycles:11.5 main: { .label screen = $400 //SEG9 [4] *(((byte*))(word/signed word/dword/signed dword) 1104+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte/word/signed word/dword/signed dword) 240 -- _deref_pbuc1=vbuc2 @@ -407,12 +411,10 @@ main: { ldx #$aa jsr fct //SEG15 [7] (byte) fct::return#0 ← (byte) fct::return#2 - // (byte) fct::return#0 = (byte) fct::return#2 // register copy reg byte a jmp b1 //SEG16 main::@1 b1: //SEG17 [8] (byte) main::a1#0 ← (byte) fct::return#0 - // (byte) main::a1#0 = (byte) fct::return#0 // register copy reg byte a //SEG18 [9] *((const byte*) main::screen#0) ← (byte) main::a1#0 -- _deref_pbuc1=vbuaa sta screen //SEG19 [10] call fct @@ -427,12 +429,10 @@ main: { ldx #$55 jsr fct //SEG23 [11] (byte) fct::return#1 ← (byte) fct::return#2 - // (byte) fct::return#1 = (byte) fct::return#2 // register copy reg byte a jmp b2 //SEG24 main::@2 b2: //SEG25 [12] (byte) main::a2#0 ← (byte) fct::return#1 - // (byte) main::a2#0 = (byte) fct::return#1 // register copy reg byte a //SEG26 [13] *((const byte*) main::screen#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) main::a2#0 -- _deref_pbuc1=vbuaa sta screen+1 jmp breturn @@ -533,6 +533,8 @@ Score: 77 //SEG6 [3] phi from @2 to @end [phi:@2->@end] //SEG7 @end //SEG8 main +// Tests a sub-optimal fragment synthesis +// vbuaa=vbuxx_band_pbuz1_derefidx_vbuc1 < vbuaa=pbuz1_derefidx_vbuc1_band_vbuxx < vbuaa=pbuz1_derefidx_vbuaa_band_vbuxx < vbuaa=pbuz1_derefidx_vbuyy_band_vbuxx < vbuaa=pbuz1_derefidx_vbuyy_band_vbuaa < vbuaa=vbuaa_band_pbuz1_derefidx_vbuyy - clobber:A Y cycles:11.5 main: { .label screen = $400 //SEG9 [4] *(((byte*))(word/signed word/dword/signed dword) 1104+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte/word/signed word/dword/signed dword) 240 -- _deref_pbuc1=vbuc2 @@ -552,10 +554,8 @@ main: { ldx #$aa jsr fct //SEG15 [7] (byte) fct::return#0 ← (byte) fct::return#2 - // (byte) fct::return#0 = (byte) fct::return#2 // register copy reg byte a //SEG16 main::@1 //SEG17 [8] (byte) main::a1#0 ← (byte) fct::return#0 - // (byte) main::a1#0 = (byte) fct::return#0 // register copy reg byte a //SEG18 [9] *((const byte*) main::screen#0) ← (byte) main::a1#0 -- _deref_pbuc1=vbuaa sta screen //SEG19 [10] call fct @@ -569,10 +569,8 @@ main: { ldx #$55 jsr fct //SEG23 [11] (byte) fct::return#1 ← (byte) fct::return#2 - // (byte) fct::return#1 = (byte) fct::return#2 // register copy reg byte a //SEG24 main::@2 //SEG25 [12] (byte) main::a2#0 ← (byte) fct::return#1 - // (byte) main::a2#0 = (byte) fct::return#1 // register copy reg byte a //SEG26 [13] *((const byte*) main::screen#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) main::a2#0 -- _deref_pbuc1=vbuaa sta screen+1 //SEG27 main::@return diff --git a/src/test/ref/immzero.asm b/src/test/ref/immzero.asm index 7f0ec6def..724fbe946 100644 --- a/src/test/ref/immzero.asm +++ b/src/test/ref/immzero.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Tests that immediate zero values are reused - even when assigning to words main: { .label w = 2 lda #<0 diff --git a/src/test/ref/immzero.log b/src/test/ref/immzero.log index 1d5fb1157..22212aebb 100644 --- a/src/test/ref/immzero.log +++ b/src/test/ref/immzero.log @@ -156,6 +156,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Tests that immediate zero values are reused - even when assigning to words main: { .label i = 2 .label w = 3 @@ -237,6 +238,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Tests that immediate zero values are reused - even when assigning to words main: { .label w = 2 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] @@ -339,6 +341,7 @@ Score: 351 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Tests that immediate zero values are reused - even when assigning to words main: { .label w = 2 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] diff --git a/src/test/ref/incrementinarray.asm b/src/test/ref/incrementinarray.asm index ac816936d..fd10ce721 100644 --- a/src/test/ref/incrementinarray.asm +++ b/src/test/ref/incrementinarray.asm @@ -32,6 +32,7 @@ main: { sta print_char_cursor+1 jmp b1 } +// Print a newline print_ln: { b1: lda print_line_cursor @@ -51,6 +52,7 @@ print_ln: { !: rts } +// Print a zero-terminated string print_str: { .label str = 4 lda #print_ln::@1] b1_from_print_ln: @@ -624,6 +625,7 @@ print_ln: { rts } //SEG43 print_str +// Print a zero-terminated string print_str: { .label str = 5 //SEG44 [21] phi from print_str to print_str::@1 [phi:print_str->print_str::@1] @@ -671,6 +673,7 @@ print_str: { jmp b1 } //SEG58 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 9 //SEG59 [28] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -846,6 +849,7 @@ main: { jmp b1 } //SEG35 print_ln +// Print a newline print_ln: { //SEG36 [16] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -878,6 +882,7 @@ print_ln: { rts } //SEG43 print_str +// Print a zero-terminated string print_str: { .label str = 4 //SEG44 [21] phi from print_str to print_str::@1 [phi:print_str->print_str::@1] @@ -925,6 +930,7 @@ print_str: { jmp b1 } //SEG58 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG59 [28] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -1140,6 +1146,7 @@ main: { jmp b1 } //SEG35 print_ln +// Print a newline print_ln: { //SEG36 [16] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] //SEG37 [16] phi (byte*) print_line_cursor#9 = (byte*) print_line_cursor#19 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy @@ -1167,6 +1174,7 @@ print_ln: { rts } //SEG43 print_str +// Print a zero-terminated string print_str: { .label str = 4 //SEG44 [21] phi from print_str to print_str::@1 [phi:print_str->print_str::@1] @@ -1208,6 +1216,7 @@ print_str: { jmp b1 } //SEG58 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG59 [28] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] diff --git a/src/test/ref/inline-function-level2.asm b/src/test/ref/inline-function-level2.asm index c3723057f..7a98fb90e 100644 --- a/src/test/ref/inline-function-level2.asm +++ b/src/test/ref/inline-function-level2.asm @@ -2,6 +2,7 @@ :BasicUpstart(main) .pc = $80d "Program" .label cur_line = 4 +// Inline functions in two levels main: { .const line1_xpos = 2 .const line1_xadd = $40 diff --git a/src/test/ref/inline-function-level2.log b/src/test/ref/inline-function-level2.log index f08543f5b..6e0e6d456 100644 --- a/src/test/ref/inline-function-level2.log +++ b/src/test/ref/inline-function-level2.log @@ -567,6 +567,7 @@ bend_from_b3: //SEG8 @end bend: //SEG9 main +// Inline functions in two levels main: { .const line1_xpos = 2 .const line1_xadd = $40 @@ -846,6 +847,7 @@ bend_from_b3: //SEG8 @end bend: //SEG9 main +// Inline functions in two levels main: { .const line1_xpos = 2 .const line1_xadd = $40 @@ -1177,6 +1179,7 @@ Score: 2366 //SEG7 [3] phi from @3 to @end [phi:@3->@end] //SEG8 @end //SEG9 main +// Inline functions in two levels main: { .const line1_xpos = 2 .const line1_xadd = $40 diff --git a/src/test/ref/inline-string-2.asm b/src/test/ref/inline-string-2.asm index 41aaef5df..7dd17e62b 100644 --- a/src/test/ref/inline-string-2.asm +++ b/src/test/ref/inline-string-2.asm @@ -2,6 +2,7 @@ :BasicUpstart(main) .pc = $80d "Program" .label screen = 2 +// Inline Strings in assignments main: { lda #<$400 sta screen diff --git a/src/test/ref/inline-string-2.log b/src/test/ref/inline-string-2.log index 0cbeb7475..3ce1a889b 100644 --- a/src/test/ref/inline-string-2.log +++ b/src/test/ref/inline-string-2.log @@ -336,6 +336,7 @@ bend_from_b3: //SEG8 @end bend: //SEG9 main +// Inline Strings in assignments main: { //SEG10 [5] call print_msg //SEG11 [9] phi from main to print_msg [phi:main->print_msg] @@ -504,6 +505,7 @@ bend_from_b3: //SEG8 @end bend: //SEG9 main +// Inline Strings in assignments main: { //SEG10 [5] call print_msg //SEG11 [9] phi from main to print_msg [phi:main->print_msg] @@ -564,7 +566,6 @@ print_msg: { //SEG30 print_msg::@2 b2: //SEG31 [13] (byte*) print::msg#0 ← (byte*) print_msg::msg#2 - // (byte*) print::msg#0 = (byte*) print_msg::msg#2 // register copy zp ZP_WORD:4 //SEG32 [14] call print //SEG33 [16] phi from print_msg::@2 to print [phi:print_msg::@2->print] print_from_b2: @@ -640,6 +641,7 @@ Removing instruction b1_from_main: Removing instruction print_msg_from_b1: Removing instruction b3_from_print_msg: Removing instruction b2_from_b3: +Removing instruction print_from_b2: Removing instruction b1_from_print: Removing instruction b1_from_b2: Succesful ASM optimization Pass5RedundantLabelElimination @@ -648,7 +650,6 @@ Removing instruction print_msg_from_main: Removing instruction b1: Removing instruction breturn: Removing instruction b3: -Removing instruction print_from_b2: Removing instruction breturn: Removing instruction breturn: Succesful ASM optimization Pass5UnusedLabelElimination @@ -712,6 +713,7 @@ Score: 612 //SEG7 [3] phi from @3 to @end [phi:@3->@end] //SEG8 @end //SEG9 main +// Inline Strings in assignments main: { //SEG10 [5] call print_msg //SEG11 [9] phi from main to print_msg [phi:main->print_msg] @@ -760,7 +762,6 @@ print_msg: { //SEG30 print_msg::@2 b2: //SEG31 [13] (byte*) print::msg#0 ← (byte*) print_msg::msg#2 - // (byte*) print::msg#0 = (byte*) print_msg::msg#2 // register copy zp ZP_WORD:4 //SEG32 [14] call print //SEG33 [16] phi from print_msg::@2 to print [phi:print_msg::@2->print] jsr print diff --git a/src/test/ref/inline-string-3.asm b/src/test/ref/inline-string-3.asm index 6bb2846f0..b81e58f25 100644 --- a/src/test/ref/inline-string-3.asm +++ b/src/test/ref/inline-string-3.asm @@ -1,6 +1,9 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Test assigning address of inline string to pointer +// The result should be an labelled .text in the ASM +// Erroneously tries to inline the string completely leading to a CompileError main: { .label PTR = $9ffe .label SCREEN = $400 diff --git a/src/test/ref/inline-string-3.log b/src/test/ref/inline-string-3.log index d840191cc..5934be250 100644 --- a/src/test/ref/inline-string-3.log +++ b/src/test/ref/inline-string-3.log @@ -139,6 +139,9 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Test assigning address of inline string to pointer +// The result should be an labelled .text in the ASM +// Erroneously tries to inline the string completely leading to a CompileError main: { .label PTR = $9ffe .label SCREEN = $400 @@ -201,6 +204,9 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Test assigning address of inline string to pointer +// The result should be an labelled .text in the ASM +// Erroneously tries to inline the string completely leading to a CompileError main: { .label PTR = $9ffe .label SCREEN = $400 @@ -279,6 +285,9 @@ Score: 43 //SEG6 [3] phi from @1 to @end [phi:@1->@end] //SEG7 @end //SEG8 main +// Test assigning address of inline string to pointer +// The result should be an labelled .text in the ASM +// Erroneously tries to inline the string completely leading to a CompileError main: { .label PTR = $9ffe .label SCREEN = $400 diff --git a/src/test/ref/irq-hardware-clobber-jsr.asm b/src/test/ref/irq-hardware-clobber-jsr.asm index 5e7f0598e..981b58179 100644 --- a/src/test/ref/irq-hardware-clobber-jsr.asm +++ b/src/test/ref/irq-hardware-clobber-jsr.asm @@ -41,6 +41,7 @@ main: { inc BORDERCOL jmp b2 } +// Interrupt Routine irq: { sta rega+1 jsr do_irq diff --git a/src/test/ref/irq-hardware-clobber-jsr.log b/src/test/ref/irq-hardware-clobber-jsr.log index 19cb058b5..ea063b0a5 100644 --- a/src/test/ref/irq-hardware-clobber-jsr.log +++ b/src/test/ref/irq-hardware-clobber-jsr.log @@ -611,6 +611,7 @@ main: { jmp b2 } //SEG20 irq +// Interrupt Routine irq: { //SEG21 entry interrupt(HARDWARE_CLOBBER) sta rega+1 @@ -753,6 +754,7 @@ main: { jmp b2 } //SEG20 irq +// Interrupt Routine irq: { //SEG21 entry interrupt(HARDWARE_CLOBBER) sta rega+1 @@ -980,6 +982,7 @@ main: { jmp b2 } //SEG20 irq +// Interrupt Routine irq: { //SEG21 entry interrupt(HARDWARE_CLOBBER) sta rega+1 diff --git a/src/test/ref/irq-hardware-clobber.asm b/src/test/ref/irq-hardware-clobber.asm index cacbcfd89..9f7e4e1c1 100644 --- a/src/test/ref/irq-hardware-clobber.asm +++ b/src/test/ref/irq-hardware-clobber.asm @@ -17,6 +17,7 @@ .const PROCPORT_DDR_MEMORY_MASK = 7 .label PROCPORT = 1 .const PROCPORT_RAM_IO = $35 +// RAM in $A000, $E000 CHAR ROM in $D000 main: { sei lda #PROCPORT_DDR_MEMORY_MASK @@ -41,6 +42,7 @@ main: { inc FGCOL jmp b2 } +// Interrupt Routine irq: { sta rega+1 lda #WHITE diff --git a/src/test/ref/irq-hardware-clobber.log b/src/test/ref/irq-hardware-clobber.log index bf0dd951a..21074b25f 100644 --- a/src/test/ref/irq-hardware-clobber.log +++ b/src/test/ref/irq-hardware-clobber.log @@ -255,6 +255,7 @@ bend_from_b2: //SEG7 @end bend: //SEG8 main +// RAM in $A000, $E000 CHAR ROM in $D000 main: { //SEG9 asm { sei } sei @@ -292,6 +293,7 @@ main: { jmp b2 } //SEG20 irq +// Interrupt Routine irq: { //SEG21 entry interrupt(HARDWARE_CLOBBER) sta rega+1 @@ -385,6 +387,7 @@ bend_from_b2: //SEG7 @end bend: //SEG8 main +// RAM in $A000, $E000 CHAR ROM in $D000 main: { //SEG9 asm { sei } sei @@ -422,6 +425,7 @@ main: { jmp b2 } //SEG20 irq +// Interrupt Routine irq: { //SEG21 entry interrupt(HARDWARE_CLOBBER) sta rega+1 @@ -540,6 +544,7 @@ Score: 212 //SEG6 [3] phi from @2 to @end [phi:@2->@end] //SEG7 @end //SEG8 main +// RAM in $A000, $E000 CHAR ROM in $D000 main: { //SEG9 asm { sei } sei @@ -576,6 +581,7 @@ main: { jmp b2 } //SEG20 irq +// Interrupt Routine irq: { //SEG21 entry interrupt(HARDWARE_CLOBBER) sta rega+1 diff --git a/src/test/ref/irq-hardware.asm b/src/test/ref/irq-hardware.asm index df86f05ff..cf5395fe6 100644 --- a/src/test/ref/irq-hardware.asm +++ b/src/test/ref/irq-hardware.asm @@ -17,6 +17,7 @@ .const PROCPORT_DDR_MEMORY_MASK = 7 .label PROCPORT = 1 .const PROCPORT_RAM_IO = $35 +// RAM in $A000, $E000 CHAR ROM in $D000 main: { sei lda #PROCPORT_DDR_MEMORY_MASK @@ -41,6 +42,7 @@ main: { inc FGCOL jmp b2 } +// Interrupt Routine irq: { sta rega+1 stx regx+1 diff --git a/src/test/ref/irq-hardware.log b/src/test/ref/irq-hardware.log index 753a8f677..00dcb5d19 100644 --- a/src/test/ref/irq-hardware.log +++ b/src/test/ref/irq-hardware.log @@ -255,6 +255,7 @@ bend_from_b2: //SEG7 @end bend: //SEG8 main +// RAM in $A000, $E000 CHAR ROM in $D000 main: { //SEG9 asm { sei } sei @@ -292,6 +293,7 @@ main: { jmp b2 } //SEG20 irq +// Interrupt Routine irq: { //SEG21 entry interrupt(HARDWARE_ALL) sta rega+1 @@ -378,6 +380,7 @@ bend_from_b2: //SEG7 @end bend: //SEG8 main +// RAM in $A000, $E000 CHAR ROM in $D000 main: { //SEG9 asm { sei } sei @@ -415,6 +418,7 @@ main: { jmp b2 } //SEG20 irq +// Interrupt Routine irq: { //SEG21 entry interrupt(HARDWARE_ALL) sta rega+1 @@ -539,6 +543,7 @@ Score: 296 //SEG6 [3] phi from @2 to @end [phi:@2->@end] //SEG7 @end //SEG8 main +// RAM in $A000, $E000 CHAR ROM in $D000 main: { //SEG9 asm { sei } sei @@ -575,6 +580,7 @@ main: { jmp b2 } //SEG20 irq +// Interrupt Routine irq: { //SEG21 entry interrupt(HARDWARE_ALL) sta rega+1 diff --git a/src/test/ref/irq-kernel-minimal.asm b/src/test/ref/irq-kernel-minimal.asm new file mode 100644 index 000000000..6cc3ce2f7 --- /dev/null +++ b/src/test/ref/irq-kernel-minimal.asm @@ -0,0 +1,25 @@ +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label BGCOL = $d021 + .label KERNEL_IRQ = $314 + .const BLACK = 0 + .const WHITE = 1 +// Setup the IRQ routine +main: { + sei + lda #irq + sta KERNEL_IRQ+1 + cli + rts +} +// The Interrupt Handler +irq: { + lda #WHITE + sta BGCOL + lda #BLACK + sta BGCOL + jmp $ea31 +} diff --git a/src/test/ref/irq-kernel-minimal.cfg b/src/test/ref/irq-kernel-minimal.cfg new file mode 100644 index 000000000..08ea82c63 --- /dev/null +++ b/src/test/ref/irq-kernel-minimal.cfg @@ -0,0 +1,24 @@ +@begin: scope:[] from + [0] phi() + to:@6 +@6: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @6 + [3] phi() +main: scope:[main] from @6 + asm { sei } + [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq() + asm { cli } + to:main::@return +main::@return: scope:[main] from main + [7] return + to:@return +irq: scope:[irq] from + [8] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 + [9] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 + to:irq::@return +irq::@return: scope:[irq] from irq + [10] return + to:@return diff --git a/src/test/ref/irq-kernel-minimal.log b/src/test/ref/irq-kernel-minimal.log new file mode 100644 index 000000000..712dbef72 --- /dev/null +++ b/src/test/ref/irq-kernel-minimal.log @@ -0,0 +1,783 @@ +Resolved forward reference irq to interrupt(KERNEL_KEYBOARD)(void()) irq() +Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (byte*) PROCPORT_DDR#0 ← ((byte*)) (byte/signed byte/word/signed word/dword/signed dword) 0 + (byte) PROCPORT_DDR_MEMORY_MASK#0 ← (byte/signed byte/word/signed word/dword/signed dword) 7 + (byte*) PROCPORT#0 ← ((byte*)) (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) PROCPORT_RAM_ALL#0 ← (byte/signed byte/word/signed word/dword/signed dword) 48 + (byte) PROCPORT_RAM_IO#0 ← (byte/signed byte/word/signed word/dword/signed dword) 53 + (byte) PROCPORT_RAM_CHARROM#0 ← (byte/signed byte/word/signed word/dword/signed dword) 49 + (byte) PROCPORT_KERNEL_IO#0 ← (byte/signed byte/word/signed word/dword/signed dword) 54 + (byte) PROCPORT_BASIC_KERNEL_IO#0 ← (byte/signed byte/word/signed word/dword/signed dword) 55 + (byte*) CHARGEN#0 ← ((byte*)) (word/dword/signed dword) 53248 + (word) SPRITE_PTRS#0 ← (word/signed word/dword/signed dword) 1016 + (byte*) SPRITES_XPOS#0 ← ((byte*)) (word/dword/signed dword) 53248 + (byte*) SPRITES_YPOS#0 ← ((byte*)) (word/dword/signed dword) 53249 + (byte*) SPRITES_XMSB#0 ← ((byte*)) (word/dword/signed dword) 53264 + (byte*) RASTER#0 ← ((byte*)) (word/dword/signed dword) 53266 + (byte*) SPRITES_ENABLE#0 ← ((byte*)) (word/dword/signed dword) 53269 + (byte*) SPRITES_EXPAND_Y#0 ← ((byte*)) (word/dword/signed dword) 53271 + (byte*) SPRITES_PRIORITY#0 ← ((byte*)) (word/dword/signed dword) 53275 + (byte*) SPRITES_MC#0 ← ((byte*)) (word/dword/signed dword) 53276 + (byte*) SPRITES_EXPAND_X#0 ← ((byte*)) (word/dword/signed dword) 53277 + (byte*) BORDERCOL#0 ← ((byte*)) (word/dword/signed dword) 53280 + (byte*) BGCOL#0 ← ((byte*)) (word/dword/signed dword) 53281 + (byte*) BGCOL1#0 ← ((byte*)) (word/dword/signed dword) 53281 + (byte*) BGCOL2#0 ← ((byte*)) (word/dword/signed dword) 53282 + (byte*) BGCOL3#0 ← ((byte*)) (word/dword/signed dword) 53283 + (byte*) BGCOL4#0 ← ((byte*)) (word/dword/signed dword) 53284 + (byte*) SPRITES_MC1#0 ← ((byte*)) (word/dword/signed dword) 53285 + (byte*) SPRITES_MC2#0 ← ((byte*)) (word/dword/signed dword) 53286 + (byte*) SPRITES_COLS#0 ← ((byte*)) (word/dword/signed dword) 53287 + (byte*) VIC_CONTROL#0 ← ((byte*)) (word/dword/signed dword) 53265 + (byte*) D011#0 ← ((byte*)) (word/dword/signed dword) 53265 + (byte) VIC_RST8#0 ← (byte/word/signed word/dword/signed dword) 128 + (byte) VIC_ECM#0 ← (byte/signed byte/word/signed word/dword/signed dword) 64 + (byte) VIC_BMM#0 ← (byte/signed byte/word/signed word/dword/signed dword) 32 + (byte) VIC_DEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 16 + (byte) VIC_RSEL#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 + (byte*) VIC_CONTROL2#0 ← ((byte*)) (word/dword/signed dword) 53270 + (byte*) D016#0 ← ((byte*)) (word/dword/signed dword) 53270 + (byte) VIC_MCM#0 ← (byte/signed byte/word/signed word/dword/signed dword) 16 + (byte) VIC_CSEL#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 + (byte*) D018#0 ← ((byte*)) (word/dword/signed dword) 53272 + (byte*) VIC_MEMORY#0 ← ((byte*)) (word/dword/signed dword) 53272 + (byte*) LIGHTPEN_X#0 ← ((byte*)) (word/dword/signed dword) 53267 + (byte*) LIGHTPEN_Y#0 ← ((byte*)) (word/dword/signed dword) 53268 + (byte*) IRQ_STATUS#0 ← ((byte*)) (word/dword/signed dword) 53273 + (byte*) IRQ_ENABLE#0 ← ((byte*)) (word/dword/signed dword) 53274 + (byte) IRQ_RASTER#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) IRQ_COLLISION_BG#0 ← (byte/signed byte/word/signed word/dword/signed dword) 2 + (byte) IRQ_COLLISION_SPRITE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 4 + (byte) IRQ_LIGHTPEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 + (byte*) COLS#0 ← ((byte*)) (word/dword/signed dword) 55296 + (byte*) CIA1_PORT_A#0 ← ((byte*)) (word/dword/signed dword) 56320 + (byte*) CIA1_PORT_B#0 ← ((byte*)) (word/dword/signed dword) 56321 + (byte*) CIA1_PORT_A_DDR#0 ← ((byte*)) (word/dword/signed dword) 56322 + (byte*) CIA1_PORT_B_DDR#0 ← ((byte*)) (word/dword/signed dword) 56323 + (byte*) CIA1_INTERRUPT#0 ← ((byte*)) (word/dword/signed dword) 56333 + (byte) CIA_INTERRUPT_CLEAR#0 ← (byte/signed byte/word/signed word/dword/signed dword) 127 + (byte*) CIA2_PORT_A#0 ← ((byte*)) (word/dword/signed dword) 56576 + (byte*) CIA2_PORT_B#0 ← ((byte*)) (word/dword/signed dword) 56577 + (byte*) CIA2_PORT_A_DDR#0 ← ((byte*)) (word/dword/signed dword) 56578 + (byte*) CIA2_PORT_B_DDR#0 ← ((byte*)) (word/dword/signed dword) 56579 + (byte*) CIA2_INTERRUPT#0 ← ((byte*)) (word/dword/signed dword) 56589 + (void()**) KERNEL_IRQ#0 ← ((void()**)) (word/signed word/dword/signed dword) 788 + (void()**) HARDWARE_IRQ#0 ← ((void()**)) (word/dword/signed dword) 65534 + (byte) BLACK#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + (byte) WHITE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) RED#0 ← (byte/signed byte/word/signed word/dword/signed dword) 2 + (byte) CYAN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 3 + (byte) PURPLE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 4 + (byte) GREEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 5 + (byte) BLUE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 6 + (byte) YELLOW#0 ← (byte/signed byte/word/signed word/dword/signed dword) 7 + (byte) ORANGE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 + (byte) BROWN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 9 + (byte) PINK#0 ← (byte/signed byte/word/signed word/dword/signed dword) 10 + (byte) DARK_GREY#0 ← (byte/signed byte/word/signed word/dword/signed dword) 11 + (byte) GREY#0 ← (byte/signed byte/word/signed word/dword/signed dword) 12 + (byte) LIGHT_GREEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 13 + (byte) LIGHT_BLUE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 14 + (byte) LIGHT_GREY#0 ← (byte/signed byte/word/signed word/dword/signed dword) 15 + to:@6 +main: scope:[main] from @6 + asm { sei } + (void()*~) main::$0 ← & interrupt(KERNEL_KEYBOARD)(void()) irq() + *((void()**) KERNEL_IRQ#0) ← (void()*~) main::$0 + asm { cli } + to:main::@return +main::@return: scope:[main] from main + return + to:@return +irq: scope:[irq] from + *((byte*) BGCOL#0) ← (byte) WHITE#0 + *((byte*) BGCOL#0) ← (byte) BLACK#0 + to:irq::@return +irq::@return: scope:[irq] from irq + return + to:@return +@6: scope:[] from @begin + call main + to:@7 +@7: scope:[] from @6 + to:@end +@end: scope:[] from @7 + +SYMBOL TABLE SSA +(label) @6 +(label) @7 +(label) @begin +(label) @end +(byte*) BGCOL +(byte*) BGCOL#0 +(byte*) BGCOL1 +(byte*) BGCOL1#0 +(byte*) BGCOL2 +(byte*) BGCOL2#0 +(byte*) BGCOL3 +(byte*) BGCOL3#0 +(byte*) BGCOL4 +(byte*) BGCOL4#0 +(byte) BLACK +(byte) BLACK#0 +(byte) BLUE +(byte) BLUE#0 +(byte*) BORDERCOL +(byte*) BORDERCOL#0 +(byte) BROWN +(byte) BROWN#0 +(byte*) CHARGEN +(byte*) CHARGEN#0 +(byte*) CIA1_INTERRUPT +(byte*) CIA1_INTERRUPT#0 +(byte*) CIA1_PORT_A +(byte*) CIA1_PORT_A#0 +(byte*) CIA1_PORT_A_DDR +(byte*) CIA1_PORT_A_DDR#0 +(byte*) CIA1_PORT_B +(byte*) CIA1_PORT_B#0 +(byte*) CIA1_PORT_B_DDR +(byte*) CIA1_PORT_B_DDR#0 +(byte*) CIA2_INTERRUPT +(byte*) CIA2_INTERRUPT#0 +(byte*) CIA2_PORT_A +(byte*) CIA2_PORT_A#0 +(byte*) CIA2_PORT_A_DDR +(byte*) CIA2_PORT_A_DDR#0 +(byte*) CIA2_PORT_B +(byte*) CIA2_PORT_B#0 +(byte*) CIA2_PORT_B_DDR +(byte*) CIA2_PORT_B_DDR#0 +(byte) CIA_INTERRUPT_CLEAR +(byte) CIA_INTERRUPT_CLEAR#0 +(byte*) COLS +(byte*) COLS#0 +(byte) CYAN +(byte) CYAN#0 +(byte*) D011 +(byte*) D011#0 +(byte*) D016 +(byte*) D016#0 +(byte*) D018 +(byte*) D018#0 +(byte) DARK_GREY +(byte) DARK_GREY#0 +(byte) GREEN +(byte) GREEN#0 +(byte) GREY +(byte) GREY#0 +(void()**) HARDWARE_IRQ +(void()**) HARDWARE_IRQ#0 +(byte) IRQ_COLLISION_BG +(byte) IRQ_COLLISION_BG#0 +(byte) IRQ_COLLISION_SPRITE +(byte) IRQ_COLLISION_SPRITE#0 +(byte*) IRQ_ENABLE +(byte*) IRQ_ENABLE#0 +(byte) IRQ_LIGHTPEN +(byte) IRQ_LIGHTPEN#0 +(byte) IRQ_RASTER +(byte) IRQ_RASTER#0 +(byte*) IRQ_STATUS +(byte*) IRQ_STATUS#0 +(void()**) KERNEL_IRQ +(void()**) KERNEL_IRQ#0 +(byte*) LIGHTPEN_X +(byte*) LIGHTPEN_X#0 +(byte*) LIGHTPEN_Y +(byte*) LIGHTPEN_Y#0 +(byte) LIGHT_BLUE +(byte) LIGHT_BLUE#0 +(byte) LIGHT_GREEN +(byte) LIGHT_GREEN#0 +(byte) LIGHT_GREY +(byte) LIGHT_GREY#0 +(byte) ORANGE +(byte) ORANGE#0 +(byte) PINK +(byte) PINK#0 +(byte*) PROCPORT +(byte*) PROCPORT#0 +(byte) PROCPORT_BASIC_KERNEL_IO +(byte) PROCPORT_BASIC_KERNEL_IO#0 +(byte*) PROCPORT_DDR +(byte*) PROCPORT_DDR#0 +(byte) PROCPORT_DDR_MEMORY_MASK +(byte) PROCPORT_DDR_MEMORY_MASK#0 +(byte) PROCPORT_KERNEL_IO +(byte) PROCPORT_KERNEL_IO#0 +(byte) PROCPORT_RAM_ALL +(byte) PROCPORT_RAM_ALL#0 +(byte) PROCPORT_RAM_CHARROM +(byte) PROCPORT_RAM_CHARROM#0 +(byte) PROCPORT_RAM_IO +(byte) PROCPORT_RAM_IO#0 +(byte) PURPLE +(byte) PURPLE#0 +(byte*) RASTER +(byte*) RASTER#0 +(byte) RED +(byte) RED#0 +(byte*) SPRITES_COLS +(byte*) SPRITES_COLS#0 +(byte*) SPRITES_ENABLE +(byte*) SPRITES_ENABLE#0 +(byte*) SPRITES_EXPAND_X +(byte*) SPRITES_EXPAND_X#0 +(byte*) SPRITES_EXPAND_Y +(byte*) SPRITES_EXPAND_Y#0 +(byte*) SPRITES_MC +(byte*) SPRITES_MC#0 +(byte*) SPRITES_MC1 +(byte*) SPRITES_MC1#0 +(byte*) SPRITES_MC2 +(byte*) SPRITES_MC2#0 +(byte*) SPRITES_PRIORITY +(byte*) SPRITES_PRIORITY#0 +(byte*) SPRITES_XMSB +(byte*) SPRITES_XMSB#0 +(byte*) SPRITES_XPOS +(byte*) SPRITES_XPOS#0 +(byte*) SPRITES_YPOS +(byte*) SPRITES_YPOS#0 +(word) SPRITE_PTRS +(word) SPRITE_PTRS#0 +(byte) VIC_BMM +(byte) VIC_BMM#0 +(byte*) VIC_CONTROL +(byte*) VIC_CONTROL#0 +(byte*) VIC_CONTROL2 +(byte*) VIC_CONTROL2#0 +(byte) VIC_CSEL +(byte) VIC_CSEL#0 +(byte) VIC_DEN +(byte) VIC_DEN#0 +(byte) VIC_ECM +(byte) VIC_ECM#0 +(byte) VIC_MCM +(byte) VIC_MCM#0 +(byte*) VIC_MEMORY +(byte*) VIC_MEMORY#0 +(byte) VIC_RSEL +(byte) VIC_RSEL#0 +(byte) VIC_RST8 +(byte) VIC_RST8#0 +(byte) WHITE +(byte) WHITE#0 +(byte) YELLOW +(byte) YELLOW#0 +interrupt(KERNEL_KEYBOARD)(void()) irq() +(label) irq::@return +(void()) main() +(void()*~) main::$0 +(label) main::@return + +Culled Empty Block (label) @7 +Successful SSA optimization Pass2CullEmptyBlocks +Constant (const byte*) PROCPORT_DDR#0 = ((byte*))0 +Constant (const byte) PROCPORT_DDR_MEMORY_MASK#0 = 7 +Constant (const byte*) PROCPORT#0 = ((byte*))1 +Constant (const byte) PROCPORT_RAM_ALL#0 = 48 +Constant (const byte) PROCPORT_RAM_IO#0 = 53 +Constant (const byte) PROCPORT_RAM_CHARROM#0 = 49 +Constant (const byte) PROCPORT_KERNEL_IO#0 = 54 +Constant (const byte) PROCPORT_BASIC_KERNEL_IO#0 = 55 +Constant (const byte*) CHARGEN#0 = ((byte*))53248 +Constant (const word) SPRITE_PTRS#0 = 1016 +Constant (const byte*) SPRITES_XPOS#0 = ((byte*))53248 +Constant (const byte*) SPRITES_YPOS#0 = ((byte*))53249 +Constant (const byte*) SPRITES_XMSB#0 = ((byte*))53264 +Constant (const byte*) RASTER#0 = ((byte*))53266 +Constant (const byte*) SPRITES_ENABLE#0 = ((byte*))53269 +Constant (const byte*) SPRITES_EXPAND_Y#0 = ((byte*))53271 +Constant (const byte*) SPRITES_PRIORITY#0 = ((byte*))53275 +Constant (const byte*) SPRITES_MC#0 = ((byte*))53276 +Constant (const byte*) SPRITES_EXPAND_X#0 = ((byte*))53277 +Constant (const byte*) BORDERCOL#0 = ((byte*))53280 +Constant (const byte*) BGCOL#0 = ((byte*))53281 +Constant (const byte*) BGCOL1#0 = ((byte*))53281 +Constant (const byte*) BGCOL2#0 = ((byte*))53282 +Constant (const byte*) BGCOL3#0 = ((byte*))53283 +Constant (const byte*) BGCOL4#0 = ((byte*))53284 +Constant (const byte*) SPRITES_MC1#0 = ((byte*))53285 +Constant (const byte*) SPRITES_MC2#0 = ((byte*))53286 +Constant (const byte*) SPRITES_COLS#0 = ((byte*))53287 +Constant (const byte*) VIC_CONTROL#0 = ((byte*))53265 +Constant (const byte*) D011#0 = ((byte*))53265 +Constant (const byte) VIC_RST8#0 = 128 +Constant (const byte) VIC_ECM#0 = 64 +Constant (const byte) VIC_BMM#0 = 32 +Constant (const byte) VIC_DEN#0 = 16 +Constant (const byte) VIC_RSEL#0 = 8 +Constant (const byte*) VIC_CONTROL2#0 = ((byte*))53270 +Constant (const byte*) D016#0 = ((byte*))53270 +Constant (const byte) VIC_MCM#0 = 16 +Constant (const byte) VIC_CSEL#0 = 8 +Constant (const byte*) D018#0 = ((byte*))53272 +Constant (const byte*) VIC_MEMORY#0 = ((byte*))53272 +Constant (const byte*) LIGHTPEN_X#0 = ((byte*))53267 +Constant (const byte*) LIGHTPEN_Y#0 = ((byte*))53268 +Constant (const byte*) IRQ_STATUS#0 = ((byte*))53273 +Constant (const byte*) IRQ_ENABLE#0 = ((byte*))53274 +Constant (const byte) IRQ_RASTER#0 = 1 +Constant (const byte) IRQ_COLLISION_BG#0 = 2 +Constant (const byte) IRQ_COLLISION_SPRITE#0 = 4 +Constant (const byte) IRQ_LIGHTPEN#0 = 8 +Constant (const byte*) COLS#0 = ((byte*))55296 +Constant (const byte*) CIA1_PORT_A#0 = ((byte*))56320 +Constant (const byte*) CIA1_PORT_B#0 = ((byte*))56321 +Constant (const byte*) CIA1_PORT_A_DDR#0 = ((byte*))56322 +Constant (const byte*) CIA1_PORT_B_DDR#0 = ((byte*))56323 +Constant (const byte*) CIA1_INTERRUPT#0 = ((byte*))56333 +Constant (const byte) CIA_INTERRUPT_CLEAR#0 = 127 +Constant (const byte*) CIA2_PORT_A#0 = ((byte*))56576 +Constant (const byte*) CIA2_PORT_B#0 = ((byte*))56577 +Constant (const byte*) CIA2_PORT_A_DDR#0 = ((byte*))56578 +Constant (const byte*) CIA2_PORT_B_DDR#0 = ((byte*))56579 +Constant (const byte*) CIA2_INTERRUPT#0 = ((byte*))56589 +Constant (const void()**) KERNEL_IRQ#0 = ((void()**))788 +Constant (const void()**) HARDWARE_IRQ#0 = ((void()**))65534 +Constant (const byte) BLACK#0 = 0 +Constant (const byte) WHITE#0 = 1 +Constant (const byte) RED#0 = 2 +Constant (const byte) CYAN#0 = 3 +Constant (const byte) PURPLE#0 = 4 +Constant (const byte) GREEN#0 = 5 +Constant (const byte) BLUE#0 = 6 +Constant (const byte) YELLOW#0 = 7 +Constant (const byte) ORANGE#0 = 8 +Constant (const byte) BROWN#0 = 9 +Constant (const byte) PINK#0 = 10 +Constant (const byte) DARK_GREY#0 = 11 +Constant (const byte) GREY#0 = 12 +Constant (const byte) LIGHT_GREEN#0 = 13 +Constant (const byte) LIGHT_BLUE#0 = 14 +Constant (const byte) LIGHT_GREY#0 = 15 +Constant (const void()*) main::$0 = &irq +Successful SSA optimization Pass2ConstantIdentification +Successful SSA optimization PassNEliminateUnusedVars +Constant inlined main::$0 = &interrupt(KERNEL_KEYBOARD)(void()) irq() +Successful SSA optimization Pass2ConstantInlining +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @6 +Adding NOP phi() at start of @end +CALL GRAPH +Calls in [] to main:2 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @6 +Adding NOP phi() at start of @end + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] phi() + to:@6 +@6: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @6 + [3] phi() +main: scope:[main] from @6 + asm { sei } + [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq() + asm { cli } + to:main::@return +main::@return: scope:[main] from main + [7] return + to:@return +irq: scope:[irq] from + [8] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 + [9] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 + to:irq::@return +irq::@return: scope:[irq] from irq + [10] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(byte*) BGCOL +(byte*) BGCOL1 +(byte*) BGCOL2 +(byte*) BGCOL3 +(byte*) BGCOL4 +(byte) BLACK +(byte) BLUE +(byte*) BORDERCOL +(byte) BROWN +(byte*) CHARGEN +(byte*) CIA1_INTERRUPT +(byte*) CIA1_PORT_A +(byte*) CIA1_PORT_A_DDR +(byte*) CIA1_PORT_B +(byte*) CIA1_PORT_B_DDR +(byte*) CIA2_INTERRUPT +(byte*) CIA2_PORT_A +(byte*) CIA2_PORT_A_DDR +(byte*) CIA2_PORT_B +(byte*) CIA2_PORT_B_DDR +(byte) CIA_INTERRUPT_CLEAR +(byte*) COLS +(byte) CYAN +(byte*) D011 +(byte*) D016 +(byte*) D018 +(byte) DARK_GREY +(byte) GREEN +(byte) GREY +(void()**) HARDWARE_IRQ +(byte) IRQ_COLLISION_BG +(byte) IRQ_COLLISION_SPRITE +(byte*) IRQ_ENABLE +(byte) IRQ_LIGHTPEN +(byte) IRQ_RASTER +(byte*) IRQ_STATUS +(void()**) KERNEL_IRQ +(byte*) LIGHTPEN_X +(byte*) LIGHTPEN_Y +(byte) LIGHT_BLUE +(byte) LIGHT_GREEN +(byte) LIGHT_GREY +(byte) ORANGE +(byte) PINK +(byte*) PROCPORT +(byte) PROCPORT_BASIC_KERNEL_IO +(byte*) PROCPORT_DDR +(byte) PROCPORT_DDR_MEMORY_MASK +(byte) PROCPORT_KERNEL_IO +(byte) PROCPORT_RAM_ALL +(byte) PROCPORT_RAM_CHARROM +(byte) PROCPORT_RAM_IO +(byte) PURPLE +(byte*) RASTER +(byte) RED +(byte*) SPRITES_COLS +(byte*) SPRITES_ENABLE +(byte*) SPRITES_EXPAND_X +(byte*) SPRITES_EXPAND_Y +(byte*) SPRITES_MC +(byte*) SPRITES_MC1 +(byte*) SPRITES_MC2 +(byte*) SPRITES_PRIORITY +(byte*) SPRITES_XMSB +(byte*) SPRITES_XPOS +(byte*) SPRITES_YPOS +(word) SPRITE_PTRS +(byte) VIC_BMM +(byte*) VIC_CONTROL +(byte*) VIC_CONTROL2 +(byte) VIC_CSEL +(byte) VIC_DEN +(byte) VIC_ECM +(byte) VIC_MCM +(byte*) VIC_MEMORY +(byte) VIC_RSEL +(byte) VIC_RST8 +(byte) WHITE +(byte) YELLOW +interrupt(KERNEL_KEYBOARD)(void()) irq() +(void()) main() + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label BGCOL = $d021 + .label KERNEL_IRQ = $314 + .const BLACK = 0 + .const WHITE = 1 +//SEG2 @begin +bbegin: +//SEG3 [1] phi from @begin to @6 [phi:@begin->@6] +b6_from_bbegin: + jmp b6 +//SEG4 @6 +b6: +//SEG5 [2] call main + jsr main +//SEG6 [3] phi from @6 to @end [phi:@6->@end] +bend_from_b6: + jmp bend +//SEG7 @end +bend: +//SEG8 main +// Setup the IRQ routine +main: { + //SEG9 asm { sei } + sei + //SEG10 [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq() -- _deref_pptc1=pprc2 + lda #irq + sta KERNEL_IRQ+1 + //SEG11 asm { cli } + cli + jmp breturn + //SEG12 main::@return + breturn: + //SEG13 [7] return + rts +} +//SEG14 irq +// The Interrupt Handler +irq: { + //SEG15 entry interrupt(KERNEL_KEYBOARD) + //SEG16 [8] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 + lda #WHITE + sta BGCOL + //SEG17 [9] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 + lda #BLACK + sta BGCOL + jmp breturn + //SEG18 irq::@return + breturn: + //SEG19 [10] return - exit interrupt(KERNEL_KEYBOARD) + jmp $ea31 +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq() [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [8] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( [ ] ) always clobbers reg byte a +Statement [9] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( [ ] ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [irq] +Uplift Scope [] + +Uplifting [main] best 55 combination +Uplifting [irq] best 55 combination +Uplifting [] best 55 combination + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label BGCOL = $d021 + .label KERNEL_IRQ = $314 + .const BLACK = 0 + .const WHITE = 1 +//SEG2 @begin +bbegin: +//SEG3 [1] phi from @begin to @6 [phi:@begin->@6] +b6_from_bbegin: + jmp b6 +//SEG4 @6 +b6: +//SEG5 [2] call main + jsr main +//SEG6 [3] phi from @6 to @end [phi:@6->@end] +bend_from_b6: + jmp bend +//SEG7 @end +bend: +//SEG8 main +// Setup the IRQ routine +main: { + //SEG9 asm { sei } + sei + //SEG10 [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq() -- _deref_pptc1=pprc2 + lda #irq + sta KERNEL_IRQ+1 + //SEG11 asm { cli } + cli + jmp breturn + //SEG12 main::@return + breturn: + //SEG13 [7] return + rts +} +//SEG14 irq +// The Interrupt Handler +irq: { + //SEG15 entry interrupt(KERNEL_KEYBOARD) + //SEG16 [8] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 + lda #WHITE + sta BGCOL + //SEG17 [9] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 + lda #BLACK + sta BGCOL + jmp breturn + //SEG18 irq::@return + breturn: + //SEG19 [10] return - exit interrupt(KERNEL_KEYBOARD) + jmp $ea31 +} + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b6 +Removing instruction jmp bend +Removing instruction jmp breturn +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction b6_from_bbegin: +Removing instruction b6: +Removing instruction bend_from_b6: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bend: +Removing instruction breturn: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction bbegin: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(label) @6 +(label) @begin +(label) @end +(byte*) BGCOL +(const byte*) BGCOL#0 BGCOL = ((byte*))(word/dword/signed dword) 53281 +(byte*) BGCOL1 +(byte*) BGCOL2 +(byte*) BGCOL3 +(byte*) BGCOL4 +(byte) BLACK +(const byte) BLACK#0 BLACK = (byte/signed byte/word/signed word/dword/signed dword) 0 +(byte) BLUE +(byte*) BORDERCOL +(byte) BROWN +(byte*) CHARGEN +(byte*) CIA1_INTERRUPT +(byte*) CIA1_PORT_A +(byte*) CIA1_PORT_A_DDR +(byte*) CIA1_PORT_B +(byte*) CIA1_PORT_B_DDR +(byte*) CIA2_INTERRUPT +(byte*) CIA2_PORT_A +(byte*) CIA2_PORT_A_DDR +(byte*) CIA2_PORT_B +(byte*) CIA2_PORT_B_DDR +(byte) CIA_INTERRUPT_CLEAR +(byte*) COLS +(byte) CYAN +(byte*) D011 +(byte*) D016 +(byte*) D018 +(byte) DARK_GREY +(byte) GREEN +(byte) GREY +(void()**) HARDWARE_IRQ +(byte) IRQ_COLLISION_BG +(byte) IRQ_COLLISION_SPRITE +(byte*) IRQ_ENABLE +(byte) IRQ_LIGHTPEN +(byte) IRQ_RASTER +(byte*) IRQ_STATUS +(void()**) KERNEL_IRQ +(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788 +(byte*) LIGHTPEN_X +(byte*) LIGHTPEN_Y +(byte) LIGHT_BLUE +(byte) LIGHT_GREEN +(byte) LIGHT_GREY +(byte) ORANGE +(byte) PINK +(byte*) PROCPORT +(byte) PROCPORT_BASIC_KERNEL_IO +(byte*) PROCPORT_DDR +(byte) PROCPORT_DDR_MEMORY_MASK +(byte) PROCPORT_KERNEL_IO +(byte) PROCPORT_RAM_ALL +(byte) PROCPORT_RAM_CHARROM +(byte) PROCPORT_RAM_IO +(byte) PURPLE +(byte*) RASTER +(byte) RED +(byte*) SPRITES_COLS +(byte*) SPRITES_ENABLE +(byte*) SPRITES_EXPAND_X +(byte*) SPRITES_EXPAND_Y +(byte*) SPRITES_MC +(byte*) SPRITES_MC1 +(byte*) SPRITES_MC2 +(byte*) SPRITES_PRIORITY +(byte*) SPRITES_XMSB +(byte*) SPRITES_XPOS +(byte*) SPRITES_YPOS +(word) SPRITE_PTRS +(byte) VIC_BMM +(byte*) VIC_CONTROL +(byte*) VIC_CONTROL2 +(byte) VIC_CSEL +(byte) VIC_DEN +(byte) VIC_ECM +(byte) VIC_MCM +(byte*) VIC_MEMORY +(byte) VIC_RSEL +(byte) VIC_RST8 +(byte) WHITE +(const byte) WHITE#0 WHITE = (byte/signed byte/word/signed word/dword/signed dword) 1 +(byte) YELLOW +interrupt(KERNEL_KEYBOARD)(void()) irq() +(label) irq::@return +(void()) main() +(label) main::@return + + + +FINAL ASSEMBLER +Score: 37 + +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label BGCOL = $d021 + .label KERNEL_IRQ = $314 + .const BLACK = 0 + .const WHITE = 1 +//SEG2 @begin +//SEG3 [1] phi from @begin to @6 [phi:@begin->@6] +//SEG4 @6 +//SEG5 [2] call main +//SEG6 [3] phi from @6 to @end [phi:@6->@end] +//SEG7 @end +//SEG8 main +// Setup the IRQ routine +main: { + //SEG9 asm { sei } + sei + //SEG10 [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq() -- _deref_pptc1=pprc2 + lda #irq + sta KERNEL_IRQ+1 + //SEG11 asm { cli } + cli + //SEG12 main::@return + //SEG13 [7] return + rts +} +//SEG14 irq +// The Interrupt Handler +irq: { + //SEG15 entry interrupt(KERNEL_KEYBOARD) + //SEG16 [8] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 + lda #WHITE + sta BGCOL + //SEG17 [9] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 + lda #BLACK + sta BGCOL + //SEG18 irq::@return + //SEG19 [10] return - exit interrupt(KERNEL_KEYBOARD) + jmp $ea31 +} + diff --git a/src/test/ref/irq-kernel-minimal.sym b/src/test/ref/irq-kernel-minimal.sym new file mode 100644 index 000000000..65222cbe1 --- /dev/null +++ b/src/test/ref/irq-kernel-minimal.sym @@ -0,0 +1,91 @@ +(label) @6 +(label) @begin +(label) @end +(byte*) BGCOL +(const byte*) BGCOL#0 BGCOL = ((byte*))(word/dword/signed dword) 53281 +(byte*) BGCOL1 +(byte*) BGCOL2 +(byte*) BGCOL3 +(byte*) BGCOL4 +(byte) BLACK +(const byte) BLACK#0 BLACK = (byte/signed byte/word/signed word/dword/signed dword) 0 +(byte) BLUE +(byte*) BORDERCOL +(byte) BROWN +(byte*) CHARGEN +(byte*) CIA1_INTERRUPT +(byte*) CIA1_PORT_A +(byte*) CIA1_PORT_A_DDR +(byte*) CIA1_PORT_B +(byte*) CIA1_PORT_B_DDR +(byte*) CIA2_INTERRUPT +(byte*) CIA2_PORT_A +(byte*) CIA2_PORT_A_DDR +(byte*) CIA2_PORT_B +(byte*) CIA2_PORT_B_DDR +(byte) CIA_INTERRUPT_CLEAR +(byte*) COLS +(byte) CYAN +(byte*) D011 +(byte*) D016 +(byte*) D018 +(byte) DARK_GREY +(byte) GREEN +(byte) GREY +(void()**) HARDWARE_IRQ +(byte) IRQ_COLLISION_BG +(byte) IRQ_COLLISION_SPRITE +(byte*) IRQ_ENABLE +(byte) IRQ_LIGHTPEN +(byte) IRQ_RASTER +(byte*) IRQ_STATUS +(void()**) KERNEL_IRQ +(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788 +(byte*) LIGHTPEN_X +(byte*) LIGHTPEN_Y +(byte) LIGHT_BLUE +(byte) LIGHT_GREEN +(byte) LIGHT_GREY +(byte) ORANGE +(byte) PINK +(byte*) PROCPORT +(byte) PROCPORT_BASIC_KERNEL_IO +(byte*) PROCPORT_DDR +(byte) PROCPORT_DDR_MEMORY_MASK +(byte) PROCPORT_KERNEL_IO +(byte) PROCPORT_RAM_ALL +(byte) PROCPORT_RAM_CHARROM +(byte) PROCPORT_RAM_IO +(byte) PURPLE +(byte*) RASTER +(byte) RED +(byte*) SPRITES_COLS +(byte*) SPRITES_ENABLE +(byte*) SPRITES_EXPAND_X +(byte*) SPRITES_EXPAND_Y +(byte*) SPRITES_MC +(byte*) SPRITES_MC1 +(byte*) SPRITES_MC2 +(byte*) SPRITES_PRIORITY +(byte*) SPRITES_XMSB +(byte*) SPRITES_XPOS +(byte*) SPRITES_YPOS +(word) SPRITE_PTRS +(byte) VIC_BMM +(byte*) VIC_CONTROL +(byte*) VIC_CONTROL2 +(byte) VIC_CSEL +(byte) VIC_DEN +(byte) VIC_ECM +(byte) VIC_MCM +(byte*) VIC_MEMORY +(byte) VIC_RSEL +(byte) VIC_RST8 +(byte) WHITE +(const byte) WHITE#0 WHITE = (byte/signed byte/word/signed word/dword/signed dword) 1 +(byte) YELLOW +interrupt(KERNEL_KEYBOARD)(void()) irq() +(label) irq::@return +(void()) main() +(label) main::@return + diff --git a/src/test/ref/irq-kernel.asm b/src/test/ref/irq-kernel.asm index b23230236..8a9cdf2a9 100644 --- a/src/test/ref/irq-kernel.asm +++ b/src/test/ref/irq-kernel.asm @@ -30,6 +30,7 @@ main: { cli rts } +// Interrupt Routine irq: { lda #WHITE sta BGCOL diff --git a/src/test/ref/irq-kernel.log b/src/test/ref/irq-kernel.log index dbe20e249..cd6e1412a 100644 --- a/src/test/ref/irq-kernel.log +++ b/src/test/ref/irq-kernel.log @@ -232,6 +232,7 @@ main: { rts } //SEG18 irq +// Interrupt Routine irq: { //SEG19 entry interrupt(KERNEL_KEYBOARD) //SEG20 [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 @@ -331,6 +332,7 @@ main: { rts } //SEG18 irq +// Interrupt Routine irq: { //SEG19 entry interrupt(KERNEL_KEYBOARD) //SEG20 [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 @@ -459,6 +461,7 @@ main: { rts } //SEG18 irq +// Interrupt Routine irq: { //SEG19 entry interrupt(KERNEL_KEYBOARD) //SEG20 [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 diff --git a/src/test/ref/irq-raster.asm b/src/test/ref/irq-raster.asm index bbfdbc200..10c20320c 100644 --- a/src/test/ref/irq-raster.asm +++ b/src/test/ref/irq-raster.asm @@ -30,6 +30,7 @@ main: { cli rts } +// Interrupt Routine irq: { lda #WHITE sta BGCOL diff --git a/src/test/ref/irq-raster.log b/src/test/ref/irq-raster.log index 0bbbe8a02..68e633c3e 100644 --- a/src/test/ref/irq-raster.log +++ b/src/test/ref/irq-raster.log @@ -232,6 +232,7 @@ main: { rts } //SEG18 irq +// Interrupt Routine irq: { //SEG19 entry interrupt(KERNEL_MIN) //SEG20 [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 @@ -331,6 +332,7 @@ main: { rts } //SEG18 irq +// Interrupt Routine irq: { //SEG19 entry interrupt(KERNEL_MIN) //SEG20 [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 @@ -459,6 +461,7 @@ main: { rts } //SEG18 irq +// Interrupt Routine irq: { //SEG19 entry interrupt(KERNEL_MIN) //SEG20 [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 diff --git a/src/test/ref/keyboard-glitch.asm b/src/test/ref/keyboard-glitch.asm index 437c2825a..07fdcc8d5 100644 --- a/src/test/ref/keyboard-glitch.asm +++ b/src/test/ref/keyboard-glitch.asm @@ -50,6 +50,10 @@ menu: { inc SCREEN jmp b2 } +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { txa and #7 @@ -63,6 +67,11 @@ keyboard_key_pressed: { and keyboard_matrix_col_bitmask,y rts } +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { lda keyboard_matrix_row_bitmask,x sta CIA1_PORT_A diff --git a/src/test/ref/keyboard-glitch.log b/src/test/ref/keyboard-glitch.log index 231379c28..64c590c3a 100644 --- a/src/test/ref/keyboard-glitch.log +++ b/src/test/ref/keyboard-glitch.log @@ -1497,6 +1497,10 @@ menu: { jmp b2_from_b6 } //SEG55 keyboard_key_pressed +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { .label _2 = $d .label colidx = 9 @@ -1543,6 +1547,11 @@ keyboard_key_pressed: { rts } //SEG66 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { .label return = $f .label rowid = $b @@ -1726,12 +1735,10 @@ menu: { ldx #KEY_C jsr keyboard_key_pressed //SEG20 [10] (byte) keyboard_key_pressed::return#2 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#2 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b16 //SEG21 menu::@16 b16: //SEG22 [11] (byte~) menu::$0 ← (byte) keyboard_key_pressed::return#2 - // (byte~) menu::$0 = (byte) keyboard_key_pressed::return#2 // register copy reg byte a //SEG23 [12] if((byte~) menu::$0==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@4 -- vbuaa_eq_0_then_la1 cmp #0 beq b4_from_b16 @@ -1759,12 +1766,10 @@ menu: { ldx #KEY_I jsr keyboard_key_pressed //SEG34 [18] (byte) keyboard_key_pressed::return#3 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#3 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b17 //SEG35 menu::@17 b17: //SEG36 [19] (byte~) menu::$4 ← (byte) keyboard_key_pressed::return#3 - // (byte~) menu::$4 = (byte) keyboard_key_pressed::return#3 // register copy reg byte a //SEG37 [20] if((byte~) menu::$4==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@5 -- vbuaa_eq_0_then_la1 cmp #0 beq b5_from_b17 @@ -1789,12 +1794,10 @@ menu: { ldx #KEY_E jsr keyboard_key_pressed //SEG46 [25] (byte) keyboard_key_pressed::return#4 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#4 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b19 //SEG47 menu::@19 b19: //SEG48 [26] (byte~) menu::$7 ← (byte) keyboard_key_pressed::return#4 - // (byte~) menu::$7 = (byte) keyboard_key_pressed::return#4 // register copy reg byte a //SEG49 [27] if((byte~) menu::$7==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@6 -- vbuaa_eq_0_then_la1 cmp #0 beq b6 @@ -1814,6 +1817,10 @@ menu: { jmp b2_from_b6 } //SEG55 keyboard_key_pressed +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { //SEG56 [32] (byte) keyboard_key_pressed::colidx#0 ← (byte) keyboard_key_pressed::key#4 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuyy=vbuxx_band_vbuc1 txa @@ -1829,12 +1836,10 @@ keyboard_key_pressed: { //SEG59 [35] call keyboard_matrix_read jsr keyboard_matrix_read //SEG60 [36] (byte) keyboard_matrix_read::return#2 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#2 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a jmp b2 //SEG61 keyboard_key_pressed::@2 b2: //SEG62 [37] (byte~) keyboard_key_pressed::$2 ← (byte) keyboard_matrix_read::return#2 - // (byte~) keyboard_key_pressed::$2 = (byte) keyboard_matrix_read::return#2 // register copy reg byte a //SEG63 [38] (byte) keyboard_key_pressed::return#0 ← (byte~) keyboard_key_pressed::$2 & *((const byte[8]) keyboard_matrix_col_bitmask#0 + (byte) keyboard_key_pressed::colidx#0) -- vbuaa=vbuaa_band_pbuc1_derefidx_vbuyy and keyboard_matrix_col_bitmask,y jmp breturn @@ -1844,6 +1849,11 @@ keyboard_key_pressed: { rts } //SEG66 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { //SEG67 [40] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0 + (byte) keyboard_matrix_read::rowid#0) -- _deref_pbuc1=pbuc2_derefidx_vbuxx lda keyboard_matrix_row_bitmask,x @@ -1874,12 +1884,10 @@ pressed: { ldx #KEY_SPACE jsr keyboard_key_pressed //SEG78 [46] (byte) keyboard_key_pressed::return#10 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#10 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b10 //SEG79 pressed::@10 b10: //SEG80 [47] (byte~) pressed::$0 ← (byte) keyboard_key_pressed::return#10 - // (byte~) pressed::$0 = (byte) keyboard_key_pressed::return#10 // register copy reg byte a //SEG81 [48] if((byte~) pressed::$0==(byte/signed byte/word/signed word/dword/signed dword) 0) goto pressed::@2 -- vbuaa_eq_0_then_la1 cmp #0 beq b2_from_b10 @@ -2242,10 +2250,8 @@ menu: { ldx #KEY_C jsr keyboard_key_pressed //SEG20 [10] (byte) keyboard_key_pressed::return#2 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#2 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG21 menu::@16 //SEG22 [11] (byte~) menu::$0 ← (byte) keyboard_key_pressed::return#2 - // (byte~) menu::$0 = (byte) keyboard_key_pressed::return#2 // register copy reg byte a //SEG23 [12] if((byte~) menu::$0==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@4 -- vbuaa_eq_0_then_la1 cmp #0 beq b4 @@ -2266,10 +2272,8 @@ menu: { ldx #KEY_I jsr keyboard_key_pressed //SEG34 [18] (byte) keyboard_key_pressed::return#3 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#3 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG35 menu::@17 //SEG36 [19] (byte~) menu::$4 ← (byte) keyboard_key_pressed::return#3 - // (byte~) menu::$4 = (byte) keyboard_key_pressed::return#3 // register copy reg byte a //SEG37 [20] if((byte~) menu::$4==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@5 -- vbuaa_eq_0_then_la1 cmp #0 beq b5 @@ -2289,10 +2293,8 @@ menu: { ldx #KEY_E jsr keyboard_key_pressed //SEG46 [25] (byte) keyboard_key_pressed::return#4 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#4 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG47 menu::@19 //SEG48 [26] (byte~) menu::$7 ← (byte) keyboard_key_pressed::return#4 - // (byte~) menu::$7 = (byte) keyboard_key_pressed::return#4 // register copy reg byte a //SEG49 [27] if((byte~) menu::$7==(byte/signed byte/word/signed word/dword/signed dword) 0) goto menu::@6 -- vbuaa_eq_0_then_la1 cmp #0 beq b6 @@ -2310,6 +2312,10 @@ menu: { jmp b2 } //SEG55 keyboard_key_pressed +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { //SEG56 [32] (byte) keyboard_key_pressed::colidx#0 ← (byte) keyboard_key_pressed::key#4 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuyy=vbuxx_band_vbuc1 txa @@ -2325,10 +2331,8 @@ keyboard_key_pressed: { //SEG59 [35] call keyboard_matrix_read jsr keyboard_matrix_read //SEG60 [36] (byte) keyboard_matrix_read::return#2 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#2 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a //SEG61 keyboard_key_pressed::@2 //SEG62 [37] (byte~) keyboard_key_pressed::$2 ← (byte) keyboard_matrix_read::return#2 - // (byte~) keyboard_key_pressed::$2 = (byte) keyboard_matrix_read::return#2 // register copy reg byte a //SEG63 [38] (byte) keyboard_key_pressed::return#0 ← (byte~) keyboard_key_pressed::$2 & *((const byte[8]) keyboard_matrix_col_bitmask#0 + (byte) keyboard_key_pressed::colidx#0) -- vbuaa=vbuaa_band_pbuc1_derefidx_vbuyy and keyboard_matrix_col_bitmask,y //SEG64 keyboard_key_pressed::@return @@ -2336,6 +2340,11 @@ keyboard_key_pressed: { rts } //SEG66 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { //SEG67 [40] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0 + (byte) keyboard_matrix_read::rowid#0) -- _deref_pbuc1=pbuc2_derefidx_vbuxx lda keyboard_matrix_row_bitmask,x @@ -2360,10 +2369,8 @@ pressed: { ldx #KEY_SPACE jsr keyboard_key_pressed //SEG78 [46] (byte) keyboard_key_pressed::return#10 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#10 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG79 pressed::@10 //SEG80 [47] (byte~) pressed::$0 ← (byte) keyboard_key_pressed::return#10 - // (byte~) pressed::$0 = (byte) keyboard_key_pressed::return#10 // register copy reg byte a //SEG81 [48] if((byte~) pressed::$0==(byte/signed byte/word/signed word/dword/signed dword) 0) goto pressed::@2 -- vbuaa_eq_0_then_la1 cmp #0 beq b2 diff --git a/src/test/ref/line-anim.asm b/src/test/ref/line-anim.asm index ed337359a..5ca528af0 100644 --- a/src/test/ref/line-anim.asm +++ b/src/test/ref/line-anim.asm @@ -70,6 +70,7 @@ main: { inc BORDERCOL jmp b5 } +// Plot a single dot in the bitmap bitmap_plot: { .label _1 = $b .label x = 5 @@ -100,6 +101,7 @@ bitmap_plot: { sta (plotter),y rts } +// Initialize the points to be animated point_init: { .label _4 = $e .label _5 = 5 @@ -256,6 +258,11 @@ point_init: { sta abs16s1__2+1 jmp abs16s2 } +// Perform division on two signed 16-bit numbers with an initial remainder. +// Returns dividend/divisor. The remainder will be set into the global variable rem16s. +// 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: { .const dividend = 0 .label _7 = 9 @@ -338,6 +345,10 @@ divr16s: { ldy #1 jmp b2 } +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 9 .label dividend = 3 @@ -388,6 +399,7 @@ divr16u: { bne b1 rts } +// Fill the screen with a specific char screen_fill: { .const ch = $10 .label screen = 3 @@ -417,6 +429,7 @@ screen_fill: { bne b1 rts } +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = 3 .label y = 2 diff --git a/src/test/ref/line-anim.log b/src/test/ref/line-anim.log index 9938c08c5..e97b5eca0 100644 --- a/src/test/ref/line-anim.log +++ b/src/test/ref/line-anim.log @@ -3282,6 +3282,7 @@ main: { jmp b5 } //SEG55 bitmap_plot +// Plot a single dot in the bitmap bitmap_plot: { .label _1 = $2d .label _2 = $31 @@ -3327,6 +3328,7 @@ bitmap_plot: { rts } //SEG63 point_init +// Initialize the points to be animated point_init: { .label _4 = $35 .label _5 = $37 @@ -3595,6 +3597,11 @@ point_init: { jmp abs16s1_breturn_from_abs16s1_b1 } //SEG120 divr16s +// Perform division on two signed 16-bit numbers with an initial remainder. +// Returns dividend/divisor. The remainder will be set into the global variable rem16s. +// 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: { .const dividend = 0 .label _7 = $57 @@ -3790,6 +3797,10 @@ divr16s: { jmp b2 } //SEG168 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label _1 = $59 .label _2 = $5a @@ -3902,6 +3913,7 @@ divr16u: { rts } //SEG203 screen_fill +// Fill the screen with a specific char screen_fill: { .const ch = $10 .label screen = $1a @@ -3970,6 +3982,7 @@ screen_fill: { rts } //SEG227 bitmap_clear +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = $1e .label x = $20 @@ -4625,7 +4638,6 @@ main: { //SEG40 main::@1 b1: //SEG41 [19] (byte) point_init::point_idx#0 ← (byte) main::i#2 - // (byte) point_init::point_idx#0 = (byte) main::i#2 // register copy zp ZP_BYTE:2 //SEG42 [20] call point_init jsr point_init jmp b20 @@ -4672,6 +4684,7 @@ main: { jmp b5 } //SEG55 bitmap_plot +// Plot a single dot in the bitmap bitmap_plot: { .label _1 = $b .label x = 5 @@ -4713,6 +4726,7 @@ bitmap_plot: { rts } //SEG63 point_init +// Initialize the points to be animated point_init: { .label _4 = $e .label _5 = 5 @@ -4889,7 +4903,6 @@ point_init: { //SEG101 point_init::@4 b4: //SEG102 [57] (signed word) divr16s::divisor#0 ← (signed word) point_init::x_diff#1 - // (signed word) divr16s::divisor#0 = (signed word) point_init::x_diff#1 // register copy zp ZP_WORD:11 //SEG103 [58] (signed word) divr16s::rem#0 ← (signed word) point_init::y_diff#0 -- vwsz1=vwsz2 lda y_diff sta divr16s.rem @@ -4900,12 +4913,10 @@ point_init: { divr16s_from_b4: jsr divr16s //SEG106 [60] (signed word) divr16s::return#3 ← (signed word) divr16s::return#2 - // (signed word) divr16s::return#3 = (signed word) divr16s::return#2 // register copy zp ZP_WORD:5 jmp b11 //SEG107 point_init::@11 b11: //SEG108 [61] (signed word) point_init::x_stepf#0 ← (signed word) divr16s::return#3 - // (signed word) point_init::x_stepf#0 = (signed word) divr16s::return#3 // register copy zp ZP_WORD:5 //SEG109 [62] (byte~) point_init::$13 ← > (signed word) point_init::x_stepf#0 -- vbuaa=_hi_vwsz1 lda x_stepf+1 //SEG110 [63] (byte~) point_init::$14 ← (byte~) point_init::$13 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuaa_ror_4 @@ -4937,7 +4948,6 @@ point_init: { adc #0 sta abs16s2__2+1 //SEG116 [67] (word~) point_init::abs16s2_return#5 ← (word)(signed word) point_init::abs16s2_$2#0 - // (word~) point_init::abs16s2_return#5 = (word)(signed word) point_init::abs16s2_$2#0 // register copy zp ZP_WORD:7 jmp abs16s2_breturn_from_abs16s2_b1 //SEG117 point_init::abs16s1_@1 abs16s1_b1: @@ -4952,10 +4962,14 @@ point_init: { adc #0 sta abs16s1__2+1 //SEG119 [69] (word~) point_init::abs16s1_return#5 ← (word)(signed word) point_init::abs16s1_$2#0 - // (word~) point_init::abs16s1_return#5 = (word)(signed word) point_init::abs16s1_$2#0 // register copy zp ZP_WORD:5 jmp abs16s1_breturn_from_abs16s1_b1 } //SEG120 divr16s +// Perform division on two signed 16-bit numbers with an initial remainder. +// Returns dividend/divisor. The remainder will be set into the global variable rem16s. +// 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: { .const dividend = 0 .label _7 = 9 @@ -4977,7 +4991,6 @@ divr16s: { //SEG123 divr16s::@17 b17: //SEG124 [72] (word~) divr16s::remu#8 ← (word)(signed word) divr16s::rem#0 - // (word~) divr16s::remu#8 = (word)(signed word) divr16s::rem#0 // register copy zp ZP_WORD:9 //SEG125 [73] phi from divr16s::@17 to divr16s::@2 [phi:divr16s::@17->divr16s::@2] b2_from_b17: //SEG126 [73] phi (word) divr16s::remu#3 = (word~) divr16s::remu#8 [phi:divr16s::@17->divr16s::@2#0] -- register_copy @@ -4998,7 +5011,6 @@ divr16s: { //SEG131 divr16s::@18 b18: //SEG132 [75] (word~) divr16s::divisoru#5 ← (word)(signed word) divr16s::divisor#0 - // (word~) divr16s::divisoru#5 = (word)(signed word) divr16s::divisor#0 // register copy zp ZP_WORD:11 //SEG133 [76] phi from divr16s::@18 divr16s::@3 to divr16s::@4 [phi:divr16s::@18/divr16s::@3->divr16s::@4] b4_from_b18: b4_from_b3: @@ -5008,22 +5020,17 @@ divr16s: { //SEG136 divr16s::@4 b4: //SEG137 [77] (word) divr16u::dividend#1 ← (word) divr16s::dividendu#3 - // (word) divr16u::dividend#1 = (word) divr16s::dividendu#3 // register copy zp ZP_WORD:3 //SEG138 [78] (word) divr16u::divisor#0 ← (word) divr16s::divisoru#3 - // (word) divr16u::divisor#0 = (word) divr16s::divisoru#3 // register copy zp ZP_WORD:11 //SEG139 [79] (word) divr16u::rem#3 ← (word) divr16s::remu#3 - // (word) divr16u::rem#3 = (word) divr16s::remu#3 // register copy zp ZP_WORD:9 //SEG140 [80] call divr16u //SEG141 [95] phi from divr16s::@4 to divr16u [phi:divr16s::@4->divr16u] divr16u_from_b4: jsr divr16u //SEG142 [81] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:5 jmp b15 //SEG143 divr16s::@15 b15: //SEG144 [82] (word) divr16s::resultu#0 ← (word) divr16u::return#2 - // (word) divr16s::resultu#0 = (word) divr16u::return#2 // register copy zp ZP_WORD:5 //SEG145 [83] if((byte) divr16s::neg#4==(byte/signed byte/word/signed word/dword/signed dword) 0) goto divr16s::@19 -- vbuyy_eq_0_then_la1 cpy #0 beq b19 @@ -5063,7 +5070,6 @@ divr16s: { //SEG154 divr16s::@19 b19: //SEG155 [88] (signed word~) divr16s::return#7 ← (signed word)(word) divr16s::resultu#0 - // (signed word~) divr16s::return#7 = (signed word)(word) divr16s::resultu#0 // register copy zp ZP_WORD:5 //SEG156 [89] (signed word~) rem16s#57 ← (signed word)(word) divr16u::rem#10 -- vwsz1=vwsz2 lda divr16u.rem sta rem16s @@ -5087,7 +5093,6 @@ divr16s: { eor #1 tay //SEG160 [92] (word~) divr16s::divisoru#4 ← (word)(signed word~) divr16s::$11 - // (word~) divr16s::divisoru#4 = (word)(signed word~) divr16s::$11 // register copy zp ZP_WORD:11 jmp b4_from_b3 //SEG161 divr16s::@1 b1: @@ -5102,7 +5107,6 @@ divr16s: { adc #0 sta _7+1 //SEG163 [94] (word~) divr16s::remu#7 ← (word)(signed word~) divr16s::$7 - // (word~) divr16s::remu#7 = (word)(signed word~) divr16s::$7 // register copy zp ZP_WORD:9 //SEG164 [73] phi from divr16s::@1 to divr16s::@2 [phi:divr16s::@1->divr16s::@2] b2_from_b1: //SEG165 [73] phi (word) divr16s::remu#3 = (word~) divr16s::remu#7 [phi:divr16s::@1->divr16s::@2#0] -- register_copy @@ -5116,6 +5120,10 @@ divr16s: { jmp b2 } //SEG168 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 9 .label dividend = 3 @@ -5218,6 +5226,7 @@ divr16u: { rts } //SEG203 screen_fill +// Fill the screen with a specific char screen_fill: { .const ch = $10 .label screen = 3 @@ -5283,6 +5292,7 @@ screen_fill: { rts } //SEG227 bitmap_clear +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = 3 .label y = 2 @@ -5293,7 +5303,6 @@ bitmap_clear: { lda bitmap_plot_yhi sta _3+1 //SEG229 [123] (byte*~) bitmap_clear::bitmap#5 ← (byte*)(word~) bitmap_clear::$3 - // (byte*~) bitmap_clear::bitmap#5 = (byte*)(word~) bitmap_clear::$3 // register copy zp ZP_WORD:3 //SEG230 [124] phi from bitmap_clear to bitmap_clear::@1 [phi:bitmap_clear->bitmap_clear::@1] b1_from_bitmap_clear: //SEG231 [124] phi (byte) bitmap_clear::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:bitmap_clear->bitmap_clear::@1#0] -- vbuz1=vbuc1 @@ -5582,8 +5591,11 @@ Removing instruction abs16s2_breturn_from_abs16s2_b1: Removing instruction abs16s2_breturn: Removing instruction b2_from_b10: Removing instruction b2_from_b11: +Removing instruction b2_from_b17: +Removing instruction b18: Removing instruction b4_from_b18: Removing instruction b4_from_b3: +Removing instruction divr16u_from_b4: Removing instruction breturn_from_b11: Removing instruction breturn_from_b19: Removing instruction b1_from_b3: @@ -5625,9 +5637,6 @@ Removing instruction divr16s_from_b4: Removing instruction b11: Removing instruction b16: Removing instruction b17: -Removing instruction b2_from_b17: -Removing instruction b18: -Removing instruction divr16u_from_b4: Removing instruction b15: Removing instruction b11: Removing instruction b2_from_b1: @@ -5666,8 +5675,8 @@ Removing instruction b10: Succesful ASM optimization Pass5UnusedLabelElimination Removing unreachable instruction jmp b2 Succesful ASM optimization Pass5UnreachableCodeElimination -Fixing long branch [145] bmi abs16s1_b1 to bpl -Fixing long branch [154] bmi abs16s2_b1 to bpl +Fixing long branch [147] bmi abs16s1_b1 to bpl +Fixing long branch [156] bmi abs16s2_b1 to bpl FINAL SYMBOL TABLE (label) @19 @@ -6170,7 +6179,6 @@ main: { //SEG40 main::@1 b1: //SEG41 [19] (byte) point_init::point_idx#0 ← (byte) main::i#2 - // (byte) point_init::point_idx#0 = (byte) main::i#2 // register copy zp ZP_BYTE:2 //SEG42 [20] call point_init jsr point_init //SEG43 main::@20 @@ -6209,6 +6217,7 @@ main: { jmp b5 } //SEG55 bitmap_plot +// Plot a single dot in the bitmap bitmap_plot: { .label _1 = $b .label x = 5 @@ -6247,6 +6256,7 @@ bitmap_plot: { rts } //SEG63 point_init +// Initialize the points to be animated point_init: { .label _4 = $e .label _5 = 5 @@ -6401,7 +6411,6 @@ point_init: { //SEG101 point_init::@4 b4: //SEG102 [57] (signed word) divr16s::divisor#0 ← (signed word) point_init::x_diff#1 - // (signed word) divr16s::divisor#0 = (signed word) point_init::x_diff#1 // register copy zp ZP_WORD:11 //SEG103 [58] (signed word) divr16s::rem#0 ← (signed word) point_init::y_diff#0 -- vwsz1=vwsz2 lda y_diff sta divr16s.rem @@ -6411,10 +6420,8 @@ point_init: { //SEG105 [70] phi from point_init::@4 to divr16s [phi:point_init::@4->divr16s] jsr divr16s //SEG106 [60] (signed word) divr16s::return#3 ← (signed word) divr16s::return#2 - // (signed word) divr16s::return#3 = (signed word) divr16s::return#2 // register copy zp ZP_WORD:5 //SEG107 point_init::@11 //SEG108 [61] (signed word) point_init::x_stepf#0 ← (signed word) divr16s::return#3 - // (signed word) point_init::x_stepf#0 = (signed word) divr16s::return#3 // register copy zp ZP_WORD:5 //SEG109 [62] (byte~) point_init::$13 ← > (signed word) point_init::x_stepf#0 -- vbuaa=_hi_vwsz1 lda x_stepf+1 //SEG110 [63] (byte~) point_init::$14 ← (byte~) point_init::$13 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuaa_ror_4 @@ -6446,7 +6453,6 @@ point_init: { adc #0 sta abs16s2__2+1 //SEG116 [67] (word~) point_init::abs16s2_return#5 ← (word)(signed word) point_init::abs16s2_$2#0 - // (word~) point_init::abs16s2_return#5 = (word)(signed word) point_init::abs16s2_$2#0 // register copy zp ZP_WORD:7 jmp b10 //SEG117 point_init::abs16s1_@1 abs16s1_b1: @@ -6461,10 +6467,14 @@ point_init: { adc #0 sta abs16s1__2+1 //SEG119 [69] (word~) point_init::abs16s1_return#5 ← (word)(signed word) point_init::abs16s1_$2#0 - // (word~) point_init::abs16s1_return#5 = (word)(signed word) point_init::abs16s1_$2#0 // register copy zp ZP_WORD:5 jmp abs16s2 } //SEG120 divr16s +// Perform division on two signed 16-bit numbers with an initial remainder. +// Returns dividend/divisor. The remainder will be set into the global variable rem16s. +// 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: { .const dividend = 0 .label _7 = 9 @@ -6482,7 +6492,6 @@ divr16s: { bmi b1 //SEG123 divr16s::@17 //SEG124 [72] (word~) divr16s::remu#8 ← (word)(signed word) divr16s::rem#0 - // (word~) divr16s::remu#8 = (word)(signed word) divr16s::rem#0 // register copy zp ZP_WORD:9 //SEG125 [73] phi from divr16s::@17 to divr16s::@2 [phi:divr16s::@17->divr16s::@2] //SEG126 [73] phi (word) divr16s::remu#3 = (word~) divr16s::remu#8 [phi:divr16s::@17->divr16s::@2#0] -- register_copy //SEG127 [73] phi (word) divr16s::dividendu#3 = ((word))(const signed word) divr16s::dividend#0 [phi:divr16s::@17->divr16s::@2#1] -- vwuz1=vbuc1 @@ -6499,26 +6508,20 @@ divr16s: { bmi b3 //SEG131 divr16s::@18 //SEG132 [75] (word~) divr16s::divisoru#5 ← (word)(signed word) divr16s::divisor#0 - // (word~) divr16s::divisoru#5 = (word)(signed word) divr16s::divisor#0 // register copy zp ZP_WORD:11 //SEG133 [76] phi from divr16s::@18 divr16s::@3 to divr16s::@4 [phi:divr16s::@18/divr16s::@3->divr16s::@4] //SEG134 [76] phi (byte) divr16s::neg#4 = (byte) divr16s::neg#3 [phi:divr16s::@18/divr16s::@3->divr16s::@4#0] -- register_copy //SEG135 [76] phi (word) divr16s::divisoru#3 = (word~) divr16s::divisoru#5 [phi:divr16s::@18/divr16s::@3->divr16s::@4#1] -- register_copy //SEG136 divr16s::@4 b4: //SEG137 [77] (word) divr16u::dividend#1 ← (word) divr16s::dividendu#3 - // (word) divr16u::dividend#1 = (word) divr16s::dividendu#3 // register copy zp ZP_WORD:3 //SEG138 [78] (word) divr16u::divisor#0 ← (word) divr16s::divisoru#3 - // (word) divr16u::divisor#0 = (word) divr16s::divisoru#3 // register copy zp ZP_WORD:11 //SEG139 [79] (word) divr16u::rem#3 ← (word) divr16s::remu#3 - // (word) divr16u::rem#3 = (word) divr16s::remu#3 // register copy zp ZP_WORD:9 //SEG140 [80] call divr16u //SEG141 [95] phi from divr16s::@4 to divr16u [phi:divr16s::@4->divr16u] jsr divr16u //SEG142 [81] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:5 //SEG143 divr16s::@15 //SEG144 [82] (word) divr16s::resultu#0 ← (word) divr16u::return#2 - // (word) divr16s::resultu#0 = (word) divr16u::return#2 // register copy zp ZP_WORD:5 //SEG145 [83] if((byte) divr16s::neg#4==(byte/signed byte/word/signed word/dword/signed dword) 0) goto divr16s::@19 -- vbuyy_eq_0_then_la1 cpy #0 beq b19 @@ -6553,7 +6556,6 @@ divr16s: { //SEG154 divr16s::@19 b19: //SEG155 [88] (signed word~) divr16s::return#7 ← (signed word)(word) divr16s::resultu#0 - // (signed word~) divr16s::return#7 = (signed word)(word) divr16s::resultu#0 // register copy zp ZP_WORD:5 //SEG156 [89] (signed word~) rem16s#57 ← (signed word)(word) divr16u::rem#10 -- vwsz1=vwsz2 lda divr16u.rem sta rem16s @@ -6577,7 +6579,6 @@ divr16s: { eor #1 tay //SEG160 [92] (word~) divr16s::divisoru#4 ← (word)(signed word~) divr16s::$11 - // (word~) divr16s::divisoru#4 = (word)(signed word~) divr16s::$11 // register copy zp ZP_WORD:11 jmp b4 //SEG161 divr16s::@1 b1: @@ -6592,7 +6593,6 @@ divr16s: { adc #0 sta _7+1 //SEG163 [94] (word~) divr16s::remu#7 ← (word)(signed word~) divr16s::$7 - // (word~) divr16s::remu#7 = (word)(signed word~) divr16s::$7 // register copy zp ZP_WORD:9 //SEG164 [73] phi from divr16s::@1 to divr16s::@2 [phi:divr16s::@1->divr16s::@2] //SEG165 [73] phi (word) divr16s::remu#3 = (word~) divr16s::remu#7 [phi:divr16s::@1->divr16s::@2#0] -- register_copy //SEG166 [73] phi (word) divr16s::dividendu#3 = ((word))-(const signed word) divr16s::dividend#0 [phi:divr16s::@1->divr16s::@2#1] -- vwuz1=vbuc1 @@ -6605,6 +6605,10 @@ divr16s: { jmp b2 } //SEG168 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 9 .label dividend = 3 @@ -6690,6 +6694,7 @@ divr16u: { rts } //SEG203 screen_fill +// Fill the screen with a specific char screen_fill: { .const ch = $10 .label screen = 3 @@ -6743,6 +6748,7 @@ screen_fill: { rts } //SEG227 bitmap_clear +// Clear all graphics on the bitmap bitmap_clear: { .label bitmap = 3 .label y = 2 @@ -6753,7 +6759,6 @@ bitmap_clear: { lda bitmap_plot_yhi sta _3+1 //SEG229 [123] (byte*~) bitmap_clear::bitmap#5 ← (byte*)(word~) bitmap_clear::$3 - // (byte*~) bitmap_clear::bitmap#5 = (byte*)(word~) bitmap_clear::$3 // register copy zp ZP_WORD:3 //SEG230 [124] phi from bitmap_clear to bitmap_clear::@1 [phi:bitmap_clear->bitmap_clear::@1] //SEG231 [124] phi (byte) bitmap_clear::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:bitmap_clear->bitmap_clear::@1#0] -- vbuz1=vbuc1 lda #0 diff --git a/src/test/ref/linegen.asm b/src/test/ref/linegen.asm index 7b1a05caa..2b576dd60 100644 --- a/src/test/ref/linegen.asm +++ b/src/test/ref/linegen.asm @@ -181,6 +181,7 @@ main: { lintab2: .fill 2*$14, 0 lintab3: .fill 2*$14, 0 } +// Print a newline print_ln: { b1: lda print_line_cursor @@ -200,6 +201,7 @@ print_ln: { !: rts } +// Print a word as HEX print_word: { .label w = 5 lda w+1 @@ -210,6 +212,7 @@ print_word: { jsr print_byte rts } +// Print a byte as HEX print_byte: { txa lsr @@ -226,6 +229,7 @@ print_byte: { jsr print_char rts } +// Print a single char print_char: { ldy #0 sta (print_char_cursor),y @@ -235,6 +239,7 @@ print_char: { !: rts } +// Print a zero-terminated string print_str: { .label str = 5 b1: @@ -257,6 +262,7 @@ print_str: { !: jmp b1 } +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 3 lda #<$400 @@ -279,6 +285,9 @@ print_cls: { bne b1 rts } +// Generate word linear table +// lintab - the table to generate into +// length - the number of points in a total sinus wavelength (the size of the table) lin16u_gen: { .label _5 = 5 .label ampl = 3 @@ -380,6 +389,10 @@ lin16u_gen: { !: rts } +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = $f .label dividend = 3 diff --git a/src/test/ref/linegen.log b/src/test/ref/linegen.log index b2d9da19f..1ccee1410 100644 --- a/src/test/ref/linegen.log +++ b/src/test/ref/linegen.log @@ -2460,6 +2460,7 @@ main: { lintab3: .fill 2*$14, 0 } //SEG163 print_ln +// Print a newline print_ln: { //SEG164 [62] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -2492,6 +2493,7 @@ print_ln: { rts } //SEG171 print_word +// Print a word as HEX print_word: { .label w = 5 //SEG172 [67] (byte) print_byte::b#0 ← > (word) print_word::w#10 -- vbuz1=_hi_vwuz2 @@ -2522,6 +2524,7 @@ print_word: { rts } //SEG185 print_byte +// Print a byte as HEX print_byte: { .label _0 = $24 .label _2 = $25 @@ -2567,6 +2570,7 @@ print_byte: { rts } //SEG201 print_char +// Print a single char print_char: { .label ch = 8 //SEG202 [81] *((byte*) print_char_cursor#50) ← (byte) print_char::ch#2 -- _deref_pbuz1=vbuz2 @@ -2585,6 +2589,7 @@ print_char: { rts } //SEG206 print_str +// Print a zero-terminated string print_str: { .label str = $b //SEG207 [85] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -2625,6 +2630,7 @@ print_str: { jmp b1_from_b2 } //SEG218 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = $d //SEG219 [92] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -2664,6 +2670,9 @@ print_cls: { rts } //SEG229 lin16u_gen +// Generate word linear table +// lintab - the table to generate into +// length - the number of points in a total sinus wavelength (the size of the table) lin16u_gen: { .label _5 = $34 .label ampl = $26 @@ -2840,6 +2849,10 @@ lin16u_gen: { rts } //SEG268 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label _1 = $36 .label _2 = $37 @@ -3578,6 +3591,7 @@ main: { lintab3: .fill 2*$14, 0 } //SEG163 print_ln +// Print a newline print_ln: { //SEG164 [62] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -3610,6 +3624,7 @@ print_ln: { rts } //SEG171 print_word +// Print a word as HEX print_word: { .label w = 5 //SEG172 [67] (byte) print_byte::b#0 ← > (word) print_word::w#10 -- vbuxx=_hi_vwuz1 @@ -3640,6 +3655,7 @@ print_word: { rts } //SEG185 print_byte +// Print a byte as HEX print_byte: { //SEG186 [73] (byte~) print_byte::$0 ← (byte) print_byte::b#3 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -3678,6 +3694,7 @@ print_byte: { rts } //SEG201 print_char +// Print a single char print_char: { //SEG202 [81] *((byte*) print_char_cursor#50) ← (byte) print_char::ch#2 -- _deref_pbuz1=vbuaa ldy #0 @@ -3694,6 +3711,7 @@ print_char: { rts } //SEG206 print_str +// Print a zero-terminated string print_str: { .label str = 5 //SEG207 [85] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -3734,6 +3752,7 @@ print_str: { jmp b1_from_b2 } //SEG218 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 3 //SEG219 [92] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -3773,6 +3792,9 @@ print_cls: { rts } //SEG229 lin16u_gen +// Generate word linear table +// lintab - the table to generate into +// length - the number of points in a total sinus wavelength (the size of the table) lin16u_gen: { .label _5 = 5 .label ampl = 3 @@ -3793,7 +3815,6 @@ lin16u_gen: { sbc min+1 sta ampl+1 //SEG231 [99] (word) divr16u::dividend#1 ← (word) lin16u_gen::ampl#0 - // (word) divr16u::dividend#1 = (word) lin16u_gen::ampl#0 // register copy zp ZP_WORD:3 //SEG232 [100] call divr16u //SEG233 [117] phi from lin16u_gen to divr16u [phi:lin16u_gen->divr16u] divr16u_from_lin16u_gen: @@ -3810,7 +3831,6 @@ lin16u_gen: { sta divr16u.rem+1 jsr divr16u //SEG237 [101] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:17 jmp b3 //SEG238 lin16u_gen::@3 b3: @@ -3820,7 +3840,6 @@ lin16u_gen: { lda divr16u.return+1 sta stepi+1 //SEG240 [103] (word) divr16u::rem#4 ← (word) rem16u#1 - // (word) divr16u::rem#4 = (word) rem16u#1 // register copy zp ZP_WORD:15 //SEG241 [104] call divr16u //SEG242 [117] phi from lin16u_gen::@3 to divr16u [phi:lin16u_gen::@3->divr16u] divr16u_from_b3: @@ -3837,12 +3856,10 @@ lin16u_gen: { //SEG245 [117] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:lin16u_gen::@3->divr16u#2] -- register_copy jsr divr16u //SEG246 [105] (word) divr16u::return#3 ← (word) divr16u::return#0 - // (word) divr16u::return#3 = (word) divr16u::return#0 // register copy zp ZP_WORD:17 jmp b4 //SEG247 lin16u_gen::@4 b4: //SEG248 [106] (word) lin16u_gen::stepf#0 ← (word) divr16u::return#3 - // (word) lin16u_gen::stepf#0 = (word) divr16u::return#3 // register copy zp ZP_WORD:17 //SEG249 [107] (dword) lin16u_gen::step#0 ← (word) lin16u_gen::stepi#0 dw= (word) lin16u_gen::stepf#0 -- vduz1=vwuz2_dword_vwuz3 lda stepi sta step+2 @@ -3934,6 +3951,10 @@ lin16u_gen: { rts } //SEG268 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = $f .label dividend = 3 @@ -4033,7 +4054,6 @@ divr16u: { //SEG301 divr16u::@6 b6: //SEG302 [133] (word) rem16u#1 ← (word) divr16u::rem#11 - // (word) rem16u#1 = (word) divr16u::rem#11 // register copy zp ZP_WORD:15 jmp breturn //SEG303 divr16u::@return breturn: @@ -4174,6 +4194,7 @@ Removing instruction b2_from_b1: Removing instruction b2_from_b4: Removing instruction b3_from_b2: Removing instruction b3_from_b5: +Removing instruction breturn: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction bend: Removing instruction lin16u_gen_from_main: @@ -4232,7 +4253,6 @@ Removing instruction b1_from_divr16u: Removing instruction b4: Removing instruction b5: Removing instruction b6: -Removing instruction breturn: Succesful ASM optimization Pass5UnusedLabelElimination Updating BasicUpstart to call main directly Removing instruction jsr main @@ -4794,6 +4814,7 @@ main: { lintab3: .fill 2*$14, 0 } //SEG163 print_ln +// Print a newline print_ln: { //SEG164 [62] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] //SEG165 [62] phi (byte*) print_line_cursor#11 = (byte*) print_line_cursor#21 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy @@ -4821,6 +4842,7 @@ print_ln: { rts } //SEG171 print_word +// Print a word as HEX print_word: { .label w = 5 //SEG172 [67] (byte) print_byte::b#0 ← > (word) print_word::w#10 -- vbuxx=_hi_vwuz1 @@ -4845,6 +4867,7 @@ print_word: { rts } //SEG185 print_byte +// Print a byte as HEX print_byte: { //SEG186 [73] (byte~) print_byte::$0 ← (byte) print_byte::b#3 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -4877,6 +4900,7 @@ print_byte: { rts } //SEG201 print_char +// Print a single char print_char: { //SEG202 [81] *((byte*) print_char_cursor#50) ← (byte) print_char::ch#2 -- _deref_pbuz1=vbuaa ldy #0 @@ -4891,6 +4915,7 @@ print_char: { rts } //SEG206 print_str +// Print a zero-terminated string print_str: { .label str = 5 //SEG207 [85] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -4925,6 +4950,7 @@ print_str: { jmp b1 } //SEG218 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 3 //SEG219 [92] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -4958,6 +4984,9 @@ print_cls: { rts } //SEG229 lin16u_gen +// Generate word linear table +// lintab - the table to generate into +// length - the number of points in a total sinus wavelength (the size of the table) lin16u_gen: { .label _5 = 5 .label ampl = 3 @@ -4978,7 +5007,6 @@ lin16u_gen: { sbc min+1 sta ampl+1 //SEG231 [99] (word) divr16u::dividend#1 ← (word) lin16u_gen::ampl#0 - // (word) divr16u::dividend#1 = (word) lin16u_gen::ampl#0 // register copy zp ZP_WORD:3 //SEG232 [100] call divr16u //SEG233 [117] phi from lin16u_gen to divr16u [phi:lin16u_gen->divr16u] //SEG234 [117] phi (word) divr16u::divisor#6 = (byte/signed byte/word/signed word/dword/signed dword) 20-(byte/signed byte/word/signed word/dword/signed dword) 1 [phi:lin16u_gen->divr16u#0] -- vwuz1=vbuc1 @@ -4993,7 +5021,6 @@ lin16u_gen: { sta divr16u.rem+1 jsr divr16u //SEG237 [101] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:17 //SEG238 lin16u_gen::@3 //SEG239 [102] (word) lin16u_gen::stepi#0 ← (word) divr16u::return#2 -- vwuz1=vwuz2 lda divr16u.return @@ -5001,7 +5028,6 @@ lin16u_gen: { lda divr16u.return+1 sta stepi+1 //SEG240 [103] (word) divr16u::rem#4 ← (word) rem16u#1 - // (word) divr16u::rem#4 = (word) rem16u#1 // register copy zp ZP_WORD:15 //SEG241 [104] call divr16u //SEG242 [117] phi from lin16u_gen::@3 to divr16u [phi:lin16u_gen::@3->divr16u] //SEG243 [117] phi (word) divr16u::divisor#6 = (byte/signed byte/word/signed word/dword/signed dword) 20-(byte/signed byte/word/signed word/dword/signed dword) 1 [phi:lin16u_gen::@3->divr16u#0] -- vwuz1=vbuc1 @@ -5016,10 +5042,8 @@ lin16u_gen: { //SEG245 [117] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:lin16u_gen::@3->divr16u#2] -- register_copy jsr divr16u //SEG246 [105] (word) divr16u::return#3 ← (word) divr16u::return#0 - // (word) divr16u::return#3 = (word) divr16u::return#0 // register copy zp ZP_WORD:17 //SEG247 lin16u_gen::@4 //SEG248 [106] (word) lin16u_gen::stepf#0 ← (word) divr16u::return#3 - // (word) lin16u_gen::stepf#0 = (word) divr16u::return#3 // register copy zp ZP_WORD:17 //SEG249 [107] (dword) lin16u_gen::step#0 ← (word) lin16u_gen::stepi#0 dw= (word) lin16u_gen::stepf#0 -- vduz1=vwuz2_dword_vwuz3 lda stepi sta step+2 @@ -5103,6 +5127,10 @@ lin16u_gen: { rts } //SEG268 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = $f .label dividend = 3 @@ -5185,7 +5213,6 @@ divr16u: { bne b1 //SEG301 divr16u::@6 //SEG302 [133] (word) rem16u#1 ← (word) divr16u::rem#11 - // (word) rem16u#1 = (word) divr16u::rem#11 // register copy zp ZP_WORD:15 //SEG303 divr16u::@return //SEG304 [134] return rts diff --git a/src/test/ref/liverange.log b/src/test/ref/liverange.log index 9116849bf..838a3b2dc 100644 --- a/src/test/ref/liverange.log +++ b/src/test/ref/liverange.log @@ -408,12 +408,10 @@ main: { ldy #0 jsr inci //SEG13 [6] (byte) inci::return#0 ← (byte) inci::return#2 - // (byte) inci::return#0 = (byte) inci::return#2 // register copy reg byte a jmp b1 //SEG14 main::@1 b1: //SEG15 [7] (byte~) main::$0 ← (byte) inci::return#0 - // (byte~) main::$0 = (byte) inci::return#0 // register copy reg byte a //SEG16 [8] (byte) main::a#1 ← (byte/signed byte/word/signed word/dword/signed dword) 4 + (byte~) main::$0 -- vbuz1=vbuc1_plus_vbuaa clc adc #4 @@ -424,12 +422,10 @@ main: { //SEG19 [16] phi (byte) i#10 = (byte) i#11 [phi:main::@1->inci#0] -- register_copy jsr inci //SEG20 [10] (byte) inci::return#1 ← (byte) inci::return#2 - // (byte) inci::return#1 = (byte) inci::return#2 // register copy reg byte a jmp b2 //SEG21 main::@2 b2: //SEG22 [11] (byte~) main::$2 ← (byte) inci::return#1 - // (byte~) main::$2 = (byte) inci::return#1 // register copy reg byte a //SEG23 [12] (byte) main::a#2 ← (byte) main::a#1 + (byte~) main::$2 -- vbuxx=vbuz1_plus_vbuaa clc adc a @@ -547,10 +543,8 @@ main: { ldy #0 jsr inci //SEG13 [6] (byte) inci::return#0 ← (byte) inci::return#2 - // (byte) inci::return#0 = (byte) inci::return#2 // register copy reg byte a //SEG14 main::@1 //SEG15 [7] (byte~) main::$0 ← (byte) inci::return#0 - // (byte~) main::$0 = (byte) inci::return#0 // register copy reg byte a //SEG16 [8] (byte) main::a#1 ← (byte/signed byte/word/signed word/dword/signed dword) 4 + (byte~) main::$0 -- vbuz1=vbuc1_plus_vbuaa clc adc #4 @@ -560,10 +554,8 @@ main: { //SEG19 [16] phi (byte) i#10 = (byte) i#11 [phi:main::@1->inci#0] -- register_copy jsr inci //SEG20 [10] (byte) inci::return#1 ← (byte) inci::return#2 - // (byte) inci::return#1 = (byte) inci::return#2 // register copy reg byte a //SEG21 main::@2 //SEG22 [11] (byte~) main::$2 ← (byte) inci::return#1 - // (byte~) main::$2 = (byte) inci::return#1 // register copy reg byte a //SEG23 [12] (byte) main::a#2 ← (byte) main::a#1 + (byte~) main::$2 -- vbuxx=vbuz1_plus_vbuaa clc adc a diff --git a/src/test/ref/local-string.asm b/src/test/ref/local-string.asm index 36c5664d6..9a9795840 100644 --- a/src/test/ref/local-string.asm +++ b/src/test/ref/local-string.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Local constant strings are placed at the start of the method. This means the generated ASM jumps / calls straignt into the constant string main: { .label screen = $400 ldx #0 diff --git a/src/test/ref/local-string.log b/src/test/ref/local-string.log index 3b8899622..13ab5d4d4 100644 --- a/src/test/ref/local-string.log +++ b/src/test/ref/local-string.log @@ -149,6 +149,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Local constant strings are placed at the start of the method. This means the generated ASM jumps / calls straignt into the constant string main: { .label screen = $400 .label i = 2 @@ -223,6 +224,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Local constant strings are placed at the start of the method. This means the generated ASM jumps / calls straignt into the constant string main: { .label screen = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] @@ -312,6 +314,7 @@ Score: 261 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Local constant strings are placed at the start of the method. This means the generated ASM jumps / calls straignt into the constant string main: { .label screen = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] diff --git a/src/test/ref/longjump.asm b/src/test/ref/longjump.asm index a68d06cde..269d6ea76 100644 --- a/src/test/ref/longjump.asm +++ b/src/test/ref/longjump.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Minimal example program generating a long jump main: { .label SCREEN = $400 ldx #0 diff --git a/src/test/ref/longjump.log b/src/test/ref/longjump.log index 90f43feb0..3f5a2e728 100644 --- a/src/test/ref/longjump.log +++ b/src/test/ref/longjump.log @@ -136,6 +136,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Minimal example program generating a long jump main: { .label SCREEN = $400 .label i = 2 @@ -458,6 +459,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Minimal example program generating a long jump main: { .label SCREEN = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] @@ -767,7 +769,7 @@ Removing instruction jmp b1 Succesful ASM optimization Pass5NextJumpElimination Removing instruction bbegin: Succesful ASM optimization Pass5UnusedLabelElimination -Fixing long branch [267] bne b1 to beq +Fixing long branch [268] bne b1 to beq FINAL SYMBOL TABLE (label) @1 @@ -801,6 +803,7 @@ Score: 5311 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Minimal example program generating a long jump main: { .label SCREEN = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] diff --git a/src/test/ref/longjump2.asm b/src/test/ref/longjump2.asm index 0d77575b9..47a6f9137 100644 --- a/src/test/ref/longjump2.asm +++ b/src/test/ref/longjump2.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Minimal example program generating two long jumps main: { jsr long1 jsr long2 diff --git a/src/test/ref/longjump2.log b/src/test/ref/longjump2.log index 6e6a06416..cd1d37d80 100644 --- a/src/test/ref/longjump2.log +++ b/src/test/ref/longjump2.log @@ -231,6 +231,7 @@ bend_from_b3: //SEG8 @end bend: //SEG9 main +// Minimal example program generating two long jumps main: { //SEG10 [5] call long1 //SEG11 [16] phi from main to long1 [phi:main->long1] @@ -868,6 +869,7 @@ bend_from_b3: //SEG8 @end bend: //SEG9 main +// Minimal example program generating two long jumps main: { //SEG10 [5] call long1 //SEG11 [16] phi from main to long1 [phi:main->long1] @@ -1497,8 +1499,8 @@ Removing instruction jmp b1 Succesful ASM optimization Pass5NextJumpElimination Removing instruction bbegin: Succesful ASM optimization Pass5UnusedLabelElimination -Fixing long branch [272] bne b1 to beq -Fixing long branch [541] bne b1 to beq +Fixing long branch [273] bne b1 to beq +Fixing long branch [542] bne b1 to beq FINAL SYMBOL TABLE (label) @3 @@ -1544,6 +1546,7 @@ Score: 10640 //SEG7 [3] phi from @3 to @end [phi:@3->@end] //SEG8 @end //SEG9 main +// Minimal example program generating two long jumps main: { //SEG10 [5] call long1 //SEG11 [16] phi from main to long1 [phi:main->long1] diff --git a/src/test/ref/loopnest3.log b/src/test/ref/loopnest3.log index eac74c7c3..185299b56 100644 --- a/src/test/ref/loopnest3.log +++ b/src/test/ref/loopnest3.log @@ -382,7 +382,6 @@ main: { //SEG14 main::@1 b1: //SEG15 [6] (byte) b::i#0 ← (byte) main::i#2 - // (byte) b::i#0 = (byte) main::i#2 // register copy reg byte y //SEG16 [7] call b jsr b jmp b3 @@ -535,7 +534,6 @@ main: { //SEG14 main::@1 b1: //SEG15 [6] (byte) b::i#0 ← (byte) main::i#2 - // (byte) b::i#0 = (byte) main::i#2 // register copy reg byte y //SEG16 [7] call b jsr b //SEG17 main::@3 diff --git a/src/test/ref/min-fmul-16.asm b/src/test/ref/min-fmul-16.asm index 7a3306941..e5cb7f6ec 100644 --- a/src/test/ref/min-fmul-16.asm +++ b/src/test/ref/min-fmul-16.asm @@ -30,9 +30,11 @@ main: { sta print_char_cursor+1 jmp b4 } +// Set the screen to print on. Also resets current line/char cursor. print_set_screen: { rts } +// Print a dword as HEX print_dword: { .label dw = 9 lda dw+2 @@ -47,6 +49,7 @@ print_dword: { jsr print_word rts } +// Print a word as HEX print_word: { .label w = 2 lda w+1 @@ -57,6 +60,7 @@ print_word: { jsr print_byte rts } +// Print a byte as HEX print_byte: { txa lsr @@ -73,6 +77,7 @@ print_byte: { jsr print_char rts } +// Print a single char print_char: { ldy #0 sta (print_char_cursor),y @@ -82,6 +87,8 @@ print_char: { !: rts } +// Fast multiply two unsigned words to a double word result +// Done in assembler to utilize fast addition A+X mulf16u: { .label memA = $f8 .label memB = $fa @@ -197,6 +204,7 @@ mulf16u: { sta return+3 rts } +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label sqr1_hi = 4 .label sqr = 7 diff --git a/src/test/ref/min-fmul-16.log b/src/test/ref/min-fmul-16.log index e3287ed4a..e7f76ac72 100644 --- a/src/test/ref/min-fmul-16.log +++ b/src/test/ref/min-fmul-16.log @@ -1450,6 +1450,7 @@ main: { jmp b1 } //SEG34 print_set_screen +// Set the screen to print on. Also resets current line/char cursor. print_set_screen: { jmp breturn //SEG35 print_set_screen::@return @@ -1458,6 +1459,7 @@ print_set_screen: { rts } //SEG37 print_dword +// Print a dword as HEX print_dword: { .label dw = $1e //SEG38 [20] (word) print_word::w#0 ← > (dword) print_dword::dw#0 -- vwuz1=_hi_vduz2 @@ -1492,6 +1494,7 @@ print_dword: { rts } //SEG51 print_word +// Print a word as HEX print_word: { .label w = 2 //SEG52 [26] (byte) print_byte::b#0 ← > (word) print_word::w#2 -- vbuz1=_hi_vwuz2 @@ -1522,6 +1525,7 @@ print_word: { rts } //SEG65 print_byte +// Print a byte as HEX print_byte: { .label _0 = $22 .label _2 = $23 @@ -1567,6 +1571,7 @@ print_byte: { rts } //SEG81 print_char +// Print a single char print_char: { .label ch = 5 //SEG82 [40] *((byte*) print_char_cursor#27) ← (byte) print_char::ch#2 -- _deref_pbuz1=vbuz2 @@ -1585,6 +1590,8 @@ print_char: { rts } //SEG86 mulf16u +// Fast multiply two unsigned words to a double word result +// Done in assembler to utilize fast addition A+X mulf16u: { .label memA = $f8 .label memB = $fa @@ -1710,6 +1717,7 @@ mulf16u: { rts } //SEG93 mulf_init +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label _2 = $28 .label _5 = $29 @@ -2125,16 +2133,13 @@ main: { //SEG21 [10] call mulf16u jsr mulf16u //SEG22 [11] (dword) mulf16u::return#0 ← (dword) mulf16u::return#1 - // (dword) mulf16u::return#0 = (dword) mulf16u::return#1 // register copy zp ZP_DWORD:9 jmp b14 //SEG23 main::@14 b14: //SEG24 [12] (dword) main::r#0 ← (dword) mulf16u::return#0 - // (dword) main::r#0 = (dword) mulf16u::return#0 // register copy zp ZP_DWORD:9 //SEG25 [13] *((const byte*) BORDERCOL#0) ← -- *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_dec__deref_pbuc1 dec BORDERCOL //SEG26 [14] (dword) print_dword::dw#0 ← (dword) main::r#0 - // (dword) print_dword::dw#0 = (dword) main::r#0 // register copy zp ZP_DWORD:9 //SEG27 [15] call print_dword jsr print_dword //SEG28 [16] phi from main::@14 to main::@15 [phi:main::@14->main::@15] @@ -2156,6 +2161,7 @@ main: { jmp b1 } //SEG34 print_set_screen +// Set the screen to print on. Also resets current line/char cursor. print_set_screen: { jmp breturn //SEG35 print_set_screen::@return @@ -2164,6 +2170,7 @@ print_set_screen: { rts } //SEG37 print_dword +// Print a dword as HEX print_dword: { .label dw = 9 //SEG38 [20] (word) print_word::w#0 ← > (dword) print_dword::dw#0 -- vwuz1=_hi_vduz2 @@ -2198,6 +2205,7 @@ print_dword: { rts } //SEG51 print_word +// Print a word as HEX print_word: { .label w = 2 //SEG52 [26] (byte) print_byte::b#0 ← > (word) print_word::w#2 -- vbuxx=_hi_vwuz1 @@ -2228,6 +2236,7 @@ print_word: { rts } //SEG65 print_byte +// Print a byte as HEX print_byte: { //SEG66 [32] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -2266,6 +2275,7 @@ print_byte: { rts } //SEG81 print_char +// Print a single char print_char: { //SEG82 [40] *((byte*) print_char_cursor#27) ← (byte) print_char::ch#2 -- _deref_pbuz1=vbuaa ldy #0 @@ -2282,6 +2292,8 @@ print_char: { rts } //SEG86 mulf16u +// Fast multiply two unsigned words to a double word result +// Done in assembler to utilize fast addition A+X mulf16u: { .label memA = $f8 .label memB = $fa @@ -2406,6 +2418,7 @@ mulf16u: { rts } //SEG93 mulf_init +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label sqr1_hi = 4 .label sqr = 7 @@ -2899,14 +2912,11 @@ main: { //SEG21 [10] call mulf16u jsr mulf16u //SEG22 [11] (dword) mulf16u::return#0 ← (dword) mulf16u::return#1 - // (dword) mulf16u::return#0 = (dword) mulf16u::return#1 // register copy zp ZP_DWORD:9 //SEG23 main::@14 //SEG24 [12] (dword) main::r#0 ← (dword) mulf16u::return#0 - // (dword) main::r#0 = (dword) mulf16u::return#0 // register copy zp ZP_DWORD:9 //SEG25 [13] *((const byte*) BORDERCOL#0) ← -- *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_dec__deref_pbuc1 dec BORDERCOL //SEG26 [14] (dword) print_dword::dw#0 ← (dword) main::r#0 - // (dword) print_dword::dw#0 = (dword) main::r#0 // register copy zp ZP_DWORD:9 //SEG27 [15] call print_dword jsr print_dword //SEG28 [16] phi from main::@14 to main::@15 [phi:main::@14->main::@15] @@ -2923,12 +2933,14 @@ main: { jmp b4 } //SEG34 print_set_screen +// Set the screen to print on. Also resets current line/char cursor. print_set_screen: { //SEG35 print_set_screen::@return //SEG36 [19] return rts } //SEG37 print_dword +// Print a dword as HEX print_dword: { .label dw = 9 //SEG38 [20] (word) print_word::w#0 ← > (dword) print_dword::dw#0 -- vwuz1=_hi_vduz2 @@ -2957,6 +2969,7 @@ print_dword: { rts } //SEG51 print_word +// Print a word as HEX print_word: { .label w = 2 //SEG52 [26] (byte) print_byte::b#0 ← > (word) print_word::w#2 -- vbuxx=_hi_vwuz1 @@ -2981,6 +2994,7 @@ print_word: { rts } //SEG65 print_byte +// Print a byte as HEX print_byte: { //SEG66 [32] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -3013,6 +3027,7 @@ print_byte: { rts } //SEG81 print_char +// Print a single char print_char: { //SEG82 [40] *((byte*) print_char_cursor#27) ← (byte) print_char::ch#2 -- _deref_pbuz1=vbuaa ldy #0 @@ -3027,6 +3042,8 @@ print_char: { rts } //SEG86 mulf16u +// Fast multiply two unsigned words to a double word result +// Done in assembler to utilize fast addition A+X mulf16u: { .label memA = $f8 .label memB = $fa @@ -3149,6 +3166,7 @@ mulf16u: { rts } //SEG93 mulf_init +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label sqr1_hi = 4 .label sqr = 7 diff --git a/src/test/ref/modglobal.log b/src/test/ref/modglobal.log index 6586444fd..0d3420bef 100644 --- a/src/test/ref/modglobal.log +++ b/src/test/ref/modglobal.log @@ -487,12 +487,10 @@ main: { lda #0 jsr inccnt //SEG15 [6] (byte) inccnt::return#0 ← (byte) inccnt::return#2 - // (byte) inccnt::return#0 = (byte) inccnt::return#2 // register copy reg byte a jmp b1 //SEG16 main::@1 b1: //SEG17 [7] (byte~) main::$0 ← (byte) inccnt::return#0 - // (byte~) main::$0 = (byte) inccnt::return#0 // register copy reg byte a //SEG18 [8] *((const byte[256]) SCREEN#0) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa sta SCREEN //SEG19 [9] (byte) cnt#2 ← ++ (byte) cnt#12 -- vbuaa=_inc_vbuz1 @@ -507,12 +505,10 @@ main: { //SEG24 [15] phi (byte) cnt#11 = (byte) cnt#2 [phi:main::@1->inccnt#2] -- register_copy jsr inccnt //SEG25 [11] (byte) inccnt::return#1 ← (byte) inccnt::return#2 - // (byte) inccnt::return#1 = (byte) inccnt::return#2 // register copy reg byte a jmp b2 //SEG26 main::@2 b2: //SEG27 [12] (byte~) main::$1 ← (byte) inccnt::return#1 - // (byte~) main::$1 = (byte) inccnt::return#1 // register copy reg byte a //SEG28 [13] *((const byte[256]) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte~) main::$1 -- _deref_pbuc1=vbuaa sta SCREEN+1 jmp breturn @@ -639,10 +635,8 @@ main: { txa jsr inccnt //SEG15 [6] (byte) inccnt::return#0 ← (byte) inccnt::return#2 - // (byte) inccnt::return#0 = (byte) inccnt::return#2 // register copy reg byte a //SEG16 main::@1 //SEG17 [7] (byte~) main::$0 ← (byte) inccnt::return#0 - // (byte~) main::$0 = (byte) inccnt::return#0 // register copy reg byte a //SEG18 [8] *((const byte[256]) SCREEN#0) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa sta SCREEN //SEG19 [9] (byte) cnt#2 ← ++ (byte) cnt#12 -- vbuaa=_inc_vbuz1 @@ -656,10 +650,8 @@ main: { //SEG24 [15] phi (byte) cnt#11 = (byte) cnt#2 [phi:main::@1->inccnt#2] -- register_copy jsr inccnt //SEG25 [11] (byte) inccnt::return#1 ← (byte) inccnt::return#2 - // (byte) inccnt::return#1 = (byte) inccnt::return#2 // register copy reg byte a //SEG26 main::@2 //SEG27 [12] (byte~) main::$1 ← (byte) inccnt::return#1 - // (byte~) main::$1 = (byte) inccnt::return#1 // register copy reg byte a //SEG28 [13] *((const byte[256]) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte~) main::$1 -- _deref_pbuc1=vbuaa sta SCREEN+1 //SEG29 main::@return diff --git a/src/test/ref/norom-charset.asm b/src/test/ref/norom-charset.asm index b41b38c12..e2003a9b3 100644 --- a/src/test/ref/norom-charset.asm +++ b/src/test/ref/norom-charset.asm @@ -37,6 +37,8 @@ main: { sta VIC_MEMORY rts } +// Generate one 5x3 character from a 16-bit char spec +// The 5x3 char is stored as 5x 3-bit rows followed by a zero. %aaabbbcc cdddeee0 gen_char3: { .label dst = 2 .label spec = 6 diff --git a/src/test/ref/norom-charset.log b/src/test/ref/norom-charset.log index 5d8a42beb..574634211 100644 --- a/src/test/ref/norom-charset.log +++ b/src/test/ref/norom-charset.log @@ -589,6 +589,8 @@ main: { rts } //SEG29 gen_char3 +// Generate one 5x3 character from a 16-bit char spec +// The 5x3 char is stored as 5x 3-bit rows followed by a zero. %aaabbbcc cdddeee0 gen_char3: { .label _0 = $c .label _1 = $d @@ -780,7 +782,6 @@ main: { //SEG16 main::@1 b1: //SEG17 [6] (byte*) gen_char3::dst#0 ← (byte*) main::charset#2 - // (byte*) gen_char3::dst#0 = (byte*) main::charset#2 // register copy zp ZP_WORD:2 //SEG18 [7] (word) gen_char3::spec#0 ← *((const word[]) charset_spec_row#0 + (byte) main::c#2) -- vwuz1=pwuc1_derefidx_vbuz2 ldy c lda charset_spec_row,y @@ -824,6 +825,8 @@ main: { rts } //SEG29 gen_char3 +// Generate one 5x3 character from a 16-bit char spec +// The 5x3 char is stored as 5x 3-bit rows followed by a zero. %aaabbbcc cdddeee0 gen_char3: { .label dst = 2 .label spec = 6 @@ -1062,7 +1065,6 @@ main: { //SEG16 main::@1 b1: //SEG17 [6] (byte*) gen_char3::dst#0 ← (byte*) main::charset#2 - // (byte*) gen_char3::dst#0 = (byte*) main::charset#2 // register copy zp ZP_WORD:2 //SEG18 [7] (word) gen_char3::spec#0 ← *((const word[]) charset_spec_row#0 + (byte) main::c#2) -- vwuz1=pwuc1_derefidx_vbuz2 ldy c lda charset_spec_row,y @@ -1098,6 +1100,8 @@ main: { rts } //SEG29 gen_char3 +// Generate one 5x3 character from a 16-bit char spec +// The 5x3 char is stored as 5x 3-bit rows followed by a zero. %aaabbbcc cdddeee0 gen_char3: { .label dst = 2 .label spec = 6 diff --git a/src/test/ref/overlap-allocation-2.log b/src/test/ref/overlap-allocation-2.log index 983068ca7..73e6a7b51 100644 --- a/src/test/ref/overlap-allocation-2.log +++ b/src/test/ref/overlap-allocation-2.log @@ -479,7 +479,6 @@ main: { //SEG14 main::@1 b1: //SEG15 [6] (byte) line::l#0 ← (byte) main::i#2 - // (byte) line::l#0 = (byte) main::i#2 // register copy reg byte x //SEG16 [7] call line //SEG17 [16] phi from main::@1 to line [phi:main::@1->line] line_from_b1: @@ -505,7 +504,6 @@ main: { //SEG26 main::@2 b2: //SEG27 [11] (byte) line::l#1 ← (byte) main::j#2 - // (byte) line::l#1 = (byte) main::j#2 // register copy reg byte x //SEG28 [12] call line //SEG29 [16] phi from main::@2 to line [phi:main::@2->line] line_from_b2: @@ -584,14 +582,14 @@ Removing instruction b3: Removing instruction main_from_b3: Removing instruction bend_from_b3: Removing instruction b1_from_b5: +Removing instruction line_from_b1: Removing instruction b2_from_b6: +Removing instruction line_from_b2: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction bend: Removing instruction b1_from_main: -Removing instruction line_from_b1: Removing instruction b5: Removing instruction b2_from_b5: -Removing instruction line_from_b2: Removing instruction b6: Removing instruction breturn: Removing instruction plot_from_line: @@ -673,7 +671,6 @@ main: { //SEG14 main::@1 b1: //SEG15 [6] (byte) line::l#0 ← (byte) main::i#2 - // (byte) line::l#0 = (byte) main::i#2 // register copy reg byte x //SEG16 [7] call line //SEG17 [16] phi from main::@1 to line [phi:main::@1->line] //SEG18 [16] phi (byte) line::l#2 = (byte) line::l#0 [phi:main::@1->line#0] -- register_copy @@ -692,7 +689,6 @@ main: { //SEG26 main::@2 b2: //SEG27 [11] (byte) line::l#1 ← (byte) main::j#2 - // (byte) line::l#1 = (byte) main::j#2 // register copy reg byte x //SEG28 [12] call line //SEG29 [16] phi from main::@2 to line [phi:main::@2->line] //SEG30 [16] phi (byte) line::l#2 = (byte) line::l#1 [phi:main::@2->line#0] -- register_copy diff --git a/src/test/ref/overlap-allocation.log b/src/test/ref/overlap-allocation.log index d72030787..79f901a51 100644 --- a/src/test/ref/overlap-allocation.log +++ b/src/test/ref/overlap-allocation.log @@ -478,7 +478,6 @@ main: { //SEG14 main::@1 b1: //SEG15 [6] (byte) plot::x#0 ← (byte) main::i#2 - // (byte) plot::x#0 = (byte) main::i#2 // register copy reg byte x //SEG16 [7] call plot //SEG17 [21] phi from main::@1 to plot [phi:main::@1->plot] plot_from_b1: @@ -504,7 +503,6 @@ main: { //SEG26 main::@2 b2: //SEG27 [11] (byte) plot::x#1 ← (byte) main::j#2 - // (byte) plot::x#1 = (byte) main::j#2 // register copy reg byte x //SEG28 [12] call plot //SEG29 [21] phi from main::@2 to plot [phi:main::@2->plot] plot_from_b2: @@ -530,7 +528,6 @@ main: { //SEG38 main::@3 b3: //SEG39 [16] (byte) plot::x#2 ← (byte) main::k#2 - // (byte) plot::x#2 = (byte) main::k#2 // register copy reg byte x //SEG40 [17] call plot //SEG41 [21] phi from main::@3 to plot [phi:main::@3->plot] plot_from_b3: @@ -582,18 +579,18 @@ Removing instruction b2: Removing instruction main_from_b2: Removing instruction bend_from_b2: Removing instruction b1_from_b7: +Removing instruction plot_from_b1: Removing instruction b2_from_b8: +Removing instruction plot_from_b2: Removing instruction b3_from_b9: +Removing instruction plot_from_b3: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction bend: Removing instruction b1_from_main: -Removing instruction plot_from_b1: Removing instruction b7: Removing instruction b2_from_b7: -Removing instruction plot_from_b2: Removing instruction b8: Removing instruction b3_from_b8: -Removing instruction plot_from_b3: Removing instruction b9: Removing instruction breturn: Removing instruction breturn: @@ -671,7 +668,6 @@ main: { //SEG14 main::@1 b1: //SEG15 [6] (byte) plot::x#0 ← (byte) main::i#2 - // (byte) plot::x#0 = (byte) main::i#2 // register copy reg byte x //SEG16 [7] call plot //SEG17 [21] phi from main::@1 to plot [phi:main::@1->plot] //SEG18 [21] phi (byte) plot::x#3 = (byte) plot::x#0 [phi:main::@1->plot#0] -- register_copy @@ -690,7 +686,6 @@ main: { //SEG26 main::@2 b2: //SEG27 [11] (byte) plot::x#1 ← (byte) main::j#2 - // (byte) plot::x#1 = (byte) main::j#2 // register copy reg byte x //SEG28 [12] call plot //SEG29 [21] phi from main::@2 to plot [phi:main::@2->plot] //SEG30 [21] phi (byte) plot::x#3 = (byte) plot::x#1 [phi:main::@2->plot#0] -- register_copy @@ -709,7 +704,6 @@ main: { //SEG38 main::@3 b3: //SEG39 [16] (byte) plot::x#2 ← (byte) main::k#2 - // (byte) plot::x#2 = (byte) main::k#2 // register copy reg byte x //SEG40 [17] call plot //SEG41 [21] phi from main::@3 to plot [phi:main::@3->plot] //SEG42 [21] phi (byte) plot::x#3 = (byte) plot::x#2 [phi:main::@3->plot#0] -- register_copy diff --git a/src/test/ref/printmsg.asm b/src/test/ref/printmsg.asm index b35ad3bf5..0fe609930 100644 --- a/src/test/ref/printmsg.asm +++ b/src/test/ref/printmsg.asm @@ -40,6 +40,7 @@ main: { jsr print_ln rts } +// Print a newline print_ln: { b1: lda print_line_cursor @@ -59,6 +60,7 @@ print_ln: { !: rts } +// Print a zero-terminated string print_str: { .label str = 4 b1: diff --git a/src/test/ref/printmsg.log b/src/test/ref/printmsg.log index bdd8a2e8b..26694e8d7 100644 --- a/src/test/ref/printmsg.log +++ b/src/test/ref/printmsg.log @@ -555,6 +555,7 @@ main: { rts } //SEG43 print_ln +// Print a newline print_ln: { //SEG44 [18] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -587,6 +588,7 @@ print_ln: { rts } //SEG51 print_str +// Print a zero-terminated string print_str: { .label str = 4 //SEG52 [23] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -769,6 +771,7 @@ main: { rts } //SEG43 print_ln +// Print a newline print_ln: { //SEG44 [18] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -801,6 +804,7 @@ print_ln: { rts } //SEG51 print_str +// Print a zero-terminated string print_str: { .label str = 4 //SEG52 [23] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -1032,6 +1036,7 @@ main: { rts } //SEG43 print_ln +// Print a newline print_ln: { //SEG44 [18] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] //SEG45 [18] phi (byte*) print_line_cursor#8 = (byte*) print_line_cursor#16 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy @@ -1059,6 +1064,7 @@ print_ln: { rts } //SEG51 print_str +// Print a zero-terminated string print_str: { .label str = 4 //SEG52 [23] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] diff --git a/src/test/ref/ptr-complex.asm b/src/test/ref/ptr-complex.asm index 5894f4bc2..6a8c62ccc 100644 --- a/src/test/ref/ptr-complex.asm +++ b/src/test/ref/ptr-complex.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Test some complex pointers main: { .label screen = $400 .label BGCOL = $d020 diff --git a/src/test/ref/ptr-complex.log b/src/test/ref/ptr-complex.log index 02bedb667..ed386e13b 100644 --- a/src/test/ref/ptr-complex.log +++ b/src/test/ref/ptr-complex.log @@ -296,6 +296,7 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Test some complex pointers main: { .label screen = $400 .label BGCOL = $d020 @@ -461,6 +462,7 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Test some complex pointers main: { .label screen = $400 .label BGCOL = $d020 @@ -645,6 +647,7 @@ Score: 954 //SEG6 [3] phi from @1 to @end [phi:@1->@end] //SEG7 @end //SEG8 main +// Test some complex pointers main: { .label screen = $400 .label BGCOL = $d020 diff --git a/src/test/ref/ptrtest.asm b/src/test/ref/ptrtest.asm index e77e0906d..31364eaa6 100644 --- a/src/test/ref/ptrtest.asm +++ b/src/test/ref/ptrtest.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Test all types of pointers main: { jsr lvalue jsr rvalue diff --git a/src/test/ref/ptrtest.log b/src/test/ref/ptrtest.log index 99bec0958..6145c4f40 100644 --- a/src/test/ref/ptrtest.log +++ b/src/test/ref/ptrtest.log @@ -443,6 +443,7 @@ bend_from_b5: //SEG8 @end bend: //SEG9 main +// Test all types of pointers main: { //SEG10 [5] call lvalue jsr lvalue @@ -721,6 +722,7 @@ bend_from_b5: //SEG8 @end bend: //SEG9 main +// Test all types of pointers main: { //SEG10 [5] call lvalue jsr lvalue @@ -1043,6 +1045,7 @@ Score: 1274 //SEG7 [3] phi from @5 to @end [phi:@5->@end] //SEG8 @end //SEG9 main +// Test all types of pointers main: { //SEG10 [5] call lvalue jsr lvalue diff --git a/src/test/ref/ptrtestmin.asm b/src/test/ref/ptrtestmin.asm index 6a471ee84..cc37a6dd7 100644 --- a/src/test/ref/ptrtestmin.asm +++ b/src/test/ref/ptrtestmin.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Test all types of pointers main: { .label SCREEN = $400 ldx #2 diff --git a/src/test/ref/ptrtestmin.log b/src/test/ref/ptrtestmin.log index 65a8302a8..727477498 100644 --- a/src/test/ref/ptrtestmin.log +++ b/src/test/ref/ptrtestmin.log @@ -140,6 +140,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Test all types of pointers main: { .label SCREEN = $400 .label b = 3 @@ -209,6 +210,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Test all types of pointers main: { .label SCREEN = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] @@ -296,6 +298,7 @@ Score: 166 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Test all types of pointers main: { .label SCREEN = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] diff --git a/src/test/ref/roll-sprite-msb.log b/src/test/ref/roll-sprite-msb.log index 6fffba113..b4b337be2 100644 --- a/src/test/ref/roll-sprite-msb.log +++ b/src/test/ref/roll-sprite-msb.log @@ -916,7 +916,6 @@ main: { //SEG17 [6] (byte) position_sprite::spriteno#0 ← (byte) main::s#2 -- vbuz1=vbuxx stx position_sprite.spriteno //SEG18 [7] (word) position_sprite::x#0 ← (word) main::xpos#2 - // (word) position_sprite::x#0 = (word) main::xpos#2 // register copy zp ZP_WORD:2 //SEG19 [8] call position_sprite jsr position_sprite jmp b3 @@ -1201,7 +1200,6 @@ main: { //SEG17 [6] (byte) position_sprite::spriteno#0 ← (byte) main::s#2 -- vbuz1=vbuxx stx position_sprite.spriteno //SEG18 [7] (word) position_sprite::x#0 ← (word) main::xpos#2 - // (word) position_sprite::x#0 = (word) main::xpos#2 // register copy zp ZP_WORD:2 //SEG19 [8] call position_sprite jsr position_sprite //SEG20 main::@3 diff --git a/src/test/ref/roll-variable.asm b/src/test/ref/roll-variable.asm index b24e6f7d9..0a3ed83b9 100644 --- a/src/test/ref/roll-variable.asm +++ b/src/test/ref/roll-variable.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Rolling constants by a variable amount main: { .label screen = $400 .label b = 2 diff --git a/src/test/ref/roll-variable.log b/src/test/ref/roll-variable.log index 4377c8494..08ff18667 100644 --- a/src/test/ref/roll-variable.log +++ b/src/test/ref/roll-variable.log @@ -141,6 +141,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Rolling constants by a variable amount main: { .label screen = $400 .label _0 = 3 @@ -224,6 +225,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Rolling constants by a variable amount main: { .label screen = $400 .label b = 2 @@ -324,6 +326,7 @@ Score: 421 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Rolling constants by a variable amount main: { .label screen = $400 .label b = 2 diff --git a/src/test/ref/scan-desire-problem.asm b/src/test/ref/scan-desire-problem.asm index a1c31898e..15d2e4d78 100644 --- a/src/test/ref/scan-desire-problem.asm +++ b/src/test/ref/scan-desire-problem.asm @@ -163,6 +163,8 @@ draw_block: { sta colors+$29 rts } +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .const b = $28 .label mb = 6 @@ -229,6 +231,8 @@ init: { sta BGCOL4 rts } +// Simple routines for working with memory +// Fill some memory with a value fill: { .label end = 6 .label addr = 4 diff --git a/src/test/ref/scan-desire-problem.log b/src/test/ref/scan-desire-problem.log index 3ba17cd48..68ce748a4 100644 --- a/src/test/ref/scan-desire-problem.log +++ b/src/test/ref/scan-desire-problem.log @@ -1964,6 +1964,8 @@ draw_block: { rts } //SEG59 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .const b = $28 .label _1 = $1d @@ -2111,6 +2113,8 @@ init: { rts } //SEG108 fill +// Simple routines for working with memory +// Fill some memory with a value fill: { .label end = $1e .label addr = $a @@ -2402,7 +2406,6 @@ main: { tay lda level_address,y //SEG24 [10] (byte) draw_block::tileno#0 ← (byte) main::tile#0 - // (byte) draw_block::tileno#0 = (byte) main::tile#0 // register copy reg byte a //SEG25 [11] (byte) draw_block::x#0 ← (byte) main::x#4 -- vbuyy=vbuz1 ldy x //SEG26 [12] (byte) draw_block::y#0 ← (byte) main::y#2 -- vbuxx=vbuz1 @@ -2462,12 +2465,10 @@ draw_block: { mul8u_from_draw_block: jsr mul8u //SEG44 [25] (word) mul8u::return#2 ← (word) mul8u::res#2 - // (word) mul8u::return#2 = (word) mul8u::res#2 // register copy zp ZP_WORD:4 jmp b1 //SEG45 draw_block::@1 b1: //SEG46 [26] (word) draw_block::z#0 ← (word) mul8u::return#2 - // (word) draw_block::z#0 = (word) mul8u::return#2 // register copy zp ZP_WORD:4 //SEG47 [27] (word) draw_block::z#1 ← (word) draw_block::z#0 + (word) draw_block::x1#0 -- vwuz1=vwuz2_plus_vwuz1 lda z_1 clc @@ -2576,6 +2577,8 @@ draw_block: { rts } //SEG59 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .const b = $28 .label mb = 6 @@ -2718,6 +2721,8 @@ init: { rts } //SEG108 fill +// Simple routines for working with memory +// Fill some memory with a value fill: { .label end = 6 .label addr = 4 @@ -3235,7 +3240,6 @@ main: { tay lda level_address,y //SEG24 [10] (byte) draw_block::tileno#0 ← (byte) main::tile#0 - // (byte) draw_block::tileno#0 = (byte) main::tile#0 // register copy reg byte a //SEG25 [11] (byte) draw_block::x#0 ← (byte) main::x#4 -- vbuyy=vbuz1 ldy x //SEG26 [12] (byte) draw_block::y#0 ← (byte) main::y#2 -- vbuxx=vbuz1 @@ -3287,10 +3291,8 @@ draw_block: { //SEG43 [38] phi from draw_block to mul8u [phi:draw_block->mul8u] jsr mul8u //SEG44 [25] (word) mul8u::return#2 ← (word) mul8u::res#2 - // (word) mul8u::return#2 = (word) mul8u::res#2 // register copy zp ZP_WORD:4 //SEG45 draw_block::@1 //SEG46 [26] (word) draw_block::z#0 ← (word) mul8u::return#2 - // (word) draw_block::z#0 = (word) mul8u::return#2 // register copy zp ZP_WORD:4 //SEG47 [27] (word) draw_block::z#1 ← (word) draw_block::z#0 + (word) draw_block::x1#0 -- vwuz1=vwuz2_plus_vwuz1 lda z_1 clc @@ -3397,6 +3399,8 @@ draw_block: { rts } //SEG59 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .const b = $28 .label mb = 6 @@ -3512,6 +3516,8 @@ init: { rts } //SEG108 fill +// Simple routines for working with memory +// Fill some memory with a value fill: { .label end = 6 .label addr = 4 diff --git a/src/test/ref/signed-words.asm b/src/test/ref/signed-words.asm index e97d5d163..bad668419 100644 --- a/src/test/ref/signed-words.asm +++ b/src/test/ref/signed-words.asm @@ -170,6 +170,7 @@ anim: { sta SPRITES_XMSB rts } +// Fill and show a sprite, clear the screen init: { .label sc = 2 lda #1 diff --git a/src/test/ref/signed-words.log b/src/test/ref/signed-words.log index e70fee73f..d50f6d3af 100644 --- a/src/test/ref/signed-words.log +++ b/src/test/ref/signed-words.log @@ -1455,6 +1455,7 @@ anim: { jmp b2 } //SEG71 init +// Fill and show a sprite, clear the screen init: { .label sc = $c .label i = $e @@ -1906,6 +1907,7 @@ anim: { jmp b2 } //SEG71 init +// Fill and show a sprite, clear the screen init: { .label sc = 2 //SEG72 [32] *((const byte*) SPRITES_ENABLE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 1 -- _deref_pbuc1=vbuc2 @@ -2465,6 +2467,7 @@ anim: { //SEG70 [14] phi (signed word) yvel#4 = (signed word) yvel_init#3 [phi:anim::@5->anim::@2#0] -- register_copy } //SEG71 init +// Fill and show a sprite, clear the screen init: { .label sc = 2 //SEG72 [32] *((const byte*) SPRITES_ENABLE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 1 -- _deref_pbuc1=vbuc2 diff --git a/src/test/ref/sinus-basic.asm b/src/test/ref/sinus-basic.asm index 26647ced0..36496a7a6 100644 --- a/src/test/ref/sinus-basic.asm +++ b/src/test/ref/sinus-basic.asm @@ -75,6 +75,7 @@ main: { f_i: .byte 0, 0, 0, 0, 0 f_127: .byte 0, 0, 0, 0, 0 } +// Print a newline print_ln: { b1: lda print_line_cursor @@ -94,6 +95,7 @@ print_ln: { !: rts } +// Print a word as HEX print_word: { .label w = 7 lda w+1 @@ -104,6 +106,7 @@ print_word: { jsr print_byte rts } +// Print a byte as HEX print_byte: { txa lsr @@ -120,6 +123,7 @@ print_byte: { jsr print_char rts } +// Print a single char print_char: { ldy #0 sta (print_char_cursor),y @@ -129,6 +133,9 @@ print_char: { !: rts } +// word = FAC +// Get the value of the FAC (floating point accumulator) as an integer 16bit word +// Destroys the value in the FAC in the process getFAC: { .label return = 7 jsr $b1aa @@ -140,6 +147,9 @@ getFAC: { sta return+1 rts } +// FAC = MEM+FAC +// Set FAC to MEM (float saved in memory) plus FAC (float accumulator) +// Reads 5 bytes from memory addMEMtoFAC: { lda #print_ln::@1] b1_from_print_ln: @@ -1325,6 +1326,7 @@ print_ln: { rts } //SEG91 print_word +// Print a word as HEX print_word: { .label w = $13 //SEG92 [43] (byte) print_byte::b#0 ← > (word) print_word::w#0 -- vbuz1=_hi_vwuz2 @@ -1355,6 +1357,7 @@ print_word: { rts } //SEG105 print_byte +// Print a byte as HEX print_byte: { .label _0 = $15 .label _2 = $16 @@ -1400,6 +1403,7 @@ print_byte: { rts } //SEG121 print_char +// Print a single char print_char: { .label ch = 6 //SEG122 [57] *((byte*) print_char_cursor#23) ← (byte) print_char::ch#2 -- _deref_pbuz1=vbuz2 @@ -1418,6 +1422,9 @@ print_char: { rts } //SEG126 getFAC +// word = FAC +// Get the value of the FAC (floating point accumulator) as an integer 16bit word +// Destroys the value in the FAC in the process getFAC: { .label return = $17 .label return_2 = $11 @@ -1437,6 +1444,9 @@ getFAC: { rts } //SEG131 addMEMtoFAC +// FAC = MEM+FAC +// Set FAC to MEM (float saved in memory) plus FAC (float accumulator) +// Reads 5 bytes from memory addMEMtoFAC: { //SEG132 [64] call prepareMEM //SEG133 [67] phi from addMEMtoFAC to prepareMEM [phi:addMEMtoFAC->prepareMEM] @@ -1461,6 +1471,7 @@ addMEMtoFAC: { rts } //SEG139 prepareMEM +// Prepare MEM pointers for operations using MEM prepareMEM: { .label _0 = $19 .label _1 = $1a @@ -1484,6 +1495,9 @@ prepareMEM: { rts } //SEG146 mulFACbyMEM +// FAC = MEM*FAC +// Set FAC to MEM (float saved in memory) multiplied by FAC (float accumulator) +// Reads 5 bytes from memory mulFACbyMEM: { .label mem = $b //SEG147 [74] (byte*) prepareMEM::mem#4 ← (byte*) mulFACbyMEM::mem#2 -- pbuz1=pbuz2 @@ -1510,6 +1524,9 @@ mulFACbyMEM: { rts } //SEG155 sinFAC +// FAC = sin(FAC) +// Set FAC to sinus of the FAC - sin(FAC) +// Sinus is calculated on radians (0-2*PI) sinFAC: { //SEG156 asm { jsr$e26b } jsr $e26b @@ -1520,6 +1537,9 @@ sinFAC: { rts } //SEG159 divMEMbyFAC +// FAC = MEM/FAC +// Set FAC to MEM (float saved in memory) divided by FAC (float accumulator) +// Reads 5 bytes from memory divMEMbyFAC: { //SEG160 [81] call prepareMEM //SEG161 [67] phi from divMEMbyFAC to prepareMEM [phi:divMEMbyFAC->prepareMEM] @@ -1544,6 +1564,8 @@ divMEMbyFAC: { rts } //SEG167 setFAC +// FAC = word +// Set the FAC (floating point accumulator) to the integer value of a 16bit word setFAC: { .label w = $d //SEG168 [85] (byte*~) prepareMEM::mem#7 ← (byte*)(word) setFAC::w#3 -- pbuz1=pbuz2 @@ -1570,6 +1592,9 @@ setFAC: { rts } //SEG176 setMEMtoFAC +// MEM = FAC +// Stores the value of the FAC to memory +// Stores 5 bytes (means it is necessary to allocate 5 bytes to avoid clobbering other data using eg. byte[] mem = {0, 0, 0, 0, 0};) setMEMtoFAC: { .label mem = $f //SEG177 [90] (byte*) prepareMEM::mem#1 ← (byte*) setMEMtoFAC::mem#2 -- pbuz1=pbuz2 @@ -1596,6 +1621,8 @@ setMEMtoFAC: { rts } //SEG185 divFACby10 +// FAC = FAC/10 +// Set FAC to FAC divided by 10 divFACby10: { //SEG186 asm { jsr$bafe } jsr $bafe @@ -1891,12 +1918,10 @@ main: { //SEG63 [28] call getFAC jsr getFAC //SEG64 [29] (word) getFAC::return#2 ← (word) getFAC::return#0 - // (word) getFAC::return#2 = (word) getFAC::return#0 // register copy zp ZP_WORD:7 jmp b14 //SEG65 main::@14 b14: //SEG66 [30] (word) print_word::w#0 ← (word) getFAC::return#2 - // (word) print_word::w#0 = (word) getFAC::return#2 // register copy zp ZP_WORD:7 //SEG67 [31] call print_word jsr print_word //SEG68 [32] phi from main::@14 to main::@15 [phi:main::@14->main::@15] @@ -1939,6 +1964,7 @@ main: { f_127: .byte 0, 0, 0, 0, 0 } //SEG83 print_ln +// Print a newline print_ln: { //SEG84 [39] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -1971,6 +1997,7 @@ print_ln: { rts } //SEG91 print_word +// Print a word as HEX print_word: { .label w = 7 //SEG92 [43] (byte) print_byte::b#0 ← > (word) print_word::w#0 -- vbuxx=_hi_vwuz1 @@ -2001,6 +2028,7 @@ print_word: { rts } //SEG105 print_byte +// Print a byte as HEX print_byte: { //SEG106 [49] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -2039,6 +2067,7 @@ print_byte: { rts } //SEG121 print_char +// Print a single char print_char: { //SEG122 [57] *((byte*) print_char_cursor#23) ← (byte) print_char::ch#2 -- _deref_pbuz1=vbuaa ldy #0 @@ -2055,6 +2084,9 @@ print_char: { rts } //SEG126 getFAC +// word = FAC +// Get the value of the FAC (floating point accumulator) as an integer 16bit word +// Destroys the value in the FAC in the process getFAC: { .label return = 7 //SEG127 asm { jsr$b1aa sty$fe sta$ff } @@ -2073,6 +2105,9 @@ getFAC: { rts } //SEG131 addMEMtoFAC +// FAC = MEM+FAC +// Set FAC to MEM (float saved in memory) plus FAC (float accumulator) +// Reads 5 bytes from memory addMEMtoFAC: { //SEG132 [64] call prepareMEM //SEG133 [67] phi from addMEMtoFAC to prepareMEM [phi:addMEMtoFAC->prepareMEM] @@ -2097,6 +2132,7 @@ addMEMtoFAC: { rts } //SEG139 prepareMEM +// Prepare MEM pointers for operations using MEM prepareMEM: { .label mem = 7 //SEG140 [68] (byte~) prepareMEM::$0 ← < (byte*) prepareMEM::mem#5 -- vbuaa=_lo_pbuz1 @@ -2114,10 +2150,12 @@ prepareMEM: { rts } //SEG146 mulFACbyMEM +// FAC = MEM*FAC +// Set FAC to MEM (float saved in memory) multiplied by FAC (float accumulator) +// Reads 5 bytes from memory mulFACbyMEM: { .label mem = 7 //SEG147 [74] (byte*) prepareMEM::mem#4 ← (byte*) mulFACbyMEM::mem#2 - // (byte*) prepareMEM::mem#4 = (byte*) mulFACbyMEM::mem#2 // register copy zp ZP_WORD:7 //SEG148 [75] call prepareMEM //SEG149 [67] phi from mulFACbyMEM to prepareMEM [phi:mulFACbyMEM->prepareMEM] prepareMEM_from_mulFACbyMEM: @@ -2137,6 +2175,9 @@ mulFACbyMEM: { rts } //SEG155 sinFAC +// FAC = sin(FAC) +// Set FAC to sinus of the FAC - sin(FAC) +// Sinus is calculated on radians (0-2*PI) sinFAC: { //SEG156 asm { jsr$e26b } jsr $e26b @@ -2147,6 +2188,9 @@ sinFAC: { rts } //SEG159 divMEMbyFAC +// FAC = MEM/FAC +// Set FAC to MEM (float saved in memory) divided by FAC (float accumulator) +// Reads 5 bytes from memory divMEMbyFAC: { //SEG160 [81] call prepareMEM //SEG161 [67] phi from divMEMbyFAC to prepareMEM [phi:divMEMbyFAC->prepareMEM] @@ -2171,10 +2215,11 @@ divMEMbyFAC: { rts } //SEG167 setFAC +// FAC = word +// Set the FAC (floating point accumulator) to the integer value of a 16bit word setFAC: { .label w = 7 //SEG168 [85] (byte*~) prepareMEM::mem#7 ← (byte*)(word) setFAC::w#3 - // (byte*~) prepareMEM::mem#7 = (byte*)(word) setFAC::w#3 // register copy zp ZP_WORD:7 //SEG169 [86] call prepareMEM //SEG170 [67] phi from setFAC to prepareMEM [phi:setFAC->prepareMEM] prepareMEM_from_setFAC: @@ -2194,10 +2239,12 @@ setFAC: { rts } //SEG176 setMEMtoFAC +// MEM = FAC +// Stores the value of the FAC to memory +// Stores 5 bytes (means it is necessary to allocate 5 bytes to avoid clobbering other data using eg. byte[] mem = {0, 0, 0, 0, 0};) setMEMtoFAC: { .label mem = 7 //SEG177 [90] (byte*) prepareMEM::mem#1 ← (byte*) setMEMtoFAC::mem#2 - // (byte*) prepareMEM::mem#1 = (byte*) setMEMtoFAC::mem#2 // register copy zp ZP_WORD:7 //SEG178 [91] call prepareMEM //SEG179 [67] phi from setMEMtoFAC to prepareMEM [phi:setMEMtoFAC->prepareMEM] prepareMEM_from_setMEMtoFAC: @@ -2217,6 +2264,8 @@ setMEMtoFAC: { rts } //SEG185 divFACby10 +// FAC = FAC/10 +// Set FAC to FAC divided by 10 divFACby10: { //SEG186 asm { jsr$bafe } jsr $bafe @@ -2606,10 +2655,8 @@ main: { //SEG63 [28] call getFAC jsr getFAC //SEG64 [29] (word) getFAC::return#2 ← (word) getFAC::return#0 - // (word) getFAC::return#2 = (word) getFAC::return#0 // register copy zp ZP_WORD:7 //SEG65 main::@14 //SEG66 [30] (word) print_word::w#0 ← (word) getFAC::return#2 - // (word) print_word::w#0 = (word) getFAC::return#2 // register copy zp ZP_WORD:7 //SEG67 [31] call print_word jsr print_word //SEG68 [32] phi from main::@14 to main::@15 [phi:main::@14->main::@15] @@ -2643,6 +2690,7 @@ main: { f_127: .byte 0, 0, 0, 0, 0 } //SEG83 print_ln +// Print a newline print_ln: { //SEG84 [39] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] //SEG85 [39] phi (byte*) print_line_cursor#6 = (byte*) print_line_cursor#13 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy @@ -2670,6 +2718,7 @@ print_ln: { rts } //SEG91 print_word +// Print a word as HEX print_word: { .label w = 7 //SEG92 [43] (byte) print_byte::b#0 ← > (word) print_word::w#0 -- vbuxx=_hi_vwuz1 @@ -2694,6 +2743,7 @@ print_word: { rts } //SEG105 print_byte +// Print a byte as HEX print_byte: { //SEG106 [49] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -2726,6 +2776,7 @@ print_byte: { rts } //SEG121 print_char +// Print a single char print_char: { //SEG122 [57] *((byte*) print_char_cursor#23) ← (byte) print_char::ch#2 -- _deref_pbuz1=vbuaa ldy #0 @@ -2740,6 +2791,9 @@ print_char: { rts } //SEG126 getFAC +// word = FAC +// Get the value of the FAC (floating point accumulator) as an integer 16bit word +// Destroys the value in the FAC in the process getFAC: { .label return = 7 //SEG127 asm { jsr$b1aa sty$fe sta$ff } @@ -2756,6 +2810,9 @@ getFAC: { rts } //SEG131 addMEMtoFAC +// FAC = MEM+FAC +// Set FAC to MEM (float saved in memory) plus FAC (float accumulator) +// Reads 5 bytes from memory addMEMtoFAC: { //SEG132 [64] call prepareMEM //SEG133 [67] phi from addMEMtoFAC to prepareMEM [phi:addMEMtoFAC->prepareMEM] @@ -2775,6 +2832,7 @@ addMEMtoFAC: { rts } //SEG139 prepareMEM +// Prepare MEM pointers for operations using MEM prepareMEM: { .label mem = 7 //SEG140 [68] (byte~) prepareMEM::$0 ← < (byte*) prepareMEM::mem#5 -- vbuaa=_lo_pbuz1 @@ -2790,10 +2848,12 @@ prepareMEM: { rts } //SEG146 mulFACbyMEM +// FAC = MEM*FAC +// Set FAC to MEM (float saved in memory) multiplied by FAC (float accumulator) +// Reads 5 bytes from memory mulFACbyMEM: { .label mem = 7 //SEG147 [74] (byte*) prepareMEM::mem#4 ← (byte*) mulFACbyMEM::mem#2 - // (byte*) prepareMEM::mem#4 = (byte*) mulFACbyMEM::mem#2 // register copy zp ZP_WORD:7 //SEG148 [75] call prepareMEM //SEG149 [67] phi from mulFACbyMEM to prepareMEM [phi:mulFACbyMEM->prepareMEM] //SEG150 [67] phi (byte*) prepareMEM::mem#5 = (byte*) prepareMEM::mem#4 [phi:mulFACbyMEM->prepareMEM#0] -- register_copy @@ -2808,6 +2868,9 @@ mulFACbyMEM: { rts } //SEG155 sinFAC +// FAC = sin(FAC) +// Set FAC to sinus of the FAC - sin(FAC) +// Sinus is calculated on radians (0-2*PI) sinFAC: { //SEG156 asm { jsr$e26b } jsr $e26b @@ -2816,6 +2879,9 @@ sinFAC: { rts } //SEG159 divMEMbyFAC +// FAC = MEM/FAC +// Set FAC to MEM (float saved in memory) divided by FAC (float accumulator) +// Reads 5 bytes from memory divMEMbyFAC: { //SEG160 [81] call prepareMEM //SEG161 [67] phi from divMEMbyFAC to prepareMEM [phi:divMEMbyFAC->prepareMEM] @@ -2835,10 +2901,11 @@ divMEMbyFAC: { rts } //SEG167 setFAC +// FAC = word +// Set the FAC (floating point accumulator) to the integer value of a 16bit word setFAC: { .label w = 7 //SEG168 [85] (byte*~) prepareMEM::mem#7 ← (byte*)(word) setFAC::w#3 - // (byte*~) prepareMEM::mem#7 = (byte*)(word) setFAC::w#3 // register copy zp ZP_WORD:7 //SEG169 [86] call prepareMEM //SEG170 [67] phi from setFAC to prepareMEM [phi:setFAC->prepareMEM] //SEG171 [67] phi (byte*) prepareMEM::mem#5 = (byte*~) prepareMEM::mem#7 [phi:setFAC->prepareMEM#0] -- register_copy @@ -2853,10 +2920,12 @@ setFAC: { rts } //SEG176 setMEMtoFAC +// MEM = FAC +// Stores the value of the FAC to memory +// Stores 5 bytes (means it is necessary to allocate 5 bytes to avoid clobbering other data using eg. byte[] mem = {0, 0, 0, 0, 0};) setMEMtoFAC: { .label mem = 7 //SEG177 [90] (byte*) prepareMEM::mem#1 ← (byte*) setMEMtoFAC::mem#2 - // (byte*) prepareMEM::mem#1 = (byte*) setMEMtoFAC::mem#2 // register copy zp ZP_WORD:7 //SEG178 [91] call prepareMEM //SEG179 [67] phi from setMEMtoFAC to prepareMEM [phi:setMEMtoFAC->prepareMEM] //SEG180 [67] phi (byte*) prepareMEM::mem#5 = (byte*) prepareMEM::mem#1 [phi:setMEMtoFAC->prepareMEM#0] -- register_copy @@ -2871,6 +2940,8 @@ setMEMtoFAC: { rts } //SEG185 divFACby10 +// FAC = FAC/10 +// Set FAC to FAC divided by 10 divFACby10: { //SEG186 asm { jsr$bafe } jsr $bafe diff --git a/src/test/ref/sinusgen16.asm b/src/test/ref/sinusgen16.asm index 5060e5c34..a18eb5bae 100644 --- a/src/test/ref/sinusgen16.asm +++ b/src/test/ref/sinusgen16.asm @@ -61,6 +61,7 @@ main: { str1: .text " @" sintab1: .fill 2*$78, 0 } +// Print a zero-terminated string print_str: { .label str = 4 b1: @@ -83,6 +84,7 @@ print_str: { !: jmp b1 } +// Print a signed word as HEX print_sword: { .label w = 6 lda w+1 @@ -102,6 +104,7 @@ print_sword: { jsr print_word rts } +// Print a word as HEX print_word: { lda print_sword.w+1 tax @@ -111,6 +114,7 @@ print_word: { jsr print_byte rts } +// Print a byte as HEX print_byte: { txa lsr @@ -127,6 +131,7 @@ print_byte: { jsr print_char rts } +// Print a single char print_char: { ldy #0 sta (print_char_cursor),y @@ -136,6 +141,7 @@ print_char: { !: rts } +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 lda #print_str::@1] @@ -2595,6 +2596,7 @@ print_str: { jmp b1_from_b2 } //SEG59 print_sword +// Print a signed word as HEX print_sword: { .label w = 6 //SEG60 [28] if((signed word) print_sword::w#1>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -2643,6 +2645,7 @@ print_sword: { rts } //SEG76 print_word +// Print a word as HEX print_word: { //SEG77 [35] (byte) print_byte::b#0 ← > (word)(signed word) print_sword::w#3 -- vbuz1=_hi_vwuz2 lda print_sword.w+1 @@ -2672,6 +2675,7 @@ print_word: { rts } //SEG90 print_byte +// Print a byte as HEX print_byte: { .label _0 = $35 .label _2 = $36 @@ -2717,6 +2721,7 @@ print_byte: { rts } //SEG106 print_char +// Print a single char print_char: { .label ch = 9 //SEG107 [49] *((byte*) print_char_cursor#33) ← (byte) print_char::ch#3 -- _deref_pbuz1=vbuz2 @@ -2735,6 +2740,7 @@ print_char: { rts } //SEG111 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = $c //SEG112 [53] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -2774,6 +2780,9 @@ print_cls: { rts } //SEG122 sin16s_gen +// Generate signed (large) word sinus table - on the full -$7fff - $7fff range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen: { .label _1 = $41 .label step = $3b @@ -2907,6 +2916,9 @@ sin16s_gen: { rts } //SEG149 sin16s +// 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: { .label _6 = $43 .label x = $17 @@ -3262,6 +3274,8 @@ sin16s: { jmp b3_from_b15 } //SEG230 mulu16_sel +// 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: { .label _0 = $69 .label _1 = $6d @@ -3338,6 +3352,7 @@ mulu16_sel: { rts } //SEG241 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label _1 = $73 .label mb = $28 @@ -3428,6 +3443,8 @@ mul16u: { jmp b1 } //SEG265 div32u16u +// 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 = $76 .label quotient_lo = $7a @@ -3504,6 +3521,10 @@ div32u16u: { rts } //SEG284 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label _1 = $80 .label _2 = $81 @@ -4025,7 +4046,6 @@ main: { //SEG33 main::@2 b2: //SEG34 [14] (signed word) print_sword::w#1 ← (signed word) main::sw#0 - // (signed word) print_sword::w#1 = (signed word) main::sw#0 // register copy zp ZP_WORD:6 //SEG35 [15] call print_sword jsr print_sword //SEG36 [16] phi from main::@2 to main::@7 [phi:main::@2->main::@7] @@ -4073,6 +4093,7 @@ main: { sintab1: .fill 2*$78, 0 } //SEG47 print_str +// Print a zero-terminated string print_str: { .label str = 4 //SEG48 [22] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -4113,6 +4134,7 @@ print_str: { jmp b1_from_b2 } //SEG59 print_sword +// Print a signed word as HEX print_sword: { .label w = 6 //SEG60 [28] if((signed word) print_sword::w#1>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -4160,6 +4182,7 @@ print_sword: { rts } //SEG76 print_word +// Print a word as HEX print_word: { //SEG77 [35] (byte) print_byte::b#0 ← > (word)(signed word) print_sword::w#3 -- vbuxx=_hi_vwuz1 lda print_sword.w+1 @@ -4189,6 +4212,7 @@ print_word: { rts } //SEG90 print_byte +// Print a byte as HEX print_byte: { //SEG91 [41] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -4227,6 +4251,7 @@ print_byte: { rts } //SEG106 print_char +// Print a single char print_char: { //SEG107 [49] *((byte*) print_char_cursor#33) ← (byte) print_char::ch#3 -- _deref_pbuz1=vbuaa ldy #0 @@ -4243,6 +4268,7 @@ print_char: { rts } //SEG111 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG112 [53] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -4282,6 +4308,9 @@ print_cls: { rts } //SEG122 sin16s_gen +// Generate signed (large) word sinus table - on the full -$7fff - $7fff range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen: { .label _1 = 6 .label step = $1b @@ -4293,12 +4322,10 @@ sin16s_gen: { div32u16u_from_sin16s_gen: jsr div32u16u //SEG125 [60] (dword) div32u16u::return#2 ← (dword) div32u16u::return#0 - // (dword) div32u16u::return#2 = (dword) div32u16u::return#0 // register copy zp ZP_DWORD:27 jmp b3 //SEG126 sin16s_gen::@3 b3: //SEG127 [61] (dword) sin16s_gen::step#0 ← (dword) div32u16u::return#2 - // (dword) sin16s_gen::step#0 = (dword) div32u16u::return#2 // register copy zp ZP_DWORD:27 //SEG128 [62] phi from sin16s_gen::@3 to sin16s_gen::@1 [phi:sin16s_gen::@3->sin16s_gen::@1] b1_from_b3: //SEG129 [62] phi (word) sin16s_gen::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin16s_gen::@3->sin16s_gen::@1#0] -- vwuz1=vbuc1 @@ -4339,12 +4366,10 @@ sin16s_gen: { //SEG138 [64] call sin16s jsr sin16s //SEG139 [65] (signed word) sin16s::return#0 ← (signed word) sin16s::return#1 - // (signed word) sin16s::return#0 = (signed word) sin16s::return#1 // register copy zp ZP_WORD:6 jmp b4 //SEG140 sin16s_gen::@4 b4: //SEG141 [66] (signed word~) sin16s_gen::$1 ← (signed word) sin16s::return#0 - // (signed word~) sin16s_gen::$1 = (signed word) sin16s::return#0 // register copy zp ZP_WORD:6 //SEG142 [67] *((signed word*) sin16s_gen::sintab#2) ← (signed word~) sin16s_gen::$1 -- _deref_pwsz1=vwsz2 ldy #0 lda _1 @@ -4395,6 +4420,9 @@ sin16s_gen: { rts } //SEG149 sin16s +// 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: { .label _6 = $f .label x = $f @@ -4533,7 +4561,6 @@ sin16s: { //SEG174 [113] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#0 [phi:sin16s::@2->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG175 [84] (word) mulu16_sel::return#0 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#0 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:19 jmp b8 //SEG176 sin16s::@8 b8: @@ -4543,7 +4570,6 @@ sin16s: { lda mulu16_sel.return+1 sta x2+1 //SEG178 [86] (word) mulu16_sel::v1#1 ← (word) sin16s::x2#0 - // (word) mulu16_sel::v1#1 = (word) sin16s::x2#0 // register copy zp ZP_WORD:8 //SEG179 [87] (word) mulu16_sel::v2#1 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -4566,9 +4592,7 @@ sin16s: { //SEG186 sin16s::@9 b9: //SEG187 [90] (word) sin16s::x3#0 ← (word) mulu16_sel::return#1 - // (word) sin16s::x3#0 = (word) mulu16_sel::return#1 // register copy zp ZP_WORD:8 //SEG188 [91] (word) mulu16_sel::v1#2 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#2 = (word) sin16s::x3#0 // register copy zp ZP_WORD:8 //SEG189 [92] call mulu16_sel //SEG190 [113] phi from sin16s::@9 to mulu16_sel [phi:sin16s::@9->mulu16_sel] mulu16_sel_from_b9: @@ -4582,12 +4606,10 @@ sin16s: { //SEG193 [113] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#2 [phi:sin16s::@9->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG194 [93] (word) mulu16_sel::return#2 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#2 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:19 jmp b10 //SEG195 sin16s::@10 b10: //SEG196 [94] (word) sin16s::x3_6#0 ← (word) mulu16_sel::return#2 - // (word) sin16s::x3_6#0 = (word) mulu16_sel::return#2 // register copy zp ZP_WORD:19 //SEG197 [95] (word) sin16s::usinx#0 ← (word) sin16s::x1#0 - (word) sin16s::x3_6#0 -- vwuz1=vwuz2_minus_vwuz3 lda x1 sec @@ -4597,7 +4619,6 @@ sin16s: { sbc x3_6+1 sta usinx+1 //SEG198 [96] (word) mulu16_sel::v1#3 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#3 = (word) sin16s::x3#0 // register copy zp ZP_WORD:8 //SEG199 [97] (word) mulu16_sel::v2#3 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -4620,9 +4641,7 @@ sin16s: { //SEG206 sin16s::@11 b11: //SEG207 [100] (word) sin16s::x4#0 ← (word) mulu16_sel::return#10 - // (word) sin16s::x4#0 = (word) mulu16_sel::return#10 // register copy zp ZP_WORD:8 //SEG208 [101] (word) mulu16_sel::v1#4 ← (word) sin16s::x4#0 - // (word) mulu16_sel::v1#4 = (word) sin16s::x4#0 // register copy zp ZP_WORD:8 //SEG209 [102] (word) mulu16_sel::v2#4 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -4637,12 +4656,10 @@ sin16s: { //SEG214 [113] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#4 [phi:sin16s::@11->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG215 [104] (word) mulu16_sel::return#11 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#11 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:19 jmp b12 //SEG216 sin16s::@12 b12: //SEG217 [105] (word) sin16s::x5#0 ← (word) mulu16_sel::return#11 - // (word) sin16s::x5#0 = (word) mulu16_sel::return#11 // register copy zp ZP_WORD:19 //SEG218 [106] (word) sin16s::x5_128#0 ← (word) sin16s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vwuz1=vwuz1_ror_4 ldy #4 !: @@ -4690,10 +4707,11 @@ sin16s: { //SEG228 sin16s::@15 b15: //SEG229 [112] (signed word~) sin16s::return#5 ← (signed word)(word) sin16s::usinx#1 - // (signed word~) sin16s::return#5 = (signed word)(word) sin16s::usinx#1 // register copy zp ZP_WORD:6 jmp b3_from_b15 } //SEG230 mulu16_sel +// 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: { .label _0 = $f .label _1 = $f @@ -4708,16 +4726,13 @@ mulu16_sel: { lda v1+1 sta mul16u.a+1 //SEG232 [115] (word) mul16u::b#0 ← (word) mulu16_sel::v2#5 - // (word) mul16u::b#0 = (word) mulu16_sel::v2#5 // register copy zp ZP_WORD:19 //SEG233 [116] call mul16u jsr mul16u //SEG234 [117] (dword) mul16u::return#2 ← (dword) mul16u::res#2 - // (dword) mul16u::return#2 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:15 jmp b2 //SEG235 mulu16_sel::@2 b2: //SEG236 [118] (dword~) mulu16_sel::$0 ← (dword) mul16u::return#2 - // (dword~) mulu16_sel::$0 = (dword) mul16u::return#2 // register copy zp ZP_DWORD:15 //SEG237 [119] (dword~) mulu16_sel::$1 ← (dword~) mulu16_sel::$0 << (byte) mulu16_sel::select#5 -- vduz1=vduz1_rol_vbuxx cpx #0 beq !e+ @@ -4741,6 +4756,7 @@ mulu16_sel: { rts } //SEG241 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label mb = $17 .label a = $15 @@ -4828,6 +4844,8 @@ mul16u: { jmp b1 } //SEG265 div32u16u +// 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 = 8 .label quotient_lo = 6 @@ -4847,7 +4865,6 @@ div32u16u: { sta divr16u.rem+1 jsr divr16u //SEG270 [134] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:6 jmp b2 //SEG271 div32u16u::@2 b2: @@ -4857,7 +4874,6 @@ div32u16u: { lda divr16u.return+1 sta quotient_hi+1 //SEG273 [136] (word) divr16u::rem#4 ← (word) rem16u#1 - // (word) divr16u::rem#4 = (word) rem16u#1 // register copy zp ZP_WORD:2 //SEG274 [137] call divr16u //SEG275 [142] phi from div32u16u::@2 to divr16u [phi:div32u16u::@2->divr16u] divr16u_from_b2: @@ -4869,12 +4885,10 @@ div32u16u: { //SEG277 [142] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:div32u16u::@2->divr16u#1] -- register_copy jsr divr16u //SEG278 [138] (word) divr16u::return#3 ← (word) divr16u::return#0 - // (word) divr16u::return#3 = (word) divr16u::return#0 // register copy zp ZP_WORD:6 jmp b3 //SEG279 div32u16u::@3 b3: //SEG280 [139] (word) div32u16u::quotient_lo#0 ← (word) divr16u::return#3 - // (word) div32u16u::quotient_lo#0 = (word) divr16u::return#3 // register copy zp ZP_WORD:6 //SEG281 [140] (dword) div32u16u::return#0 ← (word) div32u16u::quotient_hi#0 dw= (word) div32u16u::quotient_lo#0 -- vduz1=vwuz2_dword_vwuz3 lda quotient_hi sta return+2 @@ -4891,6 +4905,10 @@ div32u16u: { rts } //SEG284 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 4 @@ -4989,7 +5007,6 @@ divr16u: { //SEG317 divr16u::@6 b6: //SEG318 [158] (word) rem16u#1 ← (word) divr16u::rem#11 - // (word) rem16u#1 = (word) divr16u::rem#11 // register copy zp ZP_WORD:2 jmp breturn //SEG319 divr16u::@return breturn: @@ -5102,9 +5119,11 @@ Removing instruction print_char_from_b2: Removing instruction b1_from_print_sword: Removing instruction b1_from_b4: Removing instruction b1_from_b1: +Removing instruction b1_from_b3: Removing instruction b1_from_b4: Removing instruction b2_from_b1: Removing instruction b2_from_b5: +Removing instruction mulu16_sel_from_b9: Removing instruction b3_from_b15: Removing instruction b3_from_b6: Removing instruction breturn: @@ -5115,6 +5134,7 @@ Removing instruction b2_from_b1: Removing instruction b2_from_b4: Removing instruction b3_from_b2: Removing instruction b3_from_b5: +Removing instruction breturn: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction bend: Removing instruction sin16s_gen_from_main: @@ -5141,7 +5161,6 @@ Removing instruction b1_from_print_cls: Removing instruction breturn: Removing instruction div32u16u_from_sin16s_gen: Removing instruction b3: -Removing instruction b1_from_b3: Removing instruction b4: Removing instruction breturn: Removing instruction b4: @@ -5151,7 +5170,6 @@ Removing instruction mulu16_sel_from_b2: Removing instruction b8: Removing instruction mulu16_sel_from_b8: Removing instruction b9: -Removing instruction mulu16_sel_from_b9: Removing instruction b10: Removing instruction mulu16_sel_from_b10: Removing instruction b11: @@ -5173,7 +5191,6 @@ Removing instruction b1_from_divr16u: Removing instruction b4: Removing instruction b5: Removing instruction b6: -Removing instruction breturn: Succesful ASM optimization Pass5UnusedLabelElimination Updating BasicUpstart to call main directly Removing instruction jsr main @@ -5551,7 +5568,6 @@ main: { //SEG33 main::@2 b2: //SEG34 [14] (signed word) print_sword::w#1 ← (signed word) main::sw#0 - // (signed word) print_sword::w#1 = (signed word) main::sw#0 // register copy zp ZP_WORD:6 //SEG35 [15] call print_sword jsr print_sword //SEG36 [16] phi from main::@2 to main::@7 [phi:main::@2->main::@7] @@ -5591,6 +5607,7 @@ main: { sintab1: .fill 2*$78, 0 } //SEG47 print_str +// Print a zero-terminated string print_str: { .label str = 4 //SEG48 [22] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -5625,6 +5642,7 @@ print_str: { jmp b1 } //SEG59 print_sword +// Print a signed word as HEX print_sword: { .label w = 6 //SEG60 [28] if((signed word) print_sword::w#1>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -5661,6 +5679,7 @@ print_sword: { rts } //SEG76 print_word +// Print a word as HEX print_word: { //SEG77 [35] (byte) print_byte::b#0 ← > (word)(signed word) print_sword::w#3 -- vbuxx=_hi_vwuz1 lda print_sword.w+1 @@ -5684,6 +5703,7 @@ print_word: { rts } //SEG90 print_byte +// Print a byte as HEX print_byte: { //SEG91 [41] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -5716,6 +5736,7 @@ print_byte: { rts } //SEG106 print_char +// Print a single char print_char: { //SEG107 [49] *((byte*) print_char_cursor#33) ← (byte) print_char::ch#3 -- _deref_pbuz1=vbuaa ldy #0 @@ -5730,6 +5751,7 @@ print_char: { rts } //SEG111 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG112 [53] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -5763,6 +5785,9 @@ print_cls: { rts } //SEG122 sin16s_gen +// Generate signed (large) word sinus table - on the full -$7fff - $7fff range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen: { .label _1 = 6 .label step = $1b @@ -5773,10 +5798,8 @@ sin16s_gen: { //SEG124 [132] phi from sin16s_gen to div32u16u [phi:sin16s_gen->div32u16u] jsr div32u16u //SEG125 [60] (dword) div32u16u::return#2 ← (dword) div32u16u::return#0 - // (dword) div32u16u::return#2 = (dword) div32u16u::return#0 // register copy zp ZP_DWORD:27 //SEG126 sin16s_gen::@3 //SEG127 [61] (dword) sin16s_gen::step#0 ← (dword) div32u16u::return#2 - // (dword) sin16s_gen::step#0 = (dword) div32u16u::return#2 // register copy zp ZP_DWORD:27 //SEG128 [62] phi from sin16s_gen::@3 to sin16s_gen::@1 [phi:sin16s_gen::@3->sin16s_gen::@1] //SEG129 [62] phi (word) sin16s_gen::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin16s_gen::@3->sin16s_gen::@1#0] -- vwuz1=vbuc1 lda #<0 @@ -5811,10 +5834,8 @@ sin16s_gen: { //SEG138 [64] call sin16s jsr sin16s //SEG139 [65] (signed word) sin16s::return#0 ← (signed word) sin16s::return#1 - // (signed word) sin16s::return#0 = (signed word) sin16s::return#1 // register copy zp ZP_WORD:6 //SEG140 sin16s_gen::@4 //SEG141 [66] (signed word~) sin16s_gen::$1 ← (signed word) sin16s::return#0 - // (signed word~) sin16s_gen::$1 = (signed word) sin16s::return#0 // register copy zp ZP_WORD:6 //SEG142 [67] *((signed word*) sin16s_gen::sintab#2) ← (signed word~) sin16s_gen::$1 -- _deref_pwsz1=vwsz2 ldy #0 lda _1 @@ -5863,6 +5884,9 @@ sin16s_gen: { rts } //SEG149 sin16s +// 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: { .label _6 = $f .label x = $f @@ -5991,7 +6015,6 @@ sin16s: { //SEG174 [113] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#0 [phi:sin16s::@2->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG175 [84] (word) mulu16_sel::return#0 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#0 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:19 //SEG176 sin16s::@8 //SEG177 [85] (word) sin16s::x2#0 ← (word) mulu16_sel::return#0 -- vwuz1=vwuz2 lda mulu16_sel.return @@ -5999,7 +6022,6 @@ sin16s: { lda mulu16_sel.return+1 sta x2+1 //SEG178 [86] (word) mulu16_sel::v1#1 ← (word) sin16s::x2#0 - // (word) mulu16_sel::v1#1 = (word) sin16s::x2#0 // register copy zp ZP_WORD:8 //SEG179 [87] (word) mulu16_sel::v2#1 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -6019,9 +6041,7 @@ sin16s: { sta mulu16_sel.return_1+1 //SEG186 sin16s::@9 //SEG187 [90] (word) sin16s::x3#0 ← (word) mulu16_sel::return#1 - // (word) sin16s::x3#0 = (word) mulu16_sel::return#1 // register copy zp ZP_WORD:8 //SEG188 [91] (word) mulu16_sel::v1#2 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#2 = (word) sin16s::x3#0 // register copy zp ZP_WORD:8 //SEG189 [92] call mulu16_sel //SEG190 [113] phi from sin16s::@9 to mulu16_sel [phi:sin16s::@9->mulu16_sel] //SEG191 [113] phi (byte) mulu16_sel::select#5 = (byte/signed byte/word/signed word/dword/signed dword) 1 [phi:sin16s::@9->mulu16_sel#0] -- vbuxx=vbuc1 @@ -6034,10 +6054,8 @@ sin16s: { //SEG193 [113] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#2 [phi:sin16s::@9->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG194 [93] (word) mulu16_sel::return#2 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#2 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:19 //SEG195 sin16s::@10 //SEG196 [94] (word) sin16s::x3_6#0 ← (word) mulu16_sel::return#2 - // (word) sin16s::x3_6#0 = (word) mulu16_sel::return#2 // register copy zp ZP_WORD:19 //SEG197 [95] (word) sin16s::usinx#0 ← (word) sin16s::x1#0 - (word) sin16s::x3_6#0 -- vwuz1=vwuz2_minus_vwuz3 lda x1 sec @@ -6047,7 +6065,6 @@ sin16s: { sbc x3_6+1 sta usinx+1 //SEG198 [96] (word) mulu16_sel::v1#3 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#3 = (word) sin16s::x3#0 // register copy zp ZP_WORD:8 //SEG199 [97] (word) mulu16_sel::v2#3 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -6067,9 +6084,7 @@ sin16s: { sta mulu16_sel.return_10+1 //SEG206 sin16s::@11 //SEG207 [100] (word) sin16s::x4#0 ← (word) mulu16_sel::return#10 - // (word) sin16s::x4#0 = (word) mulu16_sel::return#10 // register copy zp ZP_WORD:8 //SEG208 [101] (word) mulu16_sel::v1#4 ← (word) sin16s::x4#0 - // (word) mulu16_sel::v1#4 = (word) sin16s::x4#0 // register copy zp ZP_WORD:8 //SEG209 [102] (word) mulu16_sel::v2#4 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -6083,10 +6098,8 @@ sin16s: { //SEG214 [113] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#4 [phi:sin16s::@11->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG215 [104] (word) mulu16_sel::return#11 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#11 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:19 //SEG216 sin16s::@12 //SEG217 [105] (word) sin16s::x5#0 ← (word) mulu16_sel::return#11 - // (word) sin16s::x5#0 = (word) mulu16_sel::return#11 // register copy zp ZP_WORD:19 //SEG218 [106] (word) sin16s::x5_128#0 ← (word) sin16s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vwuz1=vwuz1_ror_4 ldy #4 !: @@ -6126,9 +6139,10 @@ sin16s: { rts //SEG228 sin16s::@15 //SEG229 [112] (signed word~) sin16s::return#5 ← (signed word)(word) sin16s::usinx#1 - // (signed word~) sin16s::return#5 = (signed word)(word) sin16s::usinx#1 // register copy zp ZP_WORD:6 } //SEG230 mulu16_sel +// 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: { .label _0 = $f .label _1 = $f @@ -6143,14 +6157,11 @@ mulu16_sel: { lda v1+1 sta mul16u.a+1 //SEG232 [115] (word) mul16u::b#0 ← (word) mulu16_sel::v2#5 - // (word) mul16u::b#0 = (word) mulu16_sel::v2#5 // register copy zp ZP_WORD:19 //SEG233 [116] call mul16u jsr mul16u //SEG234 [117] (dword) mul16u::return#2 ← (dword) mul16u::res#2 - // (dword) mul16u::return#2 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:15 //SEG235 mulu16_sel::@2 //SEG236 [118] (dword~) mulu16_sel::$0 ← (dword) mul16u::return#2 - // (dword~) mulu16_sel::$0 = (dword) mul16u::return#2 // register copy zp ZP_DWORD:15 //SEG237 [119] (dword~) mulu16_sel::$1 ← (dword~) mulu16_sel::$0 << (byte) mulu16_sel::select#5 -- vduz1=vduz1_rol_vbuxx cpx #0 beq !e+ @@ -6172,6 +6183,7 @@ mulu16_sel: { rts } //SEG241 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label mb = $17 .label a = $15 @@ -6247,6 +6259,8 @@ mul16u: { jmp b1 } //SEG265 div32u16u +// 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 = 8 .label quotient_lo = 6 @@ -6264,7 +6278,6 @@ div32u16u: { sta divr16u.rem+1 jsr divr16u //SEG270 [134] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:6 //SEG271 div32u16u::@2 //SEG272 [135] (word) div32u16u::quotient_hi#0 ← (word) divr16u::return#2 -- vwuz1=vwuz2 lda divr16u.return @@ -6272,7 +6285,6 @@ div32u16u: { lda divr16u.return+1 sta quotient_hi+1 //SEG273 [136] (word) divr16u::rem#4 ← (word) rem16u#1 - // (word) divr16u::rem#4 = (word) rem16u#1 // register copy zp ZP_WORD:2 //SEG274 [137] call divr16u //SEG275 [142] phi from div32u16u::@2 to divr16u [phi:div32u16u::@2->divr16u] //SEG276 [142] phi (word) divr16u::dividend#5 = <(const dword) PI2_u4f28#0 [phi:div32u16u::@2->divr16u#0] -- vwuz1=vwuc1 @@ -6283,10 +6295,8 @@ div32u16u: { //SEG277 [142] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:div32u16u::@2->divr16u#1] -- register_copy jsr divr16u //SEG278 [138] (word) divr16u::return#3 ← (word) divr16u::return#0 - // (word) divr16u::return#3 = (word) divr16u::return#0 // register copy zp ZP_WORD:6 //SEG279 div32u16u::@3 //SEG280 [139] (word) div32u16u::quotient_lo#0 ← (word) divr16u::return#3 - // (word) div32u16u::quotient_lo#0 = (word) divr16u::return#3 // register copy zp ZP_WORD:6 //SEG281 [140] (dword) div32u16u::return#0 ← (word) div32u16u::quotient_hi#0 dw= (word) div32u16u::quotient_lo#0 -- vduz1=vwuz2_dword_vwuz3 lda quotient_hi sta return+2 @@ -6301,6 +6311,10 @@ div32u16u: { rts } //SEG284 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 4 @@ -6382,7 +6396,6 @@ divr16u: { bne b1 //SEG317 divr16u::@6 //SEG318 [158] (word) rem16u#1 ← (word) divr16u::rem#11 - // (word) rem16u#1 = (word) divr16u::rem#11 // register copy zp ZP_WORD:2 //SEG319 divr16u::@return //SEG320 [159] return rts diff --git a/src/test/ref/sinusgen16b.asm b/src/test/ref/sinusgen16b.asm index 122bc4561..8eb00bd78 100644 --- a/src/test/ref/sinusgen16b.asm +++ b/src/test/ref/sinusgen16b.asm @@ -76,6 +76,7 @@ main: { sintab1: .fill 2*$78, 0 sintab2: .fill 2*$78, 0 } +// Print a zero-terminated string print_str: { .label str = 6 b1: @@ -98,6 +99,7 @@ print_str: { !: jmp b1 } +// Print a signed word as HEX print_sword: { .label w = 8 lda w+1 @@ -117,6 +119,7 @@ print_sword: { jsr print_word rts } +// Print a word as HEX print_word: { lda print_sword.w+1 sta print_byte.b @@ -126,6 +129,7 @@ print_word: { jsr print_byte rts } +// Print a byte as HEX print_byte: { .label b = $a lda b @@ -143,6 +147,7 @@ print_byte: { jsr print_char rts } +// Print a single char print_char: { ldy #0 sta (print_char_cursor),y @@ -152,6 +157,7 @@ print_char: { !: rts } +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 lda #print_str::@1] @@ -3399,6 +3400,7 @@ print_str: { jmp b1_from_b2 } //SEG69 print_sword +// Print a signed word as HEX print_sword: { .label w = 9 //SEG70 [32] if((signed word) print_sword::w#1>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -3447,6 +3449,7 @@ print_sword: { rts } //SEG86 print_word +// Print a word as HEX print_word: { //SEG87 [39] (byte) print_byte::b#0 ← > (word)(signed word) print_sword::w#3 -- vbuz1=_hi_vwuz2 lda print_sword.w+1 @@ -3476,6 +3479,7 @@ print_word: { rts } //SEG100 print_byte +// Print a byte as HEX print_byte: { .label _0 = $45 .label _2 = $46 @@ -3521,6 +3525,7 @@ print_byte: { rts } //SEG116 print_char +// Print a single char print_char: { .label ch = $c //SEG117 [53] *((byte*) print_char_cursor#33) ← (byte) print_char::ch#3 -- _deref_pbuz1=vbuz2 @@ -3539,6 +3544,7 @@ print_char: { rts } //SEG121 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = $f //SEG122 [57] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -3578,6 +3584,9 @@ print_cls: { rts } //SEG132 sin16s_genb +// Generate signed (large) word sinus table - on the full -$7fff - $7fff range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_genb: { .label _2 = $51 .label step = $4b @@ -3707,6 +3716,9 @@ sin16s_genb: { rts } //SEG159 sin16sb +// 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 sin16sb: { .label x = $1a .label return = $4f @@ -4022,6 +4034,8 @@ sin16sb: { jmp b3_from_b15 } //SEG239 mulu16_sel +// 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: { .label _0 = $75 .label _1 = $79 @@ -4103,6 +4117,7 @@ mulu16_sel: { rts } //SEG250 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label _1 = $7f .label mb = $29 @@ -4193,6 +4208,8 @@ mul16u: { jmp b1 } //SEG274 div32u16u +// 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 = $82 .label quotient_lo = $86 @@ -4270,6 +4287,10 @@ div32u16u: { rts } //SEG293 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label _1 = $8c .label _2 = $8d @@ -4390,6 +4411,9 @@ divr16u: { rts } //SEG330 sin16s_gen +// Generate signed (large) word sinus table - on the full -$7fff - $7fff range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen: { .label _1 = $9a .label step = $94 @@ -4523,6 +4547,9 @@ sin16s_gen: { rts } //SEG357 sin16s +// 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: { .label _6 = $9c .label x = $3d @@ -5444,7 +5471,6 @@ main: { //SEG41 main::@2 b2: //SEG42 [16] (signed word) print_sword::w#1 ← (signed word) main::sw#0 - // (signed word) print_sword::w#1 = (signed word) main::sw#0 // register copy zp ZP_WORD:8 //SEG43 [17] call print_sword jsr print_sword //SEG44 [18] phi from main::@2 to main::@8 [phi:main::@2->main::@8] @@ -5497,6 +5523,7 @@ main: { sintab2: .fill 2*$78, 0 } //SEG57 print_str +// Print a zero-terminated string print_str: { .label str = 6 //SEG58 [26] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -5537,6 +5564,7 @@ print_str: { jmp b1_from_b2 } //SEG69 print_sword +// Print a signed word as HEX print_sword: { .label w = 8 //SEG70 [32] if((signed word) print_sword::w#1>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -5584,6 +5612,7 @@ print_sword: { rts } //SEG86 print_word +// Print a word as HEX print_word: { //SEG87 [39] (byte) print_byte::b#0 ← > (word)(signed word) print_sword::w#3 -- vbuz1=_hi_vwuz2 lda print_sword.w+1 @@ -5613,6 +5642,7 @@ print_word: { rts } //SEG100 print_byte +// Print a byte as HEX print_byte: { .label b = $a //SEG101 [45] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 @@ -5652,6 +5682,7 @@ print_byte: { rts } //SEG116 print_char +// Print a single char print_char: { //SEG117 [53] *((byte*) print_char_cursor#33) ← (byte) print_char::ch#3 -- _deref_pbuz1=vbuaa ldy #0 @@ -5668,6 +5699,7 @@ print_char: { rts } //SEG121 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG122 [57] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -5707,6 +5739,9 @@ print_cls: { rts } //SEG132 sin16s_genb +// Generate signed (large) word sinus table - on the full -$7fff - $7fff range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_genb: { .label _2 = 8 .label step = $1d @@ -5718,12 +5753,10 @@ sin16s_genb: { div32u16u_from_sin16s_genb: jsr div32u16u //SEG135 [64] (dword) div32u16u::return#3 ← (dword) div32u16u::return#0 - // (dword) div32u16u::return#3 = (dword) div32u16u::return#0 // register copy zp ZP_DWORD:29 jmp b3 //SEG136 sin16s_genb::@3 b3: //SEG137 [65] (dword) sin16s_genb::step#0 ← (dword) div32u16u::return#3 - // (dword) sin16s_genb::step#0 = (dword) div32u16u::return#3 // register copy zp ZP_DWORD:29 //SEG138 [66] phi from sin16s_genb::@3 to sin16s_genb::@1 [phi:sin16s_genb::@3->sin16s_genb::@1] b1_from_b3: //SEG139 [66] phi (word) sin16s_genb::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin16s_genb::@3->sin16s_genb::@1#0] -- vwuz1=vbuc1 @@ -5760,12 +5793,10 @@ sin16s_genb: { //SEG148 [68] call sin16sb jsr sin16sb //SEG149 [69] (signed word) sin16sb::return#0 ← (signed word) sin16sb::return#1 - // (signed word) sin16sb::return#0 = (signed word) sin16sb::return#1 // register copy zp ZP_WORD:8 jmp b4 //SEG150 sin16s_genb::@4 b4: //SEG151 [70] (signed word~) sin16s_genb::$2 ← (signed word) sin16sb::return#0 - // (signed word~) sin16s_genb::$2 = (signed word) sin16sb::return#0 // register copy zp ZP_WORD:8 //SEG152 [71] *((signed word*) sin16s_genb::sintab#2) ← (signed word~) sin16s_genb::$2 -- _deref_pwsz1=vwsz2 ldy #0 lda _2 @@ -5816,6 +5847,9 @@ sin16s_genb: { rts } //SEG159 sin16sb +// 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 sin16sb: { .label x = 6 .label return = 8 @@ -5918,7 +5952,6 @@ sin16sb: { //SEG183 [116] phi (word) mulu16_sel::v1#10 = (word) mulu16_sel::v1#5 [phi:sin16sb::@2->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG184 [87] (word) mulu16_sel::return#18 ← (word) mulu16_sel::return#17 - // (word) mulu16_sel::return#18 = (word) mulu16_sel::return#17 // register copy zp ZP_WORD:17 jmp b8 //SEG185 sin16sb::@8 b8: @@ -5928,7 +5961,6 @@ sin16sb: { lda mulu16_sel.return_18+1 sta x2+1 //SEG187 [89] (word) mulu16_sel::v1#6 ← (word) sin16sb::x2#0 - // (word) mulu16_sel::v1#6 = (word) sin16sb::x2#0 // register copy zp ZP_WORD:11 //SEG188 [90] (word) mulu16_sel::v2#6 ← (word) sin16sb::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -5951,9 +5983,7 @@ sin16sb: { //SEG195 sin16sb::@9 b9: //SEG196 [93] (word) sin16sb::x3#0 ← (word) mulu16_sel::return#19 - // (word) sin16sb::x3#0 = (word) mulu16_sel::return#19 // register copy zp ZP_WORD:11 //SEG197 [94] (word) mulu16_sel::v1#7 ← (word) sin16sb::x3#0 - // (word) mulu16_sel::v1#7 = (word) sin16sb::x3#0 // register copy zp ZP_WORD:11 //SEG198 [95] call mulu16_sel //SEG199 [116] phi from sin16sb::@9 to mulu16_sel [phi:sin16sb::@9->mulu16_sel] mulu16_sel_from_b9: @@ -5967,12 +5997,10 @@ sin16sb: { //SEG202 [116] phi (word) mulu16_sel::v1#10 = (word) mulu16_sel::v1#7 [phi:sin16sb::@9->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG203 [96] (word) mulu16_sel::return#20 ← (word) mulu16_sel::return#17 - // (word) mulu16_sel::return#20 = (word) mulu16_sel::return#17 // register copy zp ZP_WORD:17 jmp b10 //SEG204 sin16sb::@10 b10: //SEG205 [97] (word) sin16sb::x3_6#0 ← (word) mulu16_sel::return#20 - // (word) sin16sb::x3_6#0 = (word) mulu16_sel::return#20 // register copy zp ZP_WORD:17 //SEG206 [98] (word) sin16sb::usinx#0 ← (word) sin16sb::x1#0 - (word) sin16sb::x3_6#0 -- vwuz1=vwuz2_minus_vwuz3 lda x1 sec @@ -5982,7 +6010,6 @@ sin16sb: { sbc x3_6+1 sta usinx+1 //SEG207 [99] (word) mulu16_sel::v1#8 ← (word) sin16sb::x3#0 - // (word) mulu16_sel::v1#8 = (word) sin16sb::x3#0 // register copy zp ZP_WORD:11 //SEG208 [100] (word) mulu16_sel::v2#8 ← (word) sin16sb::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -6005,9 +6032,7 @@ sin16sb: { //SEG215 sin16sb::@11 b11: //SEG216 [103] (word) sin16sb::x4#0 ← (word) mulu16_sel::return#10 - // (word) sin16sb::x4#0 = (word) mulu16_sel::return#10 // register copy zp ZP_WORD:11 //SEG217 [104] (word) mulu16_sel::v1#9 ← (word) sin16sb::x4#0 - // (word) mulu16_sel::v1#9 = (word) sin16sb::x4#0 // register copy zp ZP_WORD:11 //SEG218 [105] (word) mulu16_sel::v2#9 ← (word) sin16sb::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -6022,12 +6047,10 @@ sin16sb: { //SEG223 [116] phi (word) mulu16_sel::v1#10 = (word) mulu16_sel::v1#9 [phi:sin16sb::@11->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG224 [107] (word) mulu16_sel::return#11 ← (word) mulu16_sel::return#17 - // (word) mulu16_sel::return#11 = (word) mulu16_sel::return#17 // register copy zp ZP_WORD:17 jmp b12 //SEG225 sin16sb::@12 b12: //SEG226 [108] (word) sin16sb::x5#0 ← (word) mulu16_sel::return#11 - // (word) sin16sb::x5#0 = (word) mulu16_sel::return#11 // register copy zp ZP_WORD:17 //SEG227 [109] (word) sin16sb::x5_128#0 ← (word) sin16sb::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vwuz1=vwuz1_ror_4 ldy #4 !: @@ -6075,10 +6098,11 @@ sin16sb: { //SEG237 sin16sb::@15 b15: //SEG238 [115] (signed word~) sin16sb::return#5 ← (signed word)(word) sin16sb::usinx#1 - // (signed word~) sin16sb::return#5 = (signed word)(word) sin16sb::usinx#1 // register copy zp ZP_WORD:8 jmp b3_from_b15 } //SEG239 mulu16_sel +// 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: { .label _0 = $15 .label _1 = $15 @@ -6097,16 +6121,13 @@ mulu16_sel: { lda v1+1 sta mul16u.a+1 //SEG241 [118] (word) mul16u::b#0 ← (word) mulu16_sel::v2#10 - // (word) mul16u::b#0 = (word) mulu16_sel::v2#10 // register copy zp ZP_WORD:17 //SEG242 [119] call mul16u jsr mul16u //SEG243 [120] (dword) mul16u::return#2 ← (dword) mul16u::res#2 - // (dword) mul16u::return#2 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:21 jmp b2 //SEG244 mulu16_sel::@2 b2: //SEG245 [121] (dword~) mulu16_sel::$0 ← (dword) mul16u::return#2 - // (dword~) mulu16_sel::$0 = (dword) mul16u::return#2 // register copy zp ZP_DWORD:21 //SEG246 [122] (dword~) mulu16_sel::$1 ← (dword~) mulu16_sel::$0 << (byte) mulu16_sel::select#10 -- vduz1=vduz1_rol_vbuxx cpx #0 beq !e+ @@ -6130,6 +6151,7 @@ mulu16_sel: { rts } //SEG250 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label mb = $19 .label a = $13 @@ -6217,6 +6239,8 @@ mul16u: { jmp b1 } //SEG274 div32u16u +// 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 = 8 .label quotient_lo = 6 @@ -6236,7 +6260,6 @@ div32u16u: { sta divr16u.rem+1 jsr divr16u //SEG279 [137] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:6 jmp b2 //SEG280 div32u16u::@2 b2: @@ -6246,7 +6269,6 @@ div32u16u: { lda divr16u.return+1 sta quotient_hi+1 //SEG282 [139] (word) divr16u::rem#4 ← (word) rem16u#1 - // (word) divr16u::rem#4 = (word) rem16u#1 // register copy zp ZP_WORD:2 //SEG283 [140] call divr16u //SEG284 [145] phi from div32u16u::@2 to divr16u [phi:div32u16u::@2->divr16u] divr16u_from_b2: @@ -6258,12 +6280,10 @@ div32u16u: { //SEG286 [145] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:div32u16u::@2->divr16u#1] -- register_copy jsr divr16u //SEG287 [141] (word) divr16u::return#3 ← (word) divr16u::return#0 - // (word) divr16u::return#3 = (word) divr16u::return#0 // register copy zp ZP_WORD:6 jmp b3 //SEG288 div32u16u::@3 b3: //SEG289 [142] (word) div32u16u::quotient_lo#0 ← (word) divr16u::return#3 - // (word) div32u16u::quotient_lo#0 = (word) divr16u::return#3 // register copy zp ZP_WORD:6 //SEG290 [143] (dword) div32u16u::return#0 ← (word) div32u16u::quotient_hi#0 dw= (word) div32u16u::quotient_lo#0 -- vduz1=vwuz2_dword_vwuz3 lda quotient_hi sta return+2 @@ -6280,6 +6300,10 @@ div32u16u: { rts } //SEG293 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 4 @@ -6378,7 +6402,6 @@ divr16u: { //SEG326 divr16u::@6 b6: //SEG327 [161] (word) rem16u#1 ← (word) divr16u::rem#11 - // (word) rem16u#1 = (word) divr16u::rem#11 // register copy zp ZP_WORD:2 jmp breturn //SEG328 divr16u::@return breturn: @@ -6386,6 +6409,9 @@ divr16u: { rts } //SEG330 sin16s_gen +// Generate signed (large) word sinus table - on the full -$7fff - $7fff range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen: { .label _1 = 6 .label step = $1d @@ -6397,12 +6423,10 @@ sin16s_gen: { div32u16u_from_sin16s_gen: jsr div32u16u //SEG333 [165] (dword) div32u16u::return#2 ← (dword) div32u16u::return#0 - // (dword) div32u16u::return#2 = (dword) div32u16u::return#0 // register copy zp ZP_DWORD:29 jmp b3 //SEG334 sin16s_gen::@3 b3: //SEG335 [166] (dword) sin16s_gen::step#0 ← (dword) div32u16u::return#2 - // (dword) sin16s_gen::step#0 = (dword) div32u16u::return#2 // register copy zp ZP_DWORD:29 //SEG336 [167] phi from sin16s_gen::@3 to sin16s_gen::@1 [phi:sin16s_gen::@3->sin16s_gen::@1] b1_from_b3: //SEG337 [167] phi (word) sin16s_gen::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin16s_gen::@3->sin16s_gen::@1#0] -- vwuz1=vbuc1 @@ -6443,12 +6467,10 @@ sin16s_gen: { //SEG346 [169] call sin16s jsr sin16s //SEG347 [170] (signed word) sin16s::return#0 ← (signed word) sin16s::return#1 - // (signed word) sin16s::return#0 = (signed word) sin16s::return#1 // register copy zp ZP_WORD:6 jmp b4 //SEG348 sin16s_gen::@4 b4: //SEG349 [171] (signed word~) sin16s_gen::$1 ← (signed word) sin16s::return#0 - // (signed word~) sin16s_gen::$1 = (signed word) sin16s::return#0 // register copy zp ZP_WORD:6 //SEG350 [172] *((signed word*) sin16s_gen::sintab#2) ← (signed word~) sin16s_gen::$1 -- _deref_pwsz1=vwsz2 ldy #0 lda _1 @@ -6499,6 +6521,9 @@ sin16s_gen: { rts } //SEG357 sin16s +// 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: { .label _6 = $15 .label x = $15 @@ -6645,9 +6670,7 @@ sin16s: { //SEG384 sin16s::@8 b8: //SEG385 [190] (word) sin16s::x2#0 ← (word) mulu16_sel::return#0 - // (word) sin16s::x2#0 = (word) mulu16_sel::return#0 // register copy zp ZP_WORD:11 //SEG386 [191] (word) mulu16_sel::v1#1 ← (word) sin16s::x2#0 - // (word) mulu16_sel::v1#1 = (word) sin16s::x2#0 // register copy zp ZP_WORD:11 //SEG387 [192] (word) mulu16_sel::v2#1 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -6670,9 +6693,7 @@ sin16s: { //SEG394 sin16s::@9 b9: //SEG395 [195] (word) sin16s::x3#0 ← (word) mulu16_sel::return#1 - // (word) sin16s::x3#0 = (word) mulu16_sel::return#1 // register copy zp ZP_WORD:11 //SEG396 [196] (word) mulu16_sel::v1#2 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#2 = (word) sin16s::x3#0 // register copy zp ZP_WORD:11 //SEG397 [197] call mulu16_sel //SEG398 [116] phi from sin16s::@9 to mulu16_sel [phi:sin16s::@9->mulu16_sel] mulu16_sel_from_b9: @@ -6686,12 +6707,10 @@ sin16s: { //SEG401 [116] phi (word) mulu16_sel::v1#10 = (word) mulu16_sel::v1#2 [phi:sin16s::@9->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG402 [198] (word) mulu16_sel::return#14 ← (word) mulu16_sel::return#17 - // (word) mulu16_sel::return#14 = (word) mulu16_sel::return#17 // register copy zp ZP_WORD:17 jmp b10 //SEG403 sin16s::@10 b10: //SEG404 [199] (word) sin16s::x3_6#0 ← (word) mulu16_sel::return#14 - // (word) sin16s::x3_6#0 = (word) mulu16_sel::return#14 // register copy zp ZP_WORD:17 //SEG405 [200] (word) sin16s::usinx#0 ← (word) sin16s::x1#0 - (word) sin16s::x3_6#0 -- vwuz1=vwuz2_minus_vwuz3 lda x1 sec @@ -6701,7 +6720,6 @@ sin16s: { sbc x3_6+1 sta usinx+1 //SEG406 [201] (word) mulu16_sel::v1#3 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#3 = (word) sin16s::x3#0 // register copy zp ZP_WORD:11 //SEG407 [202] (word) mulu16_sel::v2#3 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -6724,9 +6742,7 @@ sin16s: { //SEG414 sin16s::@11 b11: //SEG415 [205] (word) sin16s::x4#0 ← (word) mulu16_sel::return#15 - // (word) sin16s::x4#0 = (word) mulu16_sel::return#15 // register copy zp ZP_WORD:11 //SEG416 [206] (word) mulu16_sel::v1#4 ← (word) sin16s::x4#0 - // (word) mulu16_sel::v1#4 = (word) sin16s::x4#0 // register copy zp ZP_WORD:11 //SEG417 [207] (word) mulu16_sel::v2#4 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -6741,12 +6757,10 @@ sin16s: { //SEG422 [116] phi (word) mulu16_sel::v1#10 = (word) mulu16_sel::v1#4 [phi:sin16s::@11->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG423 [209] (word) mulu16_sel::return#16 ← (word) mulu16_sel::return#17 - // (word) mulu16_sel::return#16 = (word) mulu16_sel::return#17 // register copy zp ZP_WORD:17 jmp b12 //SEG424 sin16s::@12 b12: //SEG425 [210] (word) sin16s::x5#0 ← (word) mulu16_sel::return#16 - // (word) sin16s::x5#0 = (word) mulu16_sel::return#16 // register copy zp ZP_WORD:17 //SEG426 [211] (word) sin16s::x5_128#0 ← (word) sin16s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vwuz1=vwuz1_ror_4 ldy #4 !: @@ -6794,7 +6808,6 @@ sin16s: { //SEG436 sin16s::@15 b15: //SEG437 [217] (signed word~) sin16s::return#5 ← (signed word)(word) sin16s::usinx#1 - // (signed word~) sin16s::return#5 = (signed word)(word) sin16s::usinx#1 // register copy zp ZP_WORD:6 jmp b3_from_b15 } print_hextab: .text "0123456789abcdef" @@ -6928,9 +6941,11 @@ Removing instruction print_char_from_b2: Removing instruction b1_from_print_sword: Removing instruction b1_from_b4: Removing instruction b1_from_b1: +Removing instruction b1_from_b3: Removing instruction b1_from_b4: Removing instruction b2_from_b1: Removing instruction b2_from_b5: +Removing instruction mulu16_sel_from_b9: Removing instruction b3_from_b15: Removing instruction b3_from_b6: Removing instruction breturn: @@ -6941,9 +6956,12 @@ Removing instruction b2_from_b1: Removing instruction b2_from_b4: Removing instruction b3_from_b2: Removing instruction b3_from_b5: +Removing instruction breturn: +Removing instruction b1_from_b3: Removing instruction b1_from_b4: Removing instruction b2_from_b1: Removing instruction b2_from_b5: +Removing instruction mulu16_sel_from_b9: Removing instruction b3_from_b15: Removing instruction b3_from_b6: Removing instruction breturn: @@ -6974,7 +6992,6 @@ Removing instruction b1_from_print_cls: Removing instruction breturn: Removing instruction div32u16u_from_sin16s_genb: Removing instruction b3: -Removing instruction b1_from_b3: Removing instruction b4: Removing instruction breturn: Removing instruction b4: @@ -6984,7 +7001,6 @@ Removing instruction mulu16_sel_from_b2: Removing instruction b8: Removing instruction mulu16_sel_from_b8: Removing instruction b9: -Removing instruction mulu16_sel_from_b9: Removing instruction b10: Removing instruction mulu16_sel_from_b10: Removing instruction b11: @@ -7006,10 +7022,8 @@ Removing instruction b1_from_divr16u: Removing instruction b4: Removing instruction b5: Removing instruction b6: -Removing instruction breturn: Removing instruction div32u16u_from_sin16s_gen: Removing instruction b3: -Removing instruction b1_from_b3: Removing instruction b4: Removing instruction breturn: Removing instruction b4: @@ -7019,7 +7033,6 @@ Removing instruction mulu16_sel_from_b2: Removing instruction b8: Removing instruction mulu16_sel_from_b8: Removing instruction b9: -Removing instruction mulu16_sel_from_b9: Removing instruction b10: Removing instruction mulu16_sel_from_b10: Removing instruction b11: @@ -7517,7 +7530,6 @@ main: { //SEG41 main::@2 b2: //SEG42 [16] (signed word) print_sword::w#1 ← (signed word) main::sw#0 - // (signed word) print_sword::w#1 = (signed word) main::sw#0 // register copy zp ZP_WORD:8 //SEG43 [17] call print_sword jsr print_sword //SEG44 [18] phi from main::@2 to main::@8 [phi:main::@2->main::@8] @@ -7562,6 +7574,7 @@ main: { sintab2: .fill 2*$78, 0 } //SEG57 print_str +// Print a zero-terminated string print_str: { .label str = 6 //SEG58 [26] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -7596,6 +7609,7 @@ print_str: { jmp b1 } //SEG69 print_sword +// Print a signed word as HEX print_sword: { .label w = 8 //SEG70 [32] if((signed word) print_sword::w#1>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -7632,6 +7646,7 @@ print_sword: { rts } //SEG86 print_word +// Print a word as HEX print_word: { //SEG87 [39] (byte) print_byte::b#0 ← > (word)(signed word) print_sword::w#3 -- vbuz1=_hi_vwuz2 lda print_sword.w+1 @@ -7655,6 +7670,7 @@ print_word: { rts } //SEG100 print_byte +// Print a byte as HEX print_byte: { .label b = $a //SEG101 [45] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 @@ -7688,6 +7704,7 @@ print_byte: { rts } //SEG116 print_char +// Print a single char print_char: { //SEG117 [53] *((byte*) print_char_cursor#33) ← (byte) print_char::ch#3 -- _deref_pbuz1=vbuaa ldy #0 @@ -7702,6 +7719,7 @@ print_char: { rts } //SEG121 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG122 [57] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -7735,6 +7753,9 @@ print_cls: { rts } //SEG132 sin16s_genb +// Generate signed (large) word sinus table - on the full -$7fff - $7fff range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_genb: { .label _2 = 8 .label step = $1d @@ -7745,10 +7766,8 @@ sin16s_genb: { //SEG134 [135] phi from sin16s_genb to div32u16u [phi:sin16s_genb->div32u16u] jsr div32u16u //SEG135 [64] (dword) div32u16u::return#3 ← (dword) div32u16u::return#0 - // (dword) div32u16u::return#3 = (dword) div32u16u::return#0 // register copy zp ZP_DWORD:29 //SEG136 sin16s_genb::@3 //SEG137 [65] (dword) sin16s_genb::step#0 ← (dword) div32u16u::return#3 - // (dword) sin16s_genb::step#0 = (dword) div32u16u::return#3 // register copy zp ZP_DWORD:29 //SEG138 [66] phi from sin16s_genb::@3 to sin16s_genb::@1 [phi:sin16s_genb::@3->sin16s_genb::@1] //SEG139 [66] phi (word) sin16s_genb::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin16s_genb::@3->sin16s_genb::@1#0] -- vwuz1=vbuc1 lda #<0 @@ -7779,10 +7798,8 @@ sin16s_genb: { //SEG148 [68] call sin16sb jsr sin16sb //SEG149 [69] (signed word) sin16sb::return#0 ← (signed word) sin16sb::return#1 - // (signed word) sin16sb::return#0 = (signed word) sin16sb::return#1 // register copy zp ZP_WORD:8 //SEG150 sin16s_genb::@4 //SEG151 [70] (signed word~) sin16s_genb::$2 ← (signed word) sin16sb::return#0 - // (signed word~) sin16s_genb::$2 = (signed word) sin16sb::return#0 // register copy zp ZP_WORD:8 //SEG152 [71] *((signed word*) sin16s_genb::sintab#2) ← (signed word~) sin16s_genb::$2 -- _deref_pwsz1=vwsz2 ldy #0 lda _2 @@ -7831,6 +7848,9 @@ sin16s_genb: { rts } //SEG159 sin16sb +// 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 sin16sb: { .label x = 6 .label return = 8 @@ -7923,7 +7943,6 @@ sin16sb: { //SEG183 [116] phi (word) mulu16_sel::v1#10 = (word) mulu16_sel::v1#5 [phi:sin16sb::@2->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG184 [87] (word) mulu16_sel::return#18 ← (word) mulu16_sel::return#17 - // (word) mulu16_sel::return#18 = (word) mulu16_sel::return#17 // register copy zp ZP_WORD:17 //SEG185 sin16sb::@8 //SEG186 [88] (word) sin16sb::x2#0 ← (word) mulu16_sel::return#18 -- vwuz1=vwuz2 lda mulu16_sel.return_18 @@ -7931,7 +7950,6 @@ sin16sb: { lda mulu16_sel.return_18+1 sta x2+1 //SEG187 [89] (word) mulu16_sel::v1#6 ← (word) sin16sb::x2#0 - // (word) mulu16_sel::v1#6 = (word) sin16sb::x2#0 // register copy zp ZP_WORD:11 //SEG188 [90] (word) mulu16_sel::v2#6 ← (word) sin16sb::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -7951,9 +7969,7 @@ sin16sb: { sta mulu16_sel.return+1 //SEG195 sin16sb::@9 //SEG196 [93] (word) sin16sb::x3#0 ← (word) mulu16_sel::return#19 - // (word) sin16sb::x3#0 = (word) mulu16_sel::return#19 // register copy zp ZP_WORD:11 //SEG197 [94] (word) mulu16_sel::v1#7 ← (word) sin16sb::x3#0 - // (word) mulu16_sel::v1#7 = (word) sin16sb::x3#0 // register copy zp ZP_WORD:11 //SEG198 [95] call mulu16_sel //SEG199 [116] phi from sin16sb::@9 to mulu16_sel [phi:sin16sb::@9->mulu16_sel] //SEG200 [116] phi (byte) mulu16_sel::select#10 = (byte/signed byte/word/signed word/dword/signed dword) 1 [phi:sin16sb::@9->mulu16_sel#0] -- vbuxx=vbuc1 @@ -7966,10 +7982,8 @@ sin16sb: { //SEG202 [116] phi (word) mulu16_sel::v1#10 = (word) mulu16_sel::v1#7 [phi:sin16sb::@9->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG203 [96] (word) mulu16_sel::return#20 ← (word) mulu16_sel::return#17 - // (word) mulu16_sel::return#20 = (word) mulu16_sel::return#17 // register copy zp ZP_WORD:17 //SEG204 sin16sb::@10 //SEG205 [97] (word) sin16sb::x3_6#0 ← (word) mulu16_sel::return#20 - // (word) sin16sb::x3_6#0 = (word) mulu16_sel::return#20 // register copy zp ZP_WORD:17 //SEG206 [98] (word) sin16sb::usinx#0 ← (word) sin16sb::x1#0 - (word) sin16sb::x3_6#0 -- vwuz1=vwuz2_minus_vwuz3 lda x1 sec @@ -7979,7 +7993,6 @@ sin16sb: { sbc x3_6+1 sta usinx+1 //SEG207 [99] (word) mulu16_sel::v1#8 ← (word) sin16sb::x3#0 - // (word) mulu16_sel::v1#8 = (word) sin16sb::x3#0 // register copy zp ZP_WORD:11 //SEG208 [100] (word) mulu16_sel::v2#8 ← (word) sin16sb::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -7999,9 +8012,7 @@ sin16sb: { sta mulu16_sel.return+1 //SEG215 sin16sb::@11 //SEG216 [103] (word) sin16sb::x4#0 ← (word) mulu16_sel::return#10 - // (word) sin16sb::x4#0 = (word) mulu16_sel::return#10 // register copy zp ZP_WORD:11 //SEG217 [104] (word) mulu16_sel::v1#9 ← (word) sin16sb::x4#0 - // (word) mulu16_sel::v1#9 = (word) sin16sb::x4#0 // register copy zp ZP_WORD:11 //SEG218 [105] (word) mulu16_sel::v2#9 ← (word) sin16sb::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -8015,10 +8026,8 @@ sin16sb: { //SEG223 [116] phi (word) mulu16_sel::v1#10 = (word) mulu16_sel::v1#9 [phi:sin16sb::@11->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG224 [107] (word) mulu16_sel::return#11 ← (word) mulu16_sel::return#17 - // (word) mulu16_sel::return#11 = (word) mulu16_sel::return#17 // register copy zp ZP_WORD:17 //SEG225 sin16sb::@12 //SEG226 [108] (word) sin16sb::x5#0 ← (word) mulu16_sel::return#11 - // (word) sin16sb::x5#0 = (word) mulu16_sel::return#11 // register copy zp ZP_WORD:17 //SEG227 [109] (word) sin16sb::x5_128#0 ← (word) sin16sb::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vwuz1=vwuz1_ror_4 ldy #4 !: @@ -8058,9 +8067,10 @@ sin16sb: { rts //SEG237 sin16sb::@15 //SEG238 [115] (signed word~) sin16sb::return#5 ← (signed word)(word) sin16sb::usinx#1 - // (signed word~) sin16sb::return#5 = (signed word)(word) sin16sb::usinx#1 // register copy zp ZP_WORD:8 } //SEG239 mulu16_sel +// 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: { .label _0 = $15 .label _1 = $15 @@ -8079,14 +8089,11 @@ mulu16_sel: { lda v1+1 sta mul16u.a+1 //SEG241 [118] (word) mul16u::b#0 ← (word) mulu16_sel::v2#10 - // (word) mul16u::b#0 = (word) mulu16_sel::v2#10 // register copy zp ZP_WORD:17 //SEG242 [119] call mul16u jsr mul16u //SEG243 [120] (dword) mul16u::return#2 ← (dword) mul16u::res#2 - // (dword) mul16u::return#2 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:21 //SEG244 mulu16_sel::@2 //SEG245 [121] (dword~) mulu16_sel::$0 ← (dword) mul16u::return#2 - // (dword~) mulu16_sel::$0 = (dword) mul16u::return#2 // register copy zp ZP_DWORD:21 //SEG246 [122] (dword~) mulu16_sel::$1 ← (dword~) mulu16_sel::$0 << (byte) mulu16_sel::select#10 -- vduz1=vduz1_rol_vbuxx cpx #0 beq !e+ @@ -8108,6 +8115,7 @@ mulu16_sel: { rts } //SEG250 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label mb = $19 .label a = $13 @@ -8183,6 +8191,8 @@ mul16u: { jmp b1 } //SEG274 div32u16u +// 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 = 8 .label quotient_lo = 6 @@ -8200,7 +8210,6 @@ div32u16u: { sta divr16u.rem+1 jsr divr16u //SEG279 [137] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:6 //SEG280 div32u16u::@2 //SEG281 [138] (word) div32u16u::quotient_hi#0 ← (word) divr16u::return#2 -- vwuz1=vwuz2 lda divr16u.return @@ -8208,7 +8217,6 @@ div32u16u: { lda divr16u.return+1 sta quotient_hi+1 //SEG282 [139] (word) divr16u::rem#4 ← (word) rem16u#1 - // (word) divr16u::rem#4 = (word) rem16u#1 // register copy zp ZP_WORD:2 //SEG283 [140] call divr16u //SEG284 [145] phi from div32u16u::@2 to divr16u [phi:div32u16u::@2->divr16u] //SEG285 [145] phi (word) divr16u::dividend#5 = <(const dword) PI2_u4f28#0 [phi:div32u16u::@2->divr16u#0] -- vwuz1=vwuc1 @@ -8219,10 +8227,8 @@ div32u16u: { //SEG286 [145] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:div32u16u::@2->divr16u#1] -- register_copy jsr divr16u //SEG287 [141] (word) divr16u::return#3 ← (word) divr16u::return#0 - // (word) divr16u::return#3 = (word) divr16u::return#0 // register copy zp ZP_WORD:6 //SEG288 div32u16u::@3 //SEG289 [142] (word) div32u16u::quotient_lo#0 ← (word) divr16u::return#3 - // (word) div32u16u::quotient_lo#0 = (word) divr16u::return#3 // register copy zp ZP_WORD:6 //SEG290 [143] (dword) div32u16u::return#0 ← (word) div32u16u::quotient_hi#0 dw= (word) div32u16u::quotient_lo#0 -- vduz1=vwuz2_dword_vwuz3 lda quotient_hi sta return+2 @@ -8237,6 +8243,10 @@ div32u16u: { rts } //SEG293 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 4 @@ -8318,12 +8328,14 @@ divr16u: { bne b1 //SEG326 divr16u::@6 //SEG327 [161] (word) rem16u#1 ← (word) divr16u::rem#11 - // (word) rem16u#1 = (word) divr16u::rem#11 // register copy zp ZP_WORD:2 //SEG328 divr16u::@return //SEG329 [162] return rts } //SEG330 sin16s_gen +// Generate signed (large) word sinus table - on the full -$7fff - $7fff range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen: { .label _1 = 6 .label step = $1d @@ -8334,10 +8346,8 @@ sin16s_gen: { //SEG332 [135] phi from sin16s_gen to div32u16u [phi:sin16s_gen->div32u16u] jsr div32u16u //SEG333 [165] (dword) div32u16u::return#2 ← (dword) div32u16u::return#0 - // (dword) div32u16u::return#2 = (dword) div32u16u::return#0 // register copy zp ZP_DWORD:29 //SEG334 sin16s_gen::@3 //SEG335 [166] (dword) sin16s_gen::step#0 ← (dword) div32u16u::return#2 - // (dword) sin16s_gen::step#0 = (dword) div32u16u::return#2 // register copy zp ZP_DWORD:29 //SEG336 [167] phi from sin16s_gen::@3 to sin16s_gen::@1 [phi:sin16s_gen::@3->sin16s_gen::@1] //SEG337 [167] phi (word) sin16s_gen::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin16s_gen::@3->sin16s_gen::@1#0] -- vwuz1=vbuc1 lda #<0 @@ -8372,10 +8382,8 @@ sin16s_gen: { //SEG346 [169] call sin16s jsr sin16s //SEG347 [170] (signed word) sin16s::return#0 ← (signed word) sin16s::return#1 - // (signed word) sin16s::return#0 = (signed word) sin16s::return#1 // register copy zp ZP_WORD:6 //SEG348 sin16s_gen::@4 //SEG349 [171] (signed word~) sin16s_gen::$1 ← (signed word) sin16s::return#0 - // (signed word~) sin16s_gen::$1 = (signed word) sin16s::return#0 // register copy zp ZP_WORD:6 //SEG350 [172] *((signed word*) sin16s_gen::sintab#2) ← (signed word~) sin16s_gen::$1 -- _deref_pwsz1=vwsz2 ldy #0 lda _1 @@ -8424,6 +8432,9 @@ sin16s_gen: { rts } //SEG357 sin16s +// 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: { .label _6 = $15 .label x = $15 @@ -8558,9 +8569,7 @@ sin16s: { sta mulu16_sel.return+1 //SEG384 sin16s::@8 //SEG385 [190] (word) sin16s::x2#0 ← (word) mulu16_sel::return#0 - // (word) sin16s::x2#0 = (word) mulu16_sel::return#0 // register copy zp ZP_WORD:11 //SEG386 [191] (word) mulu16_sel::v1#1 ← (word) sin16s::x2#0 - // (word) mulu16_sel::v1#1 = (word) sin16s::x2#0 // register copy zp ZP_WORD:11 //SEG387 [192] (word) mulu16_sel::v2#1 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -8580,9 +8589,7 @@ sin16s: { sta mulu16_sel.return+1 //SEG394 sin16s::@9 //SEG395 [195] (word) sin16s::x3#0 ← (word) mulu16_sel::return#1 - // (word) sin16s::x3#0 = (word) mulu16_sel::return#1 // register copy zp ZP_WORD:11 //SEG396 [196] (word) mulu16_sel::v1#2 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#2 = (word) sin16s::x3#0 // register copy zp ZP_WORD:11 //SEG397 [197] call mulu16_sel //SEG398 [116] phi from sin16s::@9 to mulu16_sel [phi:sin16s::@9->mulu16_sel] //SEG399 [116] phi (byte) mulu16_sel::select#10 = (byte/signed byte/word/signed word/dword/signed dword) 1 [phi:sin16s::@9->mulu16_sel#0] -- vbuxx=vbuc1 @@ -8595,10 +8602,8 @@ sin16s: { //SEG401 [116] phi (word) mulu16_sel::v1#10 = (word) mulu16_sel::v1#2 [phi:sin16s::@9->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG402 [198] (word) mulu16_sel::return#14 ← (word) mulu16_sel::return#17 - // (word) mulu16_sel::return#14 = (word) mulu16_sel::return#17 // register copy zp ZP_WORD:17 //SEG403 sin16s::@10 //SEG404 [199] (word) sin16s::x3_6#0 ← (word) mulu16_sel::return#14 - // (word) sin16s::x3_6#0 = (word) mulu16_sel::return#14 // register copy zp ZP_WORD:17 //SEG405 [200] (word) sin16s::usinx#0 ← (word) sin16s::x1#0 - (word) sin16s::x3_6#0 -- vwuz1=vwuz2_minus_vwuz3 lda x1 sec @@ -8608,7 +8613,6 @@ sin16s: { sbc x3_6+1 sta usinx+1 //SEG406 [201] (word) mulu16_sel::v1#3 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#3 = (word) sin16s::x3#0 // register copy zp ZP_WORD:11 //SEG407 [202] (word) mulu16_sel::v2#3 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -8628,9 +8632,7 @@ sin16s: { sta mulu16_sel.return+1 //SEG414 sin16s::@11 //SEG415 [205] (word) sin16s::x4#0 ← (word) mulu16_sel::return#15 - // (word) sin16s::x4#0 = (word) mulu16_sel::return#15 // register copy zp ZP_WORD:11 //SEG416 [206] (word) mulu16_sel::v1#4 ← (word) sin16s::x4#0 - // (word) mulu16_sel::v1#4 = (word) sin16s::x4#0 // register copy zp ZP_WORD:11 //SEG417 [207] (word) mulu16_sel::v2#4 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -8644,10 +8646,8 @@ sin16s: { //SEG422 [116] phi (word) mulu16_sel::v1#10 = (word) mulu16_sel::v1#4 [phi:sin16s::@11->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG423 [209] (word) mulu16_sel::return#16 ← (word) mulu16_sel::return#17 - // (word) mulu16_sel::return#16 = (word) mulu16_sel::return#17 // register copy zp ZP_WORD:17 //SEG424 sin16s::@12 //SEG425 [210] (word) sin16s::x5#0 ← (word) mulu16_sel::return#16 - // (word) sin16s::x5#0 = (word) mulu16_sel::return#16 // register copy zp ZP_WORD:17 //SEG426 [211] (word) sin16s::x5_128#0 ← (word) sin16s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vwuz1=vwuz1_ror_4 ldy #4 !: @@ -8687,7 +8687,6 @@ sin16s: { rts //SEG436 sin16s::@15 //SEG437 [217] (signed word~) sin16s::return#5 ← (signed word)(word) sin16s::usinx#1 - // (signed word~) sin16s::return#5 = (signed word)(word) sin16s::usinx#1 // register copy zp ZP_WORD:6 } print_hextab: .text "0123456789abcdef" diff --git a/src/test/ref/sinusgen8.asm b/src/test/ref/sinusgen8.asm index 37689323b..59c18a305 100644 --- a/src/test/ref/sinusgen8.asm +++ b/src/test/ref/sinusgen8.asm @@ -44,6 +44,7 @@ main: { sintab2: .fill $c0, 0 sintabref: .byte 0, 4, 8, $c, $11, $15, $19, $1d, $21, $25, $29, $2d, $31, $35, $38, $3c, $40, $43, $47, $4a, $4e, $51, $54, $57, $5a, $5d, $60, $63, $65, $68, $6a, $6c, $6e, $70, $72, $74, $76, $77, $79, $7a, $7b, $7c, $7d, $7e, $7e, $7f, $7f, $7f, $80, $7f, $7f, $7f, $7e, $7e, $7d, $7c, $7b, $7a, $79, $77, $76, $74, $72, $70, $6e, $6c, $6a, $68, $65, $63, $60, $5d, $5a, $57, $54, $51, $4e, $4a, $47, $43, $40, $3c, $38, $35, $31, $2d, $29, $25, $21, $1d, $19, $15, $11, $c, 8, 4, 0, $fc, $f8, $f4, $ef, $eb, $e7, $e3, $df, $db, $d7, $d3, $cf, $cb, $c8, $c4, $c0, $bd, $b9, $b6, $b2, $af, $ac, $a9, $a6, $a3, $a0, $9d, $9b, $98, $96, $94, $92, $90, $8e, $8c, $8a, $89, $87, $86, $85, $84, $83, $82, $82, $81, $81, $81, $81, $81, $81, $81, $82, $82, $83, $84, $85, $86, $87, $89, $8a, $8c, $8e, $90, $92, $94, $96, $98, $9b, $9d, $a0, $a3, $a6, $a9, $ac, $af, $b2, $b6, $b9, $bd, $c0, $c4, $c8, $cb, $cf, $d3, $d7, $db, $df, $e3, $e7, $eb, $ef, $f4, $f8, $fc } +// Print a zero-terminated string print_str: { .label str = 2 b1: @@ -66,6 +67,7 @@ print_str: { !: jmp b1 } +// Print a signed byte as HEX print_sbyte: { .label b = 4 lda b @@ -85,6 +87,7 @@ print_sbyte: { sta b jmp b2 } +// Print a single char print_char: { ldy #0 sta (print_char_cursor),y @@ -94,6 +97,7 @@ print_char: { !: rts } +// Print a byte as HEX print_byte: { lda print_sbyte.b lsr @@ -110,6 +114,7 @@ print_byte: { jsr print_char rts } +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 lda #print_str::@1] @@ -2459,6 +2460,7 @@ print_str: { jmp b1_from_b2 } //SEG59 print_sbyte +// Print a signed byte as HEX print_sbyte: { .label b = 5 //SEG60 [28] if((signed byte) print_sbyte::b#1<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsz1_lt_0_then_la1 @@ -2516,6 +2518,7 @@ print_sbyte: { jmp b2_from_b5 } //SEG81 print_char +// Print a single char print_char: { .label ch = 6 //SEG82 [38] *((byte*) print_char_cursor#29) ← (byte) print_char::ch#4 -- _deref_pbuz1=vbuz2 @@ -2534,6 +2537,7 @@ print_char: { rts } //SEG86 print_byte +// Print a byte as HEX print_byte: { .label _0 = $26 .label _2 = $27 @@ -2578,6 +2582,7 @@ print_byte: { rts } //SEG102 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 9 //SEG103 [49] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -2617,6 +2622,9 @@ print_cls: { rts } //SEG113 sin8s_gen +// Generate signed byte sinus table - on the full -$7f - $7f range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin8s_gen: { .label _1 = $2d .label step = $2a @@ -2720,6 +2728,9 @@ sin8s_gen: { rts } //SEG140 sin8s +// Calculate signed byte sinus sin(x) +// x: unsigned word input u[4.12] in the interval $0000 - PI2_u4f12 +// result: signed byte sin(x) s[0.7] - using the full range -$7f - $7f sin8s: { .const DIV_6 = $2b .label _6 = $2e @@ -3002,6 +3013,8 @@ sin8s: { jmp b4_from_b18 } //SEG227 mulu8_sel +// 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: { .label _0 = $40 .label _1 = $42 @@ -3058,6 +3071,8 @@ mulu8_sel: { rts } //SEG238 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .label _1 = $45 .label mb = $1c @@ -3132,6 +3147,10 @@ mul8u: { jmp b1 } //SEG262 div16u +// Performs division on two 16 bit unsigned words +// Returns the quotient dividend/divisor. +// The remainder will be set into the global variable rem16u +// Implemented using simple binary division div16u: { .label return = $48 .label return_2 = $28 @@ -3159,6 +3178,10 @@ div16u: { rts } //SEG270 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label _1 = $4a .label _2 = $4b @@ -3621,7 +3644,6 @@ main: { //SEG33 main::@2 b2: //SEG34 [14] (signed byte) print_sbyte::b#1 ← (signed byte) main::sb#0 - // (signed byte) print_sbyte::b#1 = (signed byte) main::sb#0 // register copy zp ZP_BYTE:4 //SEG35 [15] call print_sbyte jsr print_sbyte //SEG36 [16] phi from main::@2 to main::@7 [phi:main::@2->main::@7] @@ -3658,6 +3680,7 @@ main: { sintabref: .byte 0, 4, 8, $c, $11, $15, $19, $1d, $21, $25, $29, $2d, $31, $35, $38, $3c, $40, $43, $47, $4a, $4e, $51, $54, $57, $5a, $5d, $60, $63, $65, $68, $6a, $6c, $6e, $70, $72, $74, $76, $77, $79, $7a, $7b, $7c, $7d, $7e, $7e, $7f, $7f, $7f, $80, $7f, $7f, $7f, $7e, $7e, $7d, $7c, $7b, $7a, $79, $77, $76, $74, $72, $70, $6e, $6c, $6a, $68, $65, $63, $60, $5d, $5a, $57, $54, $51, $4e, $4a, $47, $43, $40, $3c, $38, $35, $31, $2d, $29, $25, $21, $1d, $19, $15, $11, $c, 8, 4, 0, $fc, $f8, $f4, $ef, $eb, $e7, $e3, $df, $db, $d7, $d3, $cf, $cb, $c8, $c4, $c0, $bd, $b9, $b6, $b2, $af, $ac, $a9, $a6, $a3, $a0, $9d, $9b, $98, $96, $94, $92, $90, $8e, $8c, $8a, $89, $87, $86, $85, $84, $83, $82, $82, $81, $81, $81, $81, $81, $81, $81, $82, $82, $83, $84, $85, $86, $87, $89, $8a, $8c, $8e, $90, $92, $94, $96, $98, $9b, $9d, $a0, $a3, $a6, $a9, $ac, $af, $b2, $b6, $b9, $bd, $c0, $c4, $c8, $cb, $cf, $d3, $d7, $db, $df, $e3, $e7, $eb, $ef, $f4, $f8, $fc } //SEG47 print_str +// Print a zero-terminated string print_str: { .label str = 2 //SEG48 [22] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -3698,6 +3721,7 @@ print_str: { jmp b1_from_b2 } //SEG59 print_sbyte +// Print a signed byte as HEX print_sbyte: { .label b = 4 //SEG60 [28] if((signed byte) print_sbyte::b#1<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsz1_lt_0_then_la1 @@ -3753,6 +3777,7 @@ print_sbyte: { jmp b2_from_b5 } //SEG81 print_char +// Print a single char print_char: { //SEG82 [38] *((byte*) print_char_cursor#29) ← (byte) print_char::ch#4 -- _deref_pbuz1=vbuaa ldy #0 @@ -3769,6 +3794,7 @@ print_char: { rts } //SEG86 print_byte +// Print a byte as HEX print_byte: { //SEG87 [41] (byte~) print_byte::$0 ← (byte)(signed byte) print_sbyte::b#4 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 lda print_sbyte.b @@ -3807,6 +3833,7 @@ print_byte: { rts } //SEG102 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG103 [49] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -3846,6 +3873,9 @@ print_cls: { rts } //SEG113 sin8s_gen +// Generate signed byte sinus table - on the full -$7f - $7f range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin8s_gen: { .label step = $e .label sintab = 5 @@ -3856,12 +3886,10 @@ sin8s_gen: { div16u_from_sin8s_gen: jsr div16u //SEG116 [56] (word) div16u::return#2 ← (word) div16u::return#0 - // (word) div16u::return#2 = (word) div16u::return#0 // register copy zp ZP_WORD:14 jmp b3 //SEG117 sin8s_gen::@3 b3: //SEG118 [57] (word) sin8s_gen::step#0 ← (word) div16u::return#2 - // (word) sin8s_gen::step#0 = (word) div16u::return#2 // register copy zp ZP_WORD:14 //SEG119 [58] phi from sin8s_gen::@3 to sin8s_gen::@1 [phi:sin8s_gen::@3->sin8s_gen::@1] b1_from_b3: //SEG120 [58] phi (word) sin8s_gen::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin8s_gen::@3->sin8s_gen::@1#0] -- vwuz1=vbuc1 @@ -3896,12 +3924,10 @@ sin8s_gen: { //SEG129 [60] call sin8s jsr sin8s //SEG130 [61] (signed byte) sin8s::return#0 ← (signed byte) sin8s::return#1 - // (signed byte) sin8s::return#0 = (signed byte) sin8s::return#1 // register copy reg byte a jmp b4 //SEG131 sin8s_gen::@4 b4: //SEG132 [62] (signed byte~) sin8s_gen::$1 ← (signed byte) sin8s::return#0 - // (signed byte~) sin8s_gen::$1 = (signed byte) sin8s::return#0 // register copy reg byte a //SEG133 [63] *((signed byte*) sin8s_gen::sintab#2) ← (signed byte~) sin8s_gen::$1 -- _deref_pbsz1=vbsaa ldy #0 sta (sintab),y @@ -3939,6 +3965,9 @@ sin8s_gen: { rts } //SEG140 sin8s +// Calculate signed byte sinus sin(x) +// x: unsigned word input u[4.12] in the interval $0000 - PI2_u4f12 +// result: signed byte sin(x) s[0.7] - using the full range -$7f - $7f sin8s: { .const DIV_6 = $2b .label _6 = 9 @@ -4034,12 +4063,10 @@ sin8s: { //SEG165 [112] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#0 [phi:sin8s::@2->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG166 [80] (byte) mulu8_sel::return#0 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#0 = (byte) mulu8_sel::return#12 // register copy reg byte a jmp b10 //SEG167 sin8s::@10 b10: //SEG168 [81] (byte) sin8s::x2#0 ← (byte) mulu8_sel::return#0 - // (byte) sin8s::x2#0 = (byte) mulu8_sel::return#0 // register copy reg byte a //SEG169 [82] (byte) mulu8_sel::v1#1 ← (byte) sin8s::x2#0 -- vbuxx=vbuaa tax //SEG170 [83] (byte) mulu8_sel::v2#1 ← (byte) sin8s::x1#0 -- vbuyy=vbuz1 @@ -4054,7 +4081,6 @@ sin8s: { //SEG175 [112] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#1 [phi:sin8s::@10->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG176 [85] (byte) mulu8_sel::return#1 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#1 = (byte) mulu8_sel::return#12 // register copy reg byte a jmp b11 //SEG177 sin8s::@11 b11: @@ -4073,12 +4099,10 @@ sin8s: { //SEG184 [112] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#2 [phi:sin8s::@11->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG185 [89] (byte) mulu8_sel::return#2 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#2 = (byte) mulu8_sel::return#12 // register copy reg byte a jmp b12 //SEG186 sin8s::@12 b12: //SEG187 [90] (byte) sin8s::x3_6#0 ← (byte) mulu8_sel::return#2 - // (byte) sin8s::x3_6#0 = (byte) mulu8_sel::return#2 // register copy reg byte a //SEG188 [91] (byte) sin8s::usinx#0 ← (byte) sin8s::x1#0 - (byte) sin8s::x3_6#0 -- vbuz1=vbuz2_minus_vbuaa eor #$ff sec @@ -4098,12 +4122,10 @@ sin8s: { //SEG195 [112] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#3 [phi:sin8s::@12->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG196 [95] (byte) mulu8_sel::return#10 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#10 = (byte) mulu8_sel::return#12 // register copy reg byte a jmp b13 //SEG197 sin8s::@13 b13: //SEG198 [96] (byte) sin8s::x4#0 ← (byte) mulu8_sel::return#10 - // (byte) sin8s::x4#0 = (byte) mulu8_sel::return#10 // register copy reg byte a //SEG199 [97] (byte) mulu8_sel::v1#4 ← (byte) sin8s::x4#0 -- vbuxx=vbuaa tax //SEG200 [98] (byte) mulu8_sel::v2#4 ← (byte) sin8s::x1#0 -- vbuyy=vbuz1 @@ -4118,12 +4140,10 @@ sin8s: { //SEG205 [112] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#4 [phi:sin8s::@13->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG206 [100] (byte) mulu8_sel::return#11 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#11 = (byte) mulu8_sel::return#12 // register copy reg byte a jmp b14 //SEG207 sin8s::@14 b14: //SEG208 [101] (byte) sin8s::x5#0 ← (byte) mulu8_sel::return#11 - // (byte) sin8s::x5#0 = (byte) mulu8_sel::return#11 // register copy reg byte a //SEG209 [102] (byte) sin8s::x5_128#0 ← (byte) sin8s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuaa_ror_4 lsr lsr @@ -4179,23 +4199,22 @@ sin8s: { jmp b4_from_b18 } //SEG227 mulu8_sel +// 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: { .label _0 = 9 .label _1 = 9 .label select = $b //SEG228 [113] (byte) mul8u::a#1 ← (byte) mulu8_sel::v1#5 - // (byte) mul8u::a#1 = (byte) mulu8_sel::v1#5 // register copy reg byte x //SEG229 [114] (byte) mul8u::b#0 ← (byte) mulu8_sel::v2#5 -- vbuaa=vbuyy tya //SEG230 [115] call mul8u jsr mul8u //SEG231 [116] (word) mul8u::return#2 ← (word) mul8u::res#2 - // (word) mul8u::return#2 = (word) mul8u::res#2 // register copy zp ZP_WORD:9 jmp b2 //SEG232 mulu8_sel::@2 b2: //SEG233 [117] (word~) mulu8_sel::$0 ← (word) mul8u::return#2 - // (word~) mulu8_sel::$0 = (word) mul8u::return#2 // register copy zp ZP_WORD:9 //SEG234 [118] (word~) mulu8_sel::$1 ← (word~) mulu8_sel::$0 << (byte) mulu8_sel::select#5 -- vwuz1=vwuz1_rol_vbuz2 ldy select beq !e+ @@ -4214,6 +4233,8 @@ mulu8_sel: { rts } //SEG238 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .label mb = $c .label res = 9 @@ -4283,6 +4304,10 @@ mul8u: { jmp b1 } //SEG262 div16u +// Performs division on two 16 bit unsigned words +// Returns the quotient dividend/divisor. +// The remainder will be set into the global variable rem16u +// Implemented using simple binary division div16u: { .label return = $e //SEG263 [132] call divr16u @@ -4290,12 +4315,10 @@ div16u: { divr16u_from_div16u: jsr divr16u //SEG265 [133] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:14 jmp b2 //SEG266 div16u::@2 b2: //SEG267 [134] (word) div16u::return#0 ← (word) divr16u::return#2 - // (word) div16u::return#0 = (word) divr16u::return#2 // register copy zp ZP_WORD:14 jmp breturn //SEG268 div16u::@return breturn: @@ -4303,6 +4326,10 @@ div16u: { rts } //SEG270 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 5 @@ -4409,7 +4436,6 @@ divr16u: { //SEG303 divr16u::@6 b6: //SEG304 [152] (word) rem16u#1 ← (word) divr16u::rem#10 - // (word) rem16u#1 = (word) divr16u::rem#10 // register copy zp ZP_WORD:2 jmp breturn //SEG305 divr16u::@return breturn: @@ -4527,6 +4553,7 @@ Removing instruction b2_from_b5: Removing instruction b1_from_print_sbyte: Removing instruction print_char_from_b1: Removing instruction b1_from_b1: +Removing instruction b1_from_b3: Removing instruction b1_from_b4: Removing instruction b2_from_b1: Removing instruction b2_from_b6: @@ -4537,11 +4564,13 @@ Removing instruction b4_from_b8: Removing instruction breturn: Removing instruction b4_from_b2: Removing instruction b4_from_b7: +Removing instruction breturn: Removing instruction b1_from_b3: Removing instruction b2_from_b1: Removing instruction b2_from_b4: Removing instruction b3_from_b2: Removing instruction b3_from_b5: +Removing instruction breturn: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction bend: Removing instruction sin8s_gen_from_main: @@ -4564,7 +4593,6 @@ Removing instruction b1_from_print_cls: Removing instruction breturn: Removing instruction div16u_from_sin8s_gen: Removing instruction b3: -Removing instruction b1_from_b3: Removing instruction b4: Removing instruction breturn: Removing instruction b5: @@ -4590,12 +4618,10 @@ Removing instruction b7: Removing instruction b1_from_b4: Removing instruction divr16u_from_div16u: Removing instruction b2: -Removing instruction breturn: Removing instruction b1_from_divr16u: Removing instruction b4: Removing instruction b5: Removing instruction b6: -Removing instruction breturn: Succesful ASM optimization Pass5UnusedLabelElimination Updating BasicUpstart to call main directly Removing instruction jsr main @@ -4969,7 +4995,6 @@ main: { //SEG33 main::@2 b2: //SEG34 [14] (signed byte) print_sbyte::b#1 ← (signed byte) main::sb#0 - // (signed byte) print_sbyte::b#1 = (signed byte) main::sb#0 // register copy zp ZP_BYTE:4 //SEG35 [15] call print_sbyte jsr print_sbyte //SEG36 [16] phi from main::@2 to main::@7 [phi:main::@2->main::@7] @@ -4998,6 +5023,7 @@ main: { sintabref: .byte 0, 4, 8, $c, $11, $15, $19, $1d, $21, $25, $29, $2d, $31, $35, $38, $3c, $40, $43, $47, $4a, $4e, $51, $54, $57, $5a, $5d, $60, $63, $65, $68, $6a, $6c, $6e, $70, $72, $74, $76, $77, $79, $7a, $7b, $7c, $7d, $7e, $7e, $7f, $7f, $7f, $80, $7f, $7f, $7f, $7e, $7e, $7d, $7c, $7b, $7a, $79, $77, $76, $74, $72, $70, $6e, $6c, $6a, $68, $65, $63, $60, $5d, $5a, $57, $54, $51, $4e, $4a, $47, $43, $40, $3c, $38, $35, $31, $2d, $29, $25, $21, $1d, $19, $15, $11, $c, 8, 4, 0, $fc, $f8, $f4, $ef, $eb, $e7, $e3, $df, $db, $d7, $d3, $cf, $cb, $c8, $c4, $c0, $bd, $b9, $b6, $b2, $af, $ac, $a9, $a6, $a3, $a0, $9d, $9b, $98, $96, $94, $92, $90, $8e, $8c, $8a, $89, $87, $86, $85, $84, $83, $82, $82, $81, $81, $81, $81, $81, $81, $81, $82, $82, $83, $84, $85, $86, $87, $89, $8a, $8c, $8e, $90, $92, $94, $96, $98, $9b, $9d, $a0, $a3, $a6, $a9, $ac, $af, $b2, $b6, $b9, $bd, $c0, $c4, $c8, $cb, $cf, $d3, $d7, $db, $df, $e3, $e7, $eb, $ef, $f4, $f8, $fc } //SEG47 print_str +// Print a zero-terminated string print_str: { .label str = 2 //SEG48 [22] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -5032,6 +5058,7 @@ print_str: { jmp b1 } //SEG59 print_sbyte +// Print a signed byte as HEX print_sbyte: { .label b = 4 //SEG60 [28] if((signed byte) print_sbyte::b#1<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsz1_lt_0_then_la1 @@ -5073,6 +5100,7 @@ print_sbyte: { jmp b2 } //SEG81 print_char +// Print a single char print_char: { //SEG82 [38] *((byte*) print_char_cursor#29) ← (byte) print_char::ch#4 -- _deref_pbuz1=vbuaa ldy #0 @@ -5087,6 +5115,7 @@ print_char: { rts } //SEG86 print_byte +// Print a byte as HEX print_byte: { //SEG87 [41] (byte~) print_byte::$0 ← (byte)(signed byte) print_sbyte::b#4 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 lda print_sbyte.b @@ -5119,6 +5148,7 @@ print_byte: { rts } //SEG102 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG103 [49] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -5152,6 +5182,9 @@ print_cls: { rts } //SEG113 sin8s_gen +// Generate signed byte sinus table - on the full -$7f - $7f range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin8s_gen: { .label step = $e .label sintab = 5 @@ -5161,10 +5194,8 @@ sin8s_gen: { //SEG115 [131] phi from sin8s_gen to div16u [phi:sin8s_gen->div16u] jsr div16u //SEG116 [56] (word) div16u::return#2 ← (word) div16u::return#0 - // (word) div16u::return#2 = (word) div16u::return#0 // register copy zp ZP_WORD:14 //SEG117 sin8s_gen::@3 //SEG118 [57] (word) sin8s_gen::step#0 ← (word) div16u::return#2 - // (word) sin8s_gen::step#0 = (word) div16u::return#2 // register copy zp ZP_WORD:14 //SEG119 [58] phi from sin8s_gen::@3 to sin8s_gen::@1 [phi:sin8s_gen::@3->sin8s_gen::@1] //SEG120 [58] phi (word) sin8s_gen::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin8s_gen::@3->sin8s_gen::@1#0] -- vwuz1=vbuc1 lda #<0 @@ -5193,10 +5224,8 @@ sin8s_gen: { //SEG129 [60] call sin8s jsr sin8s //SEG130 [61] (signed byte) sin8s::return#0 ← (signed byte) sin8s::return#1 - // (signed byte) sin8s::return#0 = (signed byte) sin8s::return#1 // register copy reg byte a //SEG131 sin8s_gen::@4 //SEG132 [62] (signed byte~) sin8s_gen::$1 ← (signed byte) sin8s::return#0 - // (signed byte~) sin8s_gen::$1 = (signed byte) sin8s::return#0 // register copy reg byte a //SEG133 [63] *((signed byte*) sin8s_gen::sintab#2) ← (signed byte~) sin8s_gen::$1 -- _deref_pbsz1=vbsaa ldy #0 sta (sintab),y @@ -5232,6 +5261,9 @@ sin8s_gen: { rts } //SEG140 sin8s +// Calculate signed byte sinus sin(x) +// x: unsigned word input u[4.12] in the interval $0000 - PI2_u4f12 +// result: signed byte sin(x) s[0.7] - using the full range -$7f - $7f sin8s: { .const DIV_6 = $2b .label _6 = 9 @@ -5317,10 +5349,8 @@ sin8s: { //SEG165 [112] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#0 [phi:sin8s::@2->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG166 [80] (byte) mulu8_sel::return#0 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#0 = (byte) mulu8_sel::return#12 // register copy reg byte a //SEG167 sin8s::@10 //SEG168 [81] (byte) sin8s::x2#0 ← (byte) mulu8_sel::return#0 - // (byte) sin8s::x2#0 = (byte) mulu8_sel::return#0 // register copy reg byte a //SEG169 [82] (byte) mulu8_sel::v1#1 ← (byte) sin8s::x2#0 -- vbuxx=vbuaa tax //SEG170 [83] (byte) mulu8_sel::v2#1 ← (byte) sin8s::x1#0 -- vbuyy=vbuz1 @@ -5334,7 +5364,6 @@ sin8s: { //SEG175 [112] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#1 [phi:sin8s::@10->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG176 [85] (byte) mulu8_sel::return#1 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#1 = (byte) mulu8_sel::return#12 // register copy reg byte a //SEG177 sin8s::@11 //SEG178 [86] (byte) sin8s::x3#0 ← (byte) mulu8_sel::return#1 -- vbuz1=vbuaa sta x3 @@ -5350,10 +5379,8 @@ sin8s: { //SEG184 [112] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#2 [phi:sin8s::@11->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG185 [89] (byte) mulu8_sel::return#2 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#2 = (byte) mulu8_sel::return#12 // register copy reg byte a //SEG186 sin8s::@12 //SEG187 [90] (byte) sin8s::x3_6#0 ← (byte) mulu8_sel::return#2 - // (byte) sin8s::x3_6#0 = (byte) mulu8_sel::return#2 // register copy reg byte a //SEG188 [91] (byte) sin8s::usinx#0 ← (byte) sin8s::x1#0 - (byte) sin8s::x3_6#0 -- vbuz1=vbuz2_minus_vbuaa eor #$ff sec @@ -5372,10 +5399,8 @@ sin8s: { //SEG195 [112] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#3 [phi:sin8s::@12->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG196 [95] (byte) mulu8_sel::return#10 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#10 = (byte) mulu8_sel::return#12 // register copy reg byte a //SEG197 sin8s::@13 //SEG198 [96] (byte) sin8s::x4#0 ← (byte) mulu8_sel::return#10 - // (byte) sin8s::x4#0 = (byte) mulu8_sel::return#10 // register copy reg byte a //SEG199 [97] (byte) mulu8_sel::v1#4 ← (byte) sin8s::x4#0 -- vbuxx=vbuaa tax //SEG200 [98] (byte) mulu8_sel::v2#4 ← (byte) sin8s::x1#0 -- vbuyy=vbuz1 @@ -5389,10 +5414,8 @@ sin8s: { //SEG205 [112] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#4 [phi:sin8s::@13->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG206 [100] (byte) mulu8_sel::return#11 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#11 = (byte) mulu8_sel::return#12 // register copy reg byte a //SEG207 sin8s::@14 //SEG208 [101] (byte) sin8s::x5#0 ← (byte) mulu8_sel::return#11 - // (byte) sin8s::x5#0 = (byte) mulu8_sel::return#11 // register copy reg byte a //SEG209 [102] (byte) sin8s::x5_128#0 ← (byte) sin8s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuaa_ror_4 lsr lsr @@ -5436,21 +5459,20 @@ sin8s: { jmp b4 } //SEG227 mulu8_sel +// 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: { .label _0 = 9 .label _1 = 9 .label select = $b //SEG228 [113] (byte) mul8u::a#1 ← (byte) mulu8_sel::v1#5 - // (byte) mul8u::a#1 = (byte) mulu8_sel::v1#5 // register copy reg byte x //SEG229 [114] (byte) mul8u::b#0 ← (byte) mulu8_sel::v2#5 -- vbuaa=vbuyy tya //SEG230 [115] call mul8u jsr mul8u //SEG231 [116] (word) mul8u::return#2 ← (word) mul8u::res#2 - // (word) mul8u::return#2 = (word) mul8u::res#2 // register copy zp ZP_WORD:9 //SEG232 mulu8_sel::@2 //SEG233 [117] (word~) mulu8_sel::$0 ← (word) mul8u::return#2 - // (word~) mulu8_sel::$0 = (word) mul8u::return#2 // register copy zp ZP_WORD:9 //SEG234 [118] (word~) mulu8_sel::$1 ← (word~) mulu8_sel::$0 << (byte) mulu8_sel::select#5 -- vwuz1=vwuz1_rol_vbuz2 ldy select beq !e+ @@ -5467,6 +5489,8 @@ mulu8_sel: { rts } //SEG238 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .label mb = $c .label res = 9 @@ -5524,21 +5548,27 @@ mul8u: { jmp b1 } //SEG262 div16u +// Performs division on two 16 bit unsigned words +// Returns the quotient dividend/divisor. +// The remainder will be set into the global variable rem16u +// Implemented using simple binary division div16u: { .label return = $e //SEG263 [132] call divr16u //SEG264 [136] phi from div16u to divr16u [phi:div16u->divr16u] jsr divr16u //SEG265 [133] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:14 //SEG266 div16u::@2 //SEG267 [134] (word) div16u::return#0 ← (word) divr16u::return#2 - // (word) div16u::return#0 = (word) divr16u::return#2 // register copy zp ZP_WORD:14 //SEG268 div16u::@return //SEG269 [135] return rts } //SEG270 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 5 @@ -5627,7 +5657,6 @@ divr16u: { bne b1 //SEG303 divr16u::@6 //SEG304 [152] (word) rem16u#1 ← (word) divr16u::rem#10 - // (word) rem16u#1 = (word) divr16u::rem#10 // register copy zp ZP_WORD:2 //SEG305 divr16u::@return //SEG306 [153] return rts diff --git a/src/test/ref/sinusgen8b.asm b/src/test/ref/sinusgen8b.asm index f48607686..6e23ee56e 100644 --- a/src/test/ref/sinusgen8b.asm +++ b/src/test/ref/sinusgen8b.asm @@ -74,6 +74,7 @@ main: { sintabb: .fill $c0, 0 sintabw: .fill 2*$c0, 0 } +// Print a zero-terminated string print_str: { .label str = 2 b1: @@ -96,6 +97,7 @@ print_str: { !: jmp b1 } +// Print a signed byte as HEX print_sbyte: { .label b = 4 lda b @@ -115,6 +117,7 @@ print_sbyte: { sta b jmp b2 } +// Print a single char print_char: { ldy #0 sta (print_char_cursor),y @@ -124,6 +127,7 @@ print_char: { !: rts } +// Print a byte as HEX print_byte: { lda print_sbyte.b lsr @@ -140,6 +144,7 @@ print_byte: { jsr print_char rts } +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 lda #print_str::@1] @@ -3723,6 +3724,7 @@ print_str: { jmp b1_from_b2 } //SEG69 print_sbyte +// Print a signed byte as HEX print_sbyte: { .label b = 5 //SEG70 [36] if((signed byte) print_sbyte::b#1<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsz1_lt_0_then_la1 @@ -3780,6 +3782,7 @@ print_sbyte: { jmp b2_from_b5 } //SEG91 print_char +// Print a single char print_char: { .label ch = 6 //SEG92 [46] *((byte*) print_char_cursor#29) ← (byte) print_char::ch#4 -- _deref_pbuz1=vbuz2 @@ -3798,6 +3801,7 @@ print_char: { rts } //SEG96 print_byte +// Print a byte as HEX print_byte: { .label _0 = $4e .label _2 = $4f @@ -3842,6 +3846,7 @@ print_byte: { rts } //SEG112 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 9 //SEG113 [57] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -3881,6 +3886,9 @@ print_cls: { rts } //SEG123 sin16s_gen +// Generate signed (large) word sinus table - on the full -$7fff - $7fff range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen: { .label _1 = $5a .label step = $54 @@ -4014,6 +4022,9 @@ sin16s_gen: { rts } //SEG150 sin16s +// 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: { .label _6 = $5c .label x = $14 @@ -4369,6 +4380,8 @@ sin16s: { jmp b3_from_b15 } //SEG231 mulu16_sel +// 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: { .label _0 = $82 .label _1 = $86 @@ -4445,6 +4458,7 @@ mulu16_sel: { rts } //SEG242 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label _1 = $8c .label mb = $25 @@ -4535,6 +4549,8 @@ mul16u: { jmp b1 } //SEG266 div32u16u +// 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 = $8f .label quotient_lo = $93 @@ -4611,6 +4627,10 @@ div32u16u: { rts } //SEG285 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label _1 = $99 .label _2 = $9a @@ -4732,6 +4752,9 @@ divr16u: { rts } //SEG322 sin8s_gen +// Generate signed byte sinus table - on the full -$7f - $7f range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin8s_gen: { .label _1 = $a2 .label step = $9f @@ -4835,6 +4858,9 @@ sin8s_gen: { rts } //SEG349 sin8s +// Calculate signed byte sinus sin(x) +// x: unsigned word input u[4.12] in the interval $0000 - PI2_u4f12 +// result: signed byte sin(x) s[0.7] - using the full range -$7f - $7f sin8s: { .const DIV_6 = $2b .label _6 = $a3 @@ -5117,6 +5143,8 @@ sin8s: { jmp b4_from_b18 } //SEG436 mulu8_sel +// 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: { .label _0 = $b5 .label _1 = $b7 @@ -5173,6 +5201,8 @@ mulu8_sel: { rts } //SEG447 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .label _1 = $ba .label mb = $41 @@ -5247,6 +5277,10 @@ mul8u: { jmp b1 } //SEG471 div16u +// Performs division on two 16 bit unsigned words +// Returns the quotient dividend/divisor. +// The remainder will be set into the global variable rem16u +// Implemented using simple binary division div16u: { .label return = $bd .label return_2 = $9d @@ -5897,7 +5931,6 @@ main: { //SEG43 main::@2 b2: //SEG44 [22] (signed byte) print_sbyte::b#1 ← (signed byte) main::sd#0 - // (signed byte) print_sbyte::b#1 = (signed byte) main::sd#0 // register copy zp ZP_BYTE:4 //SEG45 [23] call print_sbyte jsr print_sbyte //SEG46 [24] phi from main::@2 to main::@8 [phi:main::@2->main::@8] @@ -5934,6 +5967,7 @@ main: { sintabw: .fill 2*$c0, 0 } //SEG57 print_str +// Print a zero-terminated string print_str: { .label str = 2 //SEG58 [30] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -5974,6 +6008,7 @@ print_str: { jmp b1_from_b2 } //SEG69 print_sbyte +// Print a signed byte as HEX print_sbyte: { .label b = 4 //SEG70 [36] if((signed byte) print_sbyte::b#1<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsz1_lt_0_then_la1 @@ -6029,6 +6064,7 @@ print_sbyte: { jmp b2_from_b5 } //SEG91 print_char +// Print a single char print_char: { //SEG92 [46] *((byte*) print_char_cursor#29) ← (byte) print_char::ch#4 -- _deref_pbuz1=vbuaa ldy #0 @@ -6045,6 +6081,7 @@ print_char: { rts } //SEG96 print_byte +// Print a byte as HEX print_byte: { //SEG97 [49] (byte~) print_byte::$0 ← (byte)(signed byte) print_sbyte::b#4 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 lda print_sbyte.b @@ -6083,6 +6120,7 @@ print_byte: { rts } //SEG112 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG113 [57] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -6122,6 +6160,9 @@ print_cls: { rts } //SEG123 sin16s_gen +// Generate signed (large) word sinus table - on the full -$7fff - $7fff range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen: { .label _1 = $f .label step = $1c @@ -6133,12 +6174,10 @@ sin16s_gen: { div32u16u_from_sin16s_gen: jsr div32u16u //SEG126 [64] (dword) div32u16u::return#2 ← (dword) div32u16u::return#0 - // (dword) div32u16u::return#2 = (dword) div32u16u::return#0 // register copy zp ZP_DWORD:28 jmp b3 //SEG127 sin16s_gen::@3 b3: //SEG128 [65] (dword) sin16s_gen::step#0 ← (dword) div32u16u::return#2 - // (dword) sin16s_gen::step#0 = (dword) div32u16u::return#2 // register copy zp ZP_DWORD:28 //SEG129 [66] phi from sin16s_gen::@3 to sin16s_gen::@1 [phi:sin16s_gen::@3->sin16s_gen::@1] b1_from_b3: //SEG130 [66] phi (word) sin16s_gen::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin16s_gen::@3->sin16s_gen::@1#0] -- vwuz1=vbuc1 @@ -6179,12 +6218,10 @@ sin16s_gen: { //SEG139 [68] call sin16s jsr sin16s //SEG140 [69] (signed word) sin16s::return#0 ← (signed word) sin16s::return#1 - // (signed word) sin16s::return#0 = (signed word) sin16s::return#1 // register copy zp ZP_WORD:15 jmp b4 //SEG141 sin16s_gen::@4 b4: //SEG142 [70] (signed word~) sin16s_gen::$1 ← (signed word) sin16s::return#0 - // (signed word~) sin16s_gen::$1 = (signed word) sin16s::return#0 // register copy zp ZP_WORD:15 //SEG143 [71] *((signed word*) sin16s_gen::sintab#2) ← (signed word~) sin16s_gen::$1 -- _deref_pwsz1=vwsz2 ldy #0 lda _1 @@ -6235,6 +6272,9 @@ sin16s_gen: { rts } //SEG150 sin16s +// 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: { .label _6 = $b .label x = $b @@ -6373,7 +6413,6 @@ sin16s: { //SEG175 [117] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#0 [phi:sin16s::@2->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG176 [88] (word) mulu16_sel::return#0 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#0 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:19 jmp b8 //SEG177 sin16s::@8 b8: @@ -6383,7 +6422,6 @@ sin16s: { lda mulu16_sel.return+1 sta x2+1 //SEG179 [90] (word) mulu16_sel::v1#1 ← (word) sin16s::x2#0 - // (word) mulu16_sel::v1#1 = (word) sin16s::x2#0 // register copy zp ZP_WORD:17 //SEG180 [91] (word) mulu16_sel::v2#1 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -6406,9 +6444,7 @@ sin16s: { //SEG187 sin16s::@9 b9: //SEG188 [94] (word) sin16s::x3#0 ← (word) mulu16_sel::return#1 - // (word) sin16s::x3#0 = (word) mulu16_sel::return#1 // register copy zp ZP_WORD:17 //SEG189 [95] (word) mulu16_sel::v1#2 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#2 = (word) sin16s::x3#0 // register copy zp ZP_WORD:17 //SEG190 [96] call mulu16_sel //SEG191 [117] phi from sin16s::@9 to mulu16_sel [phi:sin16s::@9->mulu16_sel] mulu16_sel_from_b9: @@ -6422,12 +6458,10 @@ sin16s: { //SEG194 [117] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#2 [phi:sin16s::@9->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG195 [97] (word) mulu16_sel::return#2 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#2 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:19 jmp b10 //SEG196 sin16s::@10 b10: //SEG197 [98] (word) sin16s::x3_6#0 ← (word) mulu16_sel::return#2 - // (word) sin16s::x3_6#0 = (word) mulu16_sel::return#2 // register copy zp ZP_WORD:19 //SEG198 [99] (word) sin16s::usinx#0 ← (word) sin16s::x1#0 - (word) sin16s::x3_6#0 -- vwuz1=vwuz2_minus_vwuz3 lda x1 sec @@ -6437,7 +6471,6 @@ sin16s: { sbc x3_6+1 sta usinx+1 //SEG199 [100] (word) mulu16_sel::v1#3 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#3 = (word) sin16s::x3#0 // register copy zp ZP_WORD:17 //SEG200 [101] (word) mulu16_sel::v2#3 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -6460,9 +6493,7 @@ sin16s: { //SEG207 sin16s::@11 b11: //SEG208 [104] (word) sin16s::x4#0 ← (word) mulu16_sel::return#10 - // (word) sin16s::x4#0 = (word) mulu16_sel::return#10 // register copy zp ZP_WORD:17 //SEG209 [105] (word) mulu16_sel::v1#4 ← (word) sin16s::x4#0 - // (word) mulu16_sel::v1#4 = (word) sin16s::x4#0 // register copy zp ZP_WORD:17 //SEG210 [106] (word) mulu16_sel::v2#4 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -6477,12 +6508,10 @@ sin16s: { //SEG215 [117] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#4 [phi:sin16s::@11->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG216 [108] (word) mulu16_sel::return#11 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#11 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:19 jmp b12 //SEG217 sin16s::@12 b12: //SEG218 [109] (word) sin16s::x5#0 ← (word) mulu16_sel::return#11 - // (word) sin16s::x5#0 = (word) mulu16_sel::return#11 // register copy zp ZP_WORD:19 //SEG219 [110] (word) sin16s::x5_128#0 ← (word) sin16s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vwuz1=vwuz1_ror_4 ldy #4 !: @@ -6530,10 +6559,11 @@ sin16s: { //SEG229 sin16s::@15 b15: //SEG230 [116] (signed word~) sin16s::return#5 ← (signed word)(word) sin16s::usinx#1 - // (signed word~) sin16s::return#5 = (signed word)(word) sin16s::usinx#1 // register copy zp ZP_WORD:15 jmp b3_from_b15 } //SEG231 mulu16_sel +// 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: { .label _0 = $b .label _1 = $b @@ -6548,16 +6578,13 @@ mulu16_sel: { lda v1+1 sta mul16u.a+1 //SEG233 [119] (word) mul16u::b#0 ← (word) mulu16_sel::v2#5 - // (word) mul16u::b#0 = (word) mulu16_sel::v2#5 // register copy zp ZP_WORD:19 //SEG234 [120] call mul16u jsr mul16u //SEG235 [121] (dword) mul16u::return#2 ← (dword) mul16u::res#2 - // (dword) mul16u::return#2 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:11 jmp b2 //SEG236 mulu16_sel::@2 b2: //SEG237 [122] (dword~) mulu16_sel::$0 ← (dword) mul16u::return#2 - // (dword~) mulu16_sel::$0 = (dword) mul16u::return#2 // register copy zp ZP_DWORD:11 //SEG238 [123] (dword~) mulu16_sel::$1 ← (dword~) mulu16_sel::$0 << (byte) mulu16_sel::select#5 -- vduz1=vduz1_rol_vbuxx cpx #0 beq !e+ @@ -6581,6 +6608,7 @@ mulu16_sel: { rts } //SEG242 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label mb = $17 .label a = $15 @@ -6668,6 +6696,8 @@ mul16u: { jmp b1 } //SEG266 div32u16u +// 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_lo = $f @@ -6687,7 +6717,6 @@ div32u16u: { sta divr16u.rem+1 jsr divr16u //SEG271 [138] (word) divr16u::return#3 ← (word) divr16u::return#0 - // (word) divr16u::return#3 = (word) divr16u::return#0 // register copy zp ZP_WORD:15 jmp b2 //SEG272 div32u16u::@2 b2: @@ -6697,7 +6726,6 @@ div32u16u: { lda divr16u.return+1 sta quotient_hi+1 //SEG274 [140] (word) divr16u::rem#5 ← (word) rem16u#1 - // (word) divr16u::rem#5 = (word) rem16u#1 // register copy zp ZP_WORD:2 //SEG275 [141] call divr16u //SEG276 [146] phi from div32u16u::@2 to divr16u [phi:div32u16u::@2->divr16u] divr16u_from_b2: @@ -6709,12 +6737,10 @@ div32u16u: { //SEG278 [146] phi (word) divr16u::rem#11 = (word) divr16u::rem#5 [phi:div32u16u::@2->divr16u#1] -- register_copy jsr divr16u //SEG279 [142] (word) divr16u::return#4 ← (word) divr16u::return#0 - // (word) divr16u::return#4 = (word) divr16u::return#0 // register copy zp ZP_WORD:15 jmp b3 //SEG280 div32u16u::@3 b3: //SEG281 [143] (word) div32u16u::quotient_lo#0 ← (word) divr16u::return#4 - // (word) div32u16u::quotient_lo#0 = (word) divr16u::return#4 // register copy zp ZP_WORD:15 //SEG282 [144] (dword) div32u16u::return#0 ← (word) div32u16u::quotient_hi#0 dw= (word) div32u16u::quotient_lo#0 -- vduz1=vwuz2_dword_vwuz3 lda quotient_hi sta return+2 @@ -6731,6 +6757,10 @@ div32u16u: { rts } //SEG285 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 5 @@ -6829,7 +6859,6 @@ divr16u: { //SEG318 divr16u::@6 b6: //SEG319 [162] (word) rem16u#1 ← (word) divr16u::rem#10 - // (word) rem16u#1 = (word) divr16u::rem#10 // register copy zp ZP_WORD:2 jmp breturn //SEG320 divr16u::@return breturn: @@ -6837,6 +6866,9 @@ divr16u: { rts } //SEG322 sin8s_gen +// Generate signed byte sinus table - on the full -$7f - $7f range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin8s_gen: { .label step = $f .label sintab = 5 @@ -6847,12 +6879,10 @@ sin8s_gen: { div16u_from_sin8s_gen: jsr div16u //SEG325 [166] (word) div16u::return#2 ← (word) div16u::return#0 - // (word) div16u::return#2 = (word) div16u::return#0 // register copy zp ZP_WORD:15 jmp b3 //SEG326 sin8s_gen::@3 b3: //SEG327 [167] (word) sin8s_gen::step#0 ← (word) div16u::return#2 - // (word) sin8s_gen::step#0 = (word) div16u::return#2 // register copy zp ZP_WORD:15 //SEG328 [168] phi from sin8s_gen::@3 to sin8s_gen::@1 [phi:sin8s_gen::@3->sin8s_gen::@1] b1_from_b3: //SEG329 [168] phi (word) sin8s_gen::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin8s_gen::@3->sin8s_gen::@1#0] -- vwuz1=vbuc1 @@ -6887,12 +6917,10 @@ sin8s_gen: { //SEG338 [170] call sin8s jsr sin8s //SEG339 [171] (signed byte) sin8s::return#0 ← (signed byte) sin8s::return#1 - // (signed byte) sin8s::return#0 = (signed byte) sin8s::return#1 // register copy reg byte a jmp b4 //SEG340 sin8s_gen::@4 b4: //SEG341 [172] (signed byte~) sin8s_gen::$1 ← (signed byte) sin8s::return#0 - // (signed byte~) sin8s_gen::$1 = (signed byte) sin8s::return#0 // register copy reg byte a //SEG342 [173] *((signed byte*) sin8s_gen::sintab#2) ← (signed byte~) sin8s_gen::$1 -- _deref_pbsz1=vbsaa ldy #0 sta (sintab),y @@ -6930,6 +6958,9 @@ sin8s_gen: { rts } //SEG349 sin8s +// Calculate signed byte sinus sin(x) +// x: unsigned word input u[4.12] in the interval $0000 - PI2_u4f12 +// result: signed byte sin(x) s[0.7] - using the full range -$7f - $7f sin8s: { .const DIV_6 = $2b .label _6 = $13 @@ -7025,12 +7056,10 @@ sin8s: { //SEG374 [222] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#0 [phi:sin8s::@2->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG375 [190] (byte) mulu8_sel::return#0 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#0 = (byte) mulu8_sel::return#12 // register copy reg byte a jmp b10 //SEG376 sin8s::@10 b10: //SEG377 [191] (byte) sin8s::x2#0 ← (byte) mulu8_sel::return#0 - // (byte) sin8s::x2#0 = (byte) mulu8_sel::return#0 // register copy reg byte a //SEG378 [192] (byte) mulu8_sel::v1#1 ← (byte) sin8s::x2#0 -- vbuxx=vbuaa tax //SEG379 [193] (byte) mulu8_sel::v2#1 ← (byte) sin8s::x1#0 -- vbuyy=vbuz1 @@ -7045,7 +7074,6 @@ sin8s: { //SEG384 [222] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#1 [phi:sin8s::@10->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG385 [195] (byte) mulu8_sel::return#1 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#1 = (byte) mulu8_sel::return#12 // register copy reg byte a jmp b11 //SEG386 sin8s::@11 b11: @@ -7064,12 +7092,10 @@ sin8s: { //SEG393 [222] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#2 [phi:sin8s::@11->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG394 [199] (byte) mulu8_sel::return#2 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#2 = (byte) mulu8_sel::return#12 // register copy reg byte a jmp b12 //SEG395 sin8s::@12 b12: //SEG396 [200] (byte) sin8s::x3_6#0 ← (byte) mulu8_sel::return#2 - // (byte) sin8s::x3_6#0 = (byte) mulu8_sel::return#2 // register copy reg byte a //SEG397 [201] (byte) sin8s::usinx#0 ← (byte) sin8s::x1#0 - (byte) sin8s::x3_6#0 -- vbuz1=vbuz2_minus_vbuaa eor #$ff sec @@ -7089,12 +7115,10 @@ sin8s: { //SEG404 [222] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#3 [phi:sin8s::@12->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG405 [205] (byte) mulu8_sel::return#10 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#10 = (byte) mulu8_sel::return#12 // register copy reg byte a jmp b13 //SEG406 sin8s::@13 b13: //SEG407 [206] (byte) sin8s::x4#0 ← (byte) mulu8_sel::return#10 - // (byte) sin8s::x4#0 = (byte) mulu8_sel::return#10 // register copy reg byte a //SEG408 [207] (byte) mulu8_sel::v1#4 ← (byte) sin8s::x4#0 -- vbuxx=vbuaa tax //SEG409 [208] (byte) mulu8_sel::v2#4 ← (byte) sin8s::x1#0 -- vbuyy=vbuz1 @@ -7109,12 +7133,10 @@ sin8s: { //SEG414 [222] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#4 [phi:sin8s::@13->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG415 [210] (byte) mulu8_sel::return#11 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#11 = (byte) mulu8_sel::return#12 // register copy reg byte a jmp b14 //SEG416 sin8s::@14 b14: //SEG417 [211] (byte) sin8s::x5#0 ← (byte) mulu8_sel::return#11 - // (byte) sin8s::x5#0 = (byte) mulu8_sel::return#11 // register copy reg byte a //SEG418 [212] (byte) sin8s::x5_128#0 ← (byte) sin8s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuaa_ror_4 lsr lsr @@ -7170,23 +7192,22 @@ sin8s: { jmp b4_from_b18 } //SEG436 mulu8_sel +// 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: { .label _0 = $13 .label _1 = $13 .label select = $1b //SEG437 [223] (byte) mul8u::a#1 ← (byte) mulu8_sel::v1#5 - // (byte) mul8u::a#1 = (byte) mulu8_sel::v1#5 // register copy reg byte x //SEG438 [224] (byte) mul8u::b#0 ← (byte) mulu8_sel::v2#5 -- vbuaa=vbuyy tya //SEG439 [225] call mul8u jsr mul8u //SEG440 [226] (word) mul8u::return#2 ← (word) mul8u::res#2 - // (word) mul8u::return#2 = (word) mul8u::res#2 // register copy zp ZP_WORD:19 jmp b2 //SEG441 mulu8_sel::@2 b2: //SEG442 [227] (word~) mulu8_sel::$0 ← (word) mul8u::return#2 - // (word~) mulu8_sel::$0 = (word) mul8u::return#2 // register copy zp ZP_WORD:19 //SEG443 [228] (word~) mulu8_sel::$1 ← (word~) mulu8_sel::$0 << (byte) mulu8_sel::select#5 -- vwuz1=vwuz1_rol_vbuz2 ldy select beq !e+ @@ -7205,6 +7226,8 @@ mulu8_sel: { rts } //SEG447 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .label mb = $15 .label res = $13 @@ -7274,6 +7297,10 @@ mul8u: { jmp b1 } //SEG471 div16u +// Performs division on two 16 bit unsigned words +// Returns the quotient dividend/divisor. +// The remainder will be set into the global variable rem16u +// Implemented using simple binary division div16u: { .label return = $f //SEG472 [242] call divr16u @@ -7291,12 +7318,10 @@ div16u: { sta divr16u.rem+1 jsr divr16u //SEG476 [243] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:15 jmp b2 //SEG477 div16u::@2 b2: //SEG478 [244] (word) div16u::return#0 ← (word) divr16u::return#2 - // (word) div16u::return#0 = (word) divr16u::return#2 // register copy zp ZP_WORD:15 jmp breturn //SEG479 div16u::@return breturn: @@ -7454,9 +7479,11 @@ Removing instruction b2_from_b5: Removing instruction b1_from_print_sbyte: Removing instruction print_char_from_b1: Removing instruction b1_from_b1: +Removing instruction b1_from_b3: Removing instruction b1_from_b4: Removing instruction b2_from_b1: Removing instruction b2_from_b5: +Removing instruction mulu16_sel_from_b9: Removing instruction b3_from_b15: Removing instruction b3_from_b6: Removing instruction breturn: @@ -7467,6 +7494,8 @@ Removing instruction b2_from_b1: Removing instruction b2_from_b4: Removing instruction b3_from_b2: Removing instruction b3_from_b5: +Removing instruction breturn: +Removing instruction b1_from_b3: Removing instruction b1_from_b4: Removing instruction b2_from_b1: Removing instruction b2_from_b6: @@ -7477,6 +7506,7 @@ Removing instruction b4_from_b8: Removing instruction breturn: Removing instruction b4_from_b2: Removing instruction b4_from_b7: +Removing instruction breturn: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction bend: Removing instruction sin8s_gen_from_main: @@ -7500,7 +7530,6 @@ Removing instruction b1_from_print_cls: Removing instruction breturn: Removing instruction div32u16u_from_sin16s_gen: Removing instruction b3: -Removing instruction b1_from_b3: Removing instruction b4: Removing instruction breturn: Removing instruction b4: @@ -7510,7 +7539,6 @@ Removing instruction mulu16_sel_from_b2: Removing instruction b8: Removing instruction mulu16_sel_from_b8: Removing instruction b9: -Removing instruction mulu16_sel_from_b9: Removing instruction b10: Removing instruction mulu16_sel_from_b10: Removing instruction b11: @@ -7532,10 +7560,8 @@ Removing instruction b1_from_divr16u: Removing instruction b4: Removing instruction b5: Removing instruction b6: -Removing instruction breturn: Removing instruction div16u_from_sin8s_gen: Removing instruction b3: -Removing instruction b1_from_b3: Removing instruction b4: Removing instruction breturn: Removing instruction b5: @@ -7561,7 +7587,6 @@ Removing instruction b7: Removing instruction b1_from_b4: Removing instruction divr16u_from_div16u: Removing instruction b2: -Removing instruction breturn: Succesful ASM optimization Pass5UnusedLabelElimination Updating BasicUpstart to call main directly Removing instruction jsr main @@ -8136,7 +8161,6 @@ main: { //SEG43 main::@2 b2: //SEG44 [22] (signed byte) print_sbyte::b#1 ← (signed byte) main::sd#0 - // (signed byte) print_sbyte::b#1 = (signed byte) main::sd#0 // register copy zp ZP_BYTE:4 //SEG45 [23] call print_sbyte jsr print_sbyte //SEG46 [24] phi from main::@2 to main::@8 [phi:main::@2->main::@8] @@ -8165,6 +8189,7 @@ main: { sintabw: .fill 2*$c0, 0 } //SEG57 print_str +// Print a zero-terminated string print_str: { .label str = 2 //SEG58 [30] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -8199,6 +8224,7 @@ print_str: { jmp b1 } //SEG69 print_sbyte +// Print a signed byte as HEX print_sbyte: { .label b = 4 //SEG70 [36] if((signed byte) print_sbyte::b#1<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsz1_lt_0_then_la1 @@ -8240,6 +8266,7 @@ print_sbyte: { jmp b2 } //SEG91 print_char +// Print a single char print_char: { //SEG92 [46] *((byte*) print_char_cursor#29) ← (byte) print_char::ch#4 -- _deref_pbuz1=vbuaa ldy #0 @@ -8254,6 +8281,7 @@ print_char: { rts } //SEG96 print_byte +// Print a byte as HEX print_byte: { //SEG97 [49] (byte~) print_byte::$0 ← (byte)(signed byte) print_sbyte::b#4 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 lda print_sbyte.b @@ -8286,6 +8314,7 @@ print_byte: { rts } //SEG112 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG113 [57] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -8319,6 +8348,9 @@ print_cls: { rts } //SEG123 sin16s_gen +// Generate signed (large) word sinus table - on the full -$7fff - $7fff range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin16s_gen: { .label _1 = $f .label step = $1c @@ -8329,10 +8361,8 @@ sin16s_gen: { //SEG125 [136] phi from sin16s_gen to div32u16u [phi:sin16s_gen->div32u16u] jsr div32u16u //SEG126 [64] (dword) div32u16u::return#2 ← (dword) div32u16u::return#0 - // (dword) div32u16u::return#2 = (dword) div32u16u::return#0 // register copy zp ZP_DWORD:28 //SEG127 sin16s_gen::@3 //SEG128 [65] (dword) sin16s_gen::step#0 ← (dword) div32u16u::return#2 - // (dword) sin16s_gen::step#0 = (dword) div32u16u::return#2 // register copy zp ZP_DWORD:28 //SEG129 [66] phi from sin16s_gen::@3 to sin16s_gen::@1 [phi:sin16s_gen::@3->sin16s_gen::@1] //SEG130 [66] phi (word) sin16s_gen::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin16s_gen::@3->sin16s_gen::@1#0] -- vwuz1=vbuc1 lda #<0 @@ -8367,10 +8397,8 @@ sin16s_gen: { //SEG139 [68] call sin16s jsr sin16s //SEG140 [69] (signed word) sin16s::return#0 ← (signed word) sin16s::return#1 - // (signed word) sin16s::return#0 = (signed word) sin16s::return#1 // register copy zp ZP_WORD:15 //SEG141 sin16s_gen::@4 //SEG142 [70] (signed word~) sin16s_gen::$1 ← (signed word) sin16s::return#0 - // (signed word~) sin16s_gen::$1 = (signed word) sin16s::return#0 // register copy zp ZP_WORD:15 //SEG143 [71] *((signed word*) sin16s_gen::sintab#2) ← (signed word~) sin16s_gen::$1 -- _deref_pwsz1=vwsz2 ldy #0 lda _1 @@ -8419,6 +8447,9 @@ sin16s_gen: { rts } //SEG150 sin16s +// 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: { .label _6 = $b .label x = $b @@ -8547,7 +8578,6 @@ sin16s: { //SEG175 [117] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#0 [phi:sin16s::@2->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG176 [88] (word) mulu16_sel::return#0 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#0 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:19 //SEG177 sin16s::@8 //SEG178 [89] (word) sin16s::x2#0 ← (word) mulu16_sel::return#0 -- vwuz1=vwuz2 lda mulu16_sel.return @@ -8555,7 +8585,6 @@ sin16s: { lda mulu16_sel.return+1 sta x2+1 //SEG179 [90] (word) mulu16_sel::v1#1 ← (word) sin16s::x2#0 - // (word) mulu16_sel::v1#1 = (word) sin16s::x2#0 // register copy zp ZP_WORD:17 //SEG180 [91] (word) mulu16_sel::v2#1 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -8575,9 +8604,7 @@ sin16s: { sta mulu16_sel.return_1+1 //SEG187 sin16s::@9 //SEG188 [94] (word) sin16s::x3#0 ← (word) mulu16_sel::return#1 - // (word) sin16s::x3#0 = (word) mulu16_sel::return#1 // register copy zp ZP_WORD:17 //SEG189 [95] (word) mulu16_sel::v1#2 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#2 = (word) sin16s::x3#0 // register copy zp ZP_WORD:17 //SEG190 [96] call mulu16_sel //SEG191 [117] phi from sin16s::@9 to mulu16_sel [phi:sin16s::@9->mulu16_sel] //SEG192 [117] phi (byte) mulu16_sel::select#5 = (byte/signed byte/word/signed word/dword/signed dword) 1 [phi:sin16s::@9->mulu16_sel#0] -- vbuxx=vbuc1 @@ -8590,10 +8617,8 @@ sin16s: { //SEG194 [117] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#2 [phi:sin16s::@9->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG195 [97] (word) mulu16_sel::return#2 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#2 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:19 //SEG196 sin16s::@10 //SEG197 [98] (word) sin16s::x3_6#0 ← (word) mulu16_sel::return#2 - // (word) sin16s::x3_6#0 = (word) mulu16_sel::return#2 // register copy zp ZP_WORD:19 //SEG198 [99] (word) sin16s::usinx#0 ← (word) sin16s::x1#0 - (word) sin16s::x3_6#0 -- vwuz1=vwuz2_minus_vwuz3 lda x1 sec @@ -8603,7 +8628,6 @@ sin16s: { sbc x3_6+1 sta usinx+1 //SEG199 [100] (word) mulu16_sel::v1#3 ← (word) sin16s::x3#0 - // (word) mulu16_sel::v1#3 = (word) sin16s::x3#0 // register copy zp ZP_WORD:17 //SEG200 [101] (word) mulu16_sel::v2#3 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -8623,9 +8647,7 @@ sin16s: { sta mulu16_sel.return_10+1 //SEG207 sin16s::@11 //SEG208 [104] (word) sin16s::x4#0 ← (word) mulu16_sel::return#10 - // (word) sin16s::x4#0 = (word) mulu16_sel::return#10 // register copy zp ZP_WORD:17 //SEG209 [105] (word) mulu16_sel::v1#4 ← (word) sin16s::x4#0 - // (word) mulu16_sel::v1#4 = (word) sin16s::x4#0 // register copy zp ZP_WORD:17 //SEG210 [106] (word) mulu16_sel::v2#4 ← (word) sin16s::x1#0 -- vwuz1=vwuz2 lda x1 sta mulu16_sel.v2 @@ -8639,10 +8661,8 @@ sin16s: { //SEG215 [117] phi (word) mulu16_sel::v1#5 = (word) mulu16_sel::v1#4 [phi:sin16s::@11->mulu16_sel#2] -- register_copy jsr mulu16_sel //SEG216 [108] (word) mulu16_sel::return#11 ← (word) mulu16_sel::return#12 - // (word) mulu16_sel::return#11 = (word) mulu16_sel::return#12 // register copy zp ZP_WORD:19 //SEG217 sin16s::@12 //SEG218 [109] (word) sin16s::x5#0 ← (word) mulu16_sel::return#11 - // (word) sin16s::x5#0 = (word) mulu16_sel::return#11 // register copy zp ZP_WORD:19 //SEG219 [110] (word) sin16s::x5_128#0 ← (word) sin16s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vwuz1=vwuz1_ror_4 ldy #4 !: @@ -8682,9 +8702,10 @@ sin16s: { rts //SEG229 sin16s::@15 //SEG230 [116] (signed word~) sin16s::return#5 ← (signed word)(word) sin16s::usinx#1 - // (signed word~) sin16s::return#5 = (signed word)(word) sin16s::usinx#1 // register copy zp ZP_WORD:15 } //SEG231 mulu16_sel +// 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: { .label _0 = $b .label _1 = $b @@ -8699,14 +8720,11 @@ mulu16_sel: { lda v1+1 sta mul16u.a+1 //SEG233 [119] (word) mul16u::b#0 ← (word) mulu16_sel::v2#5 - // (word) mul16u::b#0 = (word) mulu16_sel::v2#5 // register copy zp ZP_WORD:19 //SEG234 [120] call mul16u jsr mul16u //SEG235 [121] (dword) mul16u::return#2 ← (dword) mul16u::res#2 - // (dword) mul16u::return#2 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:11 //SEG236 mulu16_sel::@2 //SEG237 [122] (dword~) mulu16_sel::$0 ← (dword) mul16u::return#2 - // (dword~) mulu16_sel::$0 = (dword) mul16u::return#2 // register copy zp ZP_DWORD:11 //SEG238 [123] (dword~) mulu16_sel::$1 ← (dword~) mulu16_sel::$0 << (byte) mulu16_sel::select#5 -- vduz1=vduz1_rol_vbuxx cpx #0 beq !e+ @@ -8728,6 +8746,7 @@ mulu16_sel: { rts } //SEG242 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label mb = $17 .label a = $15 @@ -8803,6 +8822,8 @@ mul16u: { jmp b1 } //SEG266 div32u16u +// 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_lo = $f @@ -8820,7 +8841,6 @@ div32u16u: { sta divr16u.rem+1 jsr divr16u //SEG271 [138] (word) divr16u::return#3 ← (word) divr16u::return#0 - // (word) divr16u::return#3 = (word) divr16u::return#0 // register copy zp ZP_WORD:15 //SEG272 div32u16u::@2 //SEG273 [139] (word) div32u16u::quotient_hi#0 ← (word) divr16u::return#3 -- vwuz1=vwuz2 lda divr16u.return @@ -8828,7 +8848,6 @@ div32u16u: { lda divr16u.return+1 sta quotient_hi+1 //SEG274 [140] (word) divr16u::rem#5 ← (word) rem16u#1 - // (word) divr16u::rem#5 = (word) rem16u#1 // register copy zp ZP_WORD:2 //SEG275 [141] call divr16u //SEG276 [146] phi from div32u16u::@2 to divr16u [phi:div32u16u::@2->divr16u] //SEG277 [146] phi (word) divr16u::dividend#6 = <(const dword) PI2_u4f28#0 [phi:div32u16u::@2->divr16u#0] -- vwuz1=vwuc1 @@ -8839,10 +8858,8 @@ div32u16u: { //SEG278 [146] phi (word) divr16u::rem#11 = (word) divr16u::rem#5 [phi:div32u16u::@2->divr16u#1] -- register_copy jsr divr16u //SEG279 [142] (word) divr16u::return#4 ← (word) divr16u::return#0 - // (word) divr16u::return#4 = (word) divr16u::return#0 // register copy zp ZP_WORD:15 //SEG280 div32u16u::@3 //SEG281 [143] (word) div32u16u::quotient_lo#0 ← (word) divr16u::return#4 - // (word) div32u16u::quotient_lo#0 = (word) divr16u::return#4 // register copy zp ZP_WORD:15 //SEG282 [144] (dword) div32u16u::return#0 ← (word) div32u16u::quotient_hi#0 dw= (word) div32u16u::quotient_lo#0 -- vduz1=vwuz2_dword_vwuz3 lda quotient_hi sta return+2 @@ -8857,6 +8874,10 @@ div32u16u: { rts } //SEG285 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 5 @@ -8938,12 +8959,14 @@ divr16u: { bne b1 //SEG318 divr16u::@6 //SEG319 [162] (word) rem16u#1 ← (word) divr16u::rem#10 - // (word) rem16u#1 = (word) divr16u::rem#10 // register copy zp ZP_WORD:2 //SEG320 divr16u::@return //SEG321 [163] return rts } //SEG322 sin8s_gen +// Generate signed byte sinus table - on the full -$7f - $7f range +// sintab - the table to generate into +// wavelength - the number of sinus points in a total sinus wavelength (the size of the table) sin8s_gen: { .label step = $f .label sintab = 5 @@ -8953,10 +8976,8 @@ sin8s_gen: { //SEG324 [241] phi from sin8s_gen to div16u [phi:sin8s_gen->div16u] jsr div16u //SEG325 [166] (word) div16u::return#2 ← (word) div16u::return#0 - // (word) div16u::return#2 = (word) div16u::return#0 // register copy zp ZP_WORD:15 //SEG326 sin8s_gen::@3 //SEG327 [167] (word) sin8s_gen::step#0 ← (word) div16u::return#2 - // (word) sin8s_gen::step#0 = (word) div16u::return#2 // register copy zp ZP_WORD:15 //SEG328 [168] phi from sin8s_gen::@3 to sin8s_gen::@1 [phi:sin8s_gen::@3->sin8s_gen::@1] //SEG329 [168] phi (word) sin8s_gen::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:sin8s_gen::@3->sin8s_gen::@1#0] -- vwuz1=vbuc1 lda #<0 @@ -8985,10 +9006,8 @@ sin8s_gen: { //SEG338 [170] call sin8s jsr sin8s //SEG339 [171] (signed byte) sin8s::return#0 ← (signed byte) sin8s::return#1 - // (signed byte) sin8s::return#0 = (signed byte) sin8s::return#1 // register copy reg byte a //SEG340 sin8s_gen::@4 //SEG341 [172] (signed byte~) sin8s_gen::$1 ← (signed byte) sin8s::return#0 - // (signed byte~) sin8s_gen::$1 = (signed byte) sin8s::return#0 // register copy reg byte a //SEG342 [173] *((signed byte*) sin8s_gen::sintab#2) ← (signed byte~) sin8s_gen::$1 -- _deref_pbsz1=vbsaa ldy #0 sta (sintab),y @@ -9024,6 +9043,9 @@ sin8s_gen: { rts } //SEG349 sin8s +// Calculate signed byte sinus sin(x) +// x: unsigned word input u[4.12] in the interval $0000 - PI2_u4f12 +// result: signed byte sin(x) s[0.7] - using the full range -$7f - $7f sin8s: { .const DIV_6 = $2b .label _6 = $13 @@ -9109,10 +9131,8 @@ sin8s: { //SEG374 [222] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#0 [phi:sin8s::@2->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG375 [190] (byte) mulu8_sel::return#0 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#0 = (byte) mulu8_sel::return#12 // register copy reg byte a //SEG376 sin8s::@10 //SEG377 [191] (byte) sin8s::x2#0 ← (byte) mulu8_sel::return#0 - // (byte) sin8s::x2#0 = (byte) mulu8_sel::return#0 // register copy reg byte a //SEG378 [192] (byte) mulu8_sel::v1#1 ← (byte) sin8s::x2#0 -- vbuxx=vbuaa tax //SEG379 [193] (byte) mulu8_sel::v2#1 ← (byte) sin8s::x1#0 -- vbuyy=vbuz1 @@ -9126,7 +9146,6 @@ sin8s: { //SEG384 [222] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#1 [phi:sin8s::@10->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG385 [195] (byte) mulu8_sel::return#1 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#1 = (byte) mulu8_sel::return#12 // register copy reg byte a //SEG386 sin8s::@11 //SEG387 [196] (byte) sin8s::x3#0 ← (byte) mulu8_sel::return#1 -- vbuz1=vbuaa sta x3 @@ -9142,10 +9161,8 @@ sin8s: { //SEG393 [222] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#2 [phi:sin8s::@11->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG394 [199] (byte) mulu8_sel::return#2 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#2 = (byte) mulu8_sel::return#12 // register copy reg byte a //SEG395 sin8s::@12 //SEG396 [200] (byte) sin8s::x3_6#0 ← (byte) mulu8_sel::return#2 - // (byte) sin8s::x3_6#0 = (byte) mulu8_sel::return#2 // register copy reg byte a //SEG397 [201] (byte) sin8s::usinx#0 ← (byte) sin8s::x1#0 - (byte) sin8s::x3_6#0 -- vbuz1=vbuz2_minus_vbuaa eor #$ff sec @@ -9164,10 +9181,8 @@ sin8s: { //SEG404 [222] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#3 [phi:sin8s::@12->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG405 [205] (byte) mulu8_sel::return#10 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#10 = (byte) mulu8_sel::return#12 // register copy reg byte a //SEG406 sin8s::@13 //SEG407 [206] (byte) sin8s::x4#0 ← (byte) mulu8_sel::return#10 - // (byte) sin8s::x4#0 = (byte) mulu8_sel::return#10 // register copy reg byte a //SEG408 [207] (byte) mulu8_sel::v1#4 ← (byte) sin8s::x4#0 -- vbuxx=vbuaa tax //SEG409 [208] (byte) mulu8_sel::v2#4 ← (byte) sin8s::x1#0 -- vbuyy=vbuz1 @@ -9181,10 +9196,8 @@ sin8s: { //SEG414 [222] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#4 [phi:sin8s::@13->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG415 [210] (byte) mulu8_sel::return#11 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#11 = (byte) mulu8_sel::return#12 // register copy reg byte a //SEG416 sin8s::@14 //SEG417 [211] (byte) sin8s::x5#0 ← (byte) mulu8_sel::return#11 - // (byte) sin8s::x5#0 = (byte) mulu8_sel::return#11 // register copy reg byte a //SEG418 [212] (byte) sin8s::x5_128#0 ← (byte) sin8s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuaa_ror_4 lsr lsr @@ -9228,21 +9241,20 @@ sin8s: { jmp b4 } //SEG436 mulu8_sel +// 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: { .label _0 = $13 .label _1 = $13 .label select = $1b //SEG437 [223] (byte) mul8u::a#1 ← (byte) mulu8_sel::v1#5 - // (byte) mul8u::a#1 = (byte) mulu8_sel::v1#5 // register copy reg byte x //SEG438 [224] (byte) mul8u::b#0 ← (byte) mulu8_sel::v2#5 -- vbuaa=vbuyy tya //SEG439 [225] call mul8u jsr mul8u //SEG440 [226] (word) mul8u::return#2 ← (word) mul8u::res#2 - // (word) mul8u::return#2 = (word) mul8u::res#2 // register copy zp ZP_WORD:19 //SEG441 mulu8_sel::@2 //SEG442 [227] (word~) mulu8_sel::$0 ← (word) mul8u::return#2 - // (word~) mulu8_sel::$0 = (word) mul8u::return#2 // register copy zp ZP_WORD:19 //SEG443 [228] (word~) mulu8_sel::$1 ← (word~) mulu8_sel::$0 << (byte) mulu8_sel::select#5 -- vwuz1=vwuz1_rol_vbuz2 ldy select beq !e+ @@ -9259,6 +9271,8 @@ mulu8_sel: { rts } //SEG447 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .label mb = $15 .label res = $13 @@ -9316,6 +9330,10 @@ mul8u: { jmp b1 } //SEG471 div16u +// Performs division on two 16 bit unsigned words +// Returns the quotient dividend/divisor. +// The remainder will be set into the global variable rem16u +// Implemented using simple binary division div16u: { .label return = $f //SEG472 [242] call divr16u @@ -9331,10 +9349,8 @@ div16u: { sta divr16u.rem+1 jsr divr16u //SEG476 [243] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:15 //SEG477 div16u::@2 //SEG478 [244] (word) div16u::return#0 ← (word) divr16u::return#2 - // (word) div16u::return#0 = (word) divr16u::return#2 // register copy zp ZP_WORD:15 //SEG479 div16u::@return //SEG480 [245] return rts diff --git a/src/test/ref/sinusgenscale8.asm b/src/test/ref/sinusgenscale8.asm index 4b0ee5878..70c4e33cd 100644 --- a/src/test/ref/sinusgenscale8.asm +++ b/src/test/ref/sinusgenscale8.asm @@ -14,6 +14,11 @@ main: { rts sintab: .fill $14, 0 } +// Generate unsigned byte sinus table in a min-max range +// sintab - the table to generate into +// tabsize - the number of sinus points (the size of the table) +// min - the minimal value +// max - the maximal value sin8u_table: { .const min = $a .const max = $ff @@ -182,6 +187,7 @@ sin8u_table: { str7: .text " scaled: @" str8: .text " trans: @" } +// Print a newline print_ln: { b1: lda print_line_cursor @@ -201,6 +207,7 @@ print_ln: { !: rts } +// Print a byte as HEX print_byte: { .label b = $a lda b @@ -218,6 +225,7 @@ print_byte: { jsr print_char rts } +// Print a single char print_char: { ldy #0 sta (print_char_cursor),y @@ -227,6 +235,7 @@ print_char: { !: rts } +// Print a zero-terminated string print_str: { .label str = $b b1: @@ -249,6 +258,7 @@ print_str: { !: jmp b1 } +// Print a signed word as HEX print_sword: { .label w = $b lda w+1 @@ -268,6 +278,7 @@ print_sword: { jsr print_word rts } +// Print a word as HEX print_word: { .label w = $b lda w+1 @@ -278,6 +289,7 @@ print_word: { jsr print_byte rts } +// Print a signed byte as HEX print_sbyte: { .label b = $a lda b @@ -297,6 +309,8 @@ print_sbyte: { sta b jmp b2 } +// Multiply a signed byte and an unsigned byte (into a signed word) +// Fixes offsets introduced by using unsigned multiplication mul8su: { .const b = sin8u_table.amplitude+1 .label m = $f @@ -314,6 +328,8 @@ mul8su: { b1: rts } +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .label mb = $b .label res = $f @@ -347,6 +363,9 @@ mul8u: { rol mb+1 jmp b1 } +// Calculate signed byte sinus sin(x) +// x: unsigned word input u[4.12] in the interval $0000 - PI2_u4f12 +// result: signed byte sin(x) s[0.7] - using the full range -$7f - $7f sin8s: { .const DIV_6 = $2b .label _6 = $b @@ -455,6 +474,8 @@ sin8s: { txa jmp b4 } +// 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: { .label _0 = $f .label _1 = $f @@ -472,11 +493,19 @@ mulu8_sel: { lda _1+1 rts } +// Performs division on two 16 bit unsigned words +// Returns the quotient dividend/divisor. +// The remainder will be set into the global variable rem16u +// Implemented using simple binary division div16u: { .label return = $12 jsr divr16u rts } +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 4 @@ -533,6 +562,7 @@ divr16u: { bne b1 rts } +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 lda #<$400 diff --git a/src/test/ref/sinusgenscale8.log b/src/test/ref/sinusgenscale8.log index 94ddff430..d1cfaad5e 100644 --- a/src/test/ref/sinusgenscale8.log +++ b/src/test/ref/sinusgenscale8.log @@ -3539,6 +3539,11 @@ main: { sintab: .fill $14, 0 } //SEG18 sin8u_table +// Generate unsigned byte sinus table in a min-max range +// sintab - the table to generate into +// tabsize - the number of sinus points (the size of the table) +// min - the minimal value +// max - the maximal value sin8u_table: { .const min = $a .const max = $ff @@ -3956,6 +3961,7 @@ sin8u_table: { str8: .text " trans: @" } //SEG162 print_ln +// Print a newline print_ln: { //SEG163 [70] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -3988,6 +3994,7 @@ print_ln: { rts } //SEG170 print_byte +// Print a byte as HEX print_byte: { .label _0 = $3b .label _2 = $3c @@ -4033,6 +4040,7 @@ print_byte: { rts } //SEG186 print_char +// Print a single char print_char: { .label ch = $b //SEG187 [83] *((byte*) print_char_cursor#64) ← (byte) print_char::ch#5 -- _deref_pbuz1=vbuz2 @@ -4051,6 +4059,7 @@ print_char: { rts } //SEG191 print_str +// Print a zero-terminated string print_str: { .label str = $c //SEG192 [87] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -4091,6 +4100,7 @@ print_str: { jmp b1_from_b2 } //SEG203 print_sword +// Print a signed word as HEX print_sword: { .label w = $e //SEG204 [93] if((signed word) print_sword::w#1>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -4148,6 +4158,7 @@ print_sword: { rts } //SEG224 print_word +// Print a word as HEX print_word: { .label w = $12 //SEG225 [102] (byte) print_byte::b#1 ← > (word) print_word::w#3 -- vbuz1=_hi_vwuz2 @@ -4178,6 +4189,7 @@ print_word: { rts } //SEG238 print_sbyte +// Print a signed byte as HEX print_sbyte: { .label b = $14 //SEG239 [107] if((signed byte) print_sbyte::b#1<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsz1_lt_0_then_la1 @@ -4242,6 +4254,8 @@ print_sbyte: { jmp b2_from_b5 } //SEG264 mul8su +// Multiply a signed byte and an unsigned byte (into a signed word) +// Fixes offsets introduced by using unsigned multiplication mul8su: { .const b = sin8u_table.amplitude+1 .label _5 = $3f @@ -4309,6 +4323,8 @@ mul8su: { rts } //SEG284 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .label _1 = $42 .label mb = $1b @@ -4384,6 +4400,9 @@ mul8u: { jmp b1 } //SEG308 sin8s +// Calculate signed byte sinus sin(x) +// x: unsigned word input u[4.12] in the interval $0000 - PI2_u4f12 +// result: signed byte sin(x) s[0.7] - using the full range -$7f - $7f sin8s: { .const DIV_6 = $2b .label _6 = $43 @@ -4665,6 +4684,8 @@ sin8s: { jmp b4_from_b18 } //SEG395 mulu8_sel +// 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: { .label _0 = $54 .label _1 = $56 @@ -4725,6 +4746,10 @@ mulu8_sel: { rts } //SEG409 div16u +// Performs division on two 16 bit unsigned words +// Returns the quotient dividend/divisor. +// The remainder will be set into the global variable rem16u +// Implemented using simple binary division div16u: { .label return = $5b .label return_2 = $2e @@ -4752,6 +4777,10 @@ div16u: { rts } //SEG417 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label _1 = $5d .label _2 = $5e @@ -4879,6 +4908,7 @@ divr16u: { rts } //SEG454 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = $2c //SEG455 [215] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -5279,6 +5309,11 @@ main: { sintab: .fill $14, 0 } //SEG18 sin8u_table +// Generate unsigned byte sinus table in a min-max range +// sintab - the table to generate into +// tabsize - the number of sinus points (the size of the table) +// min - the minimal value +// max - the maximal value sin8u_table: { .const min = $a .const max = $ff @@ -5296,12 +5331,10 @@ sin8u_table: { div16u_from_sin8u_table: jsr div16u //SEG21 [11] (word) div16u::return#2 ← (word) div16u::return#0 - // (word) div16u::return#2 = (word) div16u::return#0 // register copy zp ZP_WORD:18 jmp b3 //SEG22 sin8u_table::@3 b3: //SEG23 [12] (word) sin8u_table::step#0 ← (word) div16u::return#2 - // (word) sin8u_table::step#0 = (word) div16u::return#2 // register copy zp ZP_WORD:18 //SEG24 [13] call print_str //SEG25 [86] phi from sin8u_table::@3 to print_str [phi:sin8u_table::@3->print_str] print_str_from_b3: @@ -5490,7 +5523,6 @@ sin8u_table: { //SEG97 [36] call sin8s jsr sin8s //SEG98 [37] (signed byte) sin8s::return#2 ← (signed byte) sin8s::return#0 - // (signed byte) sin8s::return#2 = (signed byte) sin8s::return#0 // register copy reg byte a jmp b15 //SEG99 sin8u_table::@15 b15: @@ -5501,12 +5533,10 @@ sin8u_table: { //SEG102 [40] call mul8su jsr mul8su //SEG103 [41] (signed word) mul8su::return#2 ← (signed word)(word) mul8su::m#2 - // (signed word) mul8su::return#2 = (signed word)(word) mul8su::m#2 // register copy zp ZP_WORD:15 jmp b16 //SEG104 sin8u_table::@16 b16: //SEG105 [42] (signed word) sin8u_table::sinx_sc#0 ← (signed word) mul8su::return#2 - // (signed word) sin8u_table::sinx_sc#0 = (signed word) mul8su::return#2 // register copy zp ZP_WORD:15 //SEG106 [43] (byte~) sin8u_table::$21 ← > (signed word) sin8u_table::sinx_sc#0 -- vbuaa=_hi_vwsz1 lda sinx_sc+1 //SEG107 [44] (byte) sin8u_table::sinx_tr#0 ← (const byte) sin8u_table::mid#0 + (byte~) sin8u_table::$21 -- vbuxx=vbuc1_plus_vbuaa @@ -5676,6 +5706,7 @@ sin8u_table: { str8: .text " trans: @" } //SEG162 print_ln +// Print a newline print_ln: { //SEG163 [70] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -5708,6 +5739,7 @@ print_ln: { rts } //SEG170 print_byte +// Print a byte as HEX print_byte: { .label b = $a //SEG171 [75] (byte~) print_byte::$0 ← (byte) print_byte::b#8 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 @@ -5747,6 +5779,7 @@ print_byte: { rts } //SEG186 print_char +// Print a single char print_char: { //SEG187 [83] *((byte*) print_char_cursor#64) ← (byte) print_char::ch#5 -- _deref_pbuz1=vbuaa ldy #0 @@ -5763,6 +5796,7 @@ print_char: { rts } //SEG191 print_str +// Print a zero-terminated string print_str: { .label str = $b //SEG192 [87] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -5803,6 +5837,7 @@ print_str: { jmp b1_from_b2 } //SEG203 print_sword +// Print a signed word as HEX print_sword: { .label w = $b //SEG204 [93] if((signed word) print_sword::w#1>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -5842,7 +5877,6 @@ print_sword: { //SEG216 print_sword::@1 b1: //SEG217 [98] (word~) print_word::w#5 ← (word)(signed word) print_sword::w#3 - // (word~) print_word::w#5 = (word)(signed word) print_sword::w#3 // register copy zp ZP_WORD:11 //SEG218 [99] call print_word //SEG219 [101] phi from print_sword::@1 to print_word [phi:print_sword::@1->print_word] print_word_from_b1: @@ -5856,6 +5890,7 @@ print_sword: { rts } //SEG224 print_word +// Print a word as HEX print_word: { .label w = $b //SEG225 [102] (byte) print_byte::b#1 ← > (word) print_word::w#3 -- vbuz1=_hi_vwuz2 @@ -5886,6 +5921,7 @@ print_word: { rts } //SEG238 print_sbyte +// Print a signed byte as HEX print_sbyte: { .label b = $a //SEG239 [107] if((signed byte) print_sbyte::b#1<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsz1_lt_0_then_la1 @@ -5911,7 +5947,6 @@ print_sbyte: { //SEG248 print_sbyte::@2 b2: //SEG249 [111] (byte~) print_byte::b#10 ← (byte)(signed byte) print_sbyte::b#4 - // (byte~) print_byte::b#10 = (byte)(signed byte) print_sbyte::b#4 // register copy zp ZP_BYTE:10 //SEG250 [112] call print_byte //SEG251 [74] phi from print_sbyte::@2 to print_byte [phi:print_sbyte::@2->print_byte] print_byte_from_b2: @@ -5947,6 +5982,8 @@ print_sbyte: { jmp b2_from_b5 } //SEG264 mul8su +// Multiply a signed byte and an unsigned byte (into a signed word) +// Fixes offsets introduced by using unsigned multiplication mul8su: { .const b = sin8u_table.amplitude+1 .label m = $f @@ -5962,12 +5999,10 @@ mul8su: { lda #b jsr mul8u //SEG270 [119] (word) mul8u::return#2 ← (word) mul8u::res#2 - // (word) mul8u::return#2 = (word) mul8u::res#2 // register copy zp ZP_WORD:15 jmp b4 //SEG271 mul8su::@4 b4: //SEG272 [120] (word) mul8su::m#0 ← (word) mul8u::return#2 - // (word) mul8su::m#0 = (word) mul8u::return#2 // register copy zp ZP_WORD:15 //SEG273 [121] if((signed byte) mul8su::a#0>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mul8su::@1 -- vbsyy_ge_0_then_la1 cpy #0 bpl b1_from_b4 @@ -5997,6 +6032,8 @@ mul8su: { rts } //SEG284 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .label mb = $b .label res = $f @@ -6066,6 +6103,9 @@ mul8u: { jmp b1 } //SEG308 sin8s +// Calculate signed byte sinus sin(x) +// x: unsigned word input u[4.12] in the interval $0000 - PI2_u4f12 +// result: signed byte sin(x) s[0.7] - using the full range -$7f - $7f sin8s: { .const DIV_6 = $2b .label _6 = $b @@ -6161,12 +6201,10 @@ sin8s: { //SEG333 [182] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#0 [phi:sin8s::@2->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG334 [150] (byte) mulu8_sel::return#0 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#0 = (byte) mulu8_sel::return#12 // register copy reg byte a jmp b10 //SEG335 sin8s::@10 b10: //SEG336 [151] (byte) sin8s::x2#0 ← (byte) mulu8_sel::return#0 - // (byte) sin8s::x2#0 = (byte) mulu8_sel::return#0 // register copy reg byte a //SEG337 [152] (byte) mulu8_sel::v1#1 ← (byte) sin8s::x2#0 -- vbuxx=vbuaa tax //SEG338 [153] (byte) mulu8_sel::v2#1 ← (byte) sin8s::x1#0 -- vbuyy=vbuz1 @@ -6181,7 +6219,6 @@ sin8s: { //SEG343 [182] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#1 [phi:sin8s::@10->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG344 [155] (byte) mulu8_sel::return#1 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#1 = (byte) mulu8_sel::return#12 // register copy reg byte a jmp b11 //SEG345 sin8s::@11 b11: @@ -6200,12 +6237,10 @@ sin8s: { //SEG352 [182] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#2 [phi:sin8s::@11->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG353 [159] (byte) mulu8_sel::return#2 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#2 = (byte) mulu8_sel::return#12 // register copy reg byte a jmp b12 //SEG354 sin8s::@12 b12: //SEG355 [160] (byte) sin8s::x3_6#0 ← (byte) mulu8_sel::return#2 - // (byte) sin8s::x3_6#0 = (byte) mulu8_sel::return#2 // register copy reg byte a //SEG356 [161] (byte) sin8s::usinx#0 ← (byte) sin8s::x1#0 - (byte) sin8s::x3_6#0 -- vbuz1=vbuz2_minus_vbuaa eor #$ff sec @@ -6225,12 +6260,10 @@ sin8s: { //SEG363 [182] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#3 [phi:sin8s::@12->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG364 [165] (byte) mulu8_sel::return#10 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#10 = (byte) mulu8_sel::return#12 // register copy reg byte a jmp b13 //SEG365 sin8s::@13 b13: //SEG366 [166] (byte) sin8s::x4#0 ← (byte) mulu8_sel::return#10 - // (byte) sin8s::x4#0 = (byte) mulu8_sel::return#10 // register copy reg byte a //SEG367 [167] (byte) mulu8_sel::v1#4 ← (byte) sin8s::x4#0 -- vbuxx=vbuaa tax //SEG368 [168] (byte) mulu8_sel::v2#4 ← (byte) sin8s::x1#0 -- vbuyy=vbuz1 @@ -6245,12 +6278,10 @@ sin8s: { //SEG373 [182] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#4 [phi:sin8s::@13->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG374 [170] (byte) mulu8_sel::return#11 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#11 = (byte) mulu8_sel::return#12 // register copy reg byte a jmp b14 //SEG375 sin8s::@14 b14: //SEG376 [171] (byte) sin8s::x5#0 ← (byte) mulu8_sel::return#11 - // (byte) sin8s::x5#0 = (byte) mulu8_sel::return#11 // register copy reg byte a //SEG377 [172] (byte) sin8s::x5_128#0 ← (byte) sin8s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuaa_ror_4 lsr lsr @@ -6306,12 +6337,13 @@ sin8s: { jmp b4_from_b18 } //SEG395 mulu8_sel +// 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: { .label _0 = $f .label _1 = $f .label select = $11 //SEG396 [183] (byte) mul8u::a#2 ← (byte) mulu8_sel::v1#5 - // (byte) mul8u::a#2 = (byte) mulu8_sel::v1#5 // register copy reg byte x //SEG397 [184] (byte) mul8u::b#1 ← (byte) mulu8_sel::v2#5 -- vbuaa=vbuyy tya //SEG398 [185] call mul8u @@ -6321,12 +6353,10 @@ mulu8_sel: { //SEG401 [128] phi (byte) mul8u::b#2 = (byte) mul8u::b#1 [phi:mulu8_sel->mul8u#1] -- register_copy jsr mul8u //SEG402 [186] (word) mul8u::return#3 ← (word) mul8u::res#2 - // (word) mul8u::return#3 = (word) mul8u::res#2 // register copy zp ZP_WORD:15 jmp b2 //SEG403 mulu8_sel::@2 b2: //SEG404 [187] (word~) mulu8_sel::$0 ← (word) mul8u::return#3 - // (word~) mulu8_sel::$0 = (word) mul8u::return#3 // register copy zp ZP_WORD:15 //SEG405 [188] (word~) mulu8_sel::$1 ← (word~) mulu8_sel::$0 << (byte) mulu8_sel::select#5 -- vwuz1=vwuz1_rol_vbuz2 ldy select beq !e+ @@ -6345,6 +6375,10 @@ mulu8_sel: { rts } //SEG409 div16u +// Performs division on two 16 bit unsigned words +// Returns the quotient dividend/divisor. +// The remainder will be set into the global variable rem16u +// Implemented using simple binary division div16u: { .label return = $12 //SEG410 [192] call divr16u @@ -6352,12 +6386,10 @@ div16u: { divr16u_from_div16u: jsr divr16u //SEG412 [193] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:18 jmp b2 //SEG413 div16u::@2 b2: //SEG414 [194] (word) div16u::return#0 ← (word) divr16u::return#2 - // (word) div16u::return#0 = (word) divr16u::return#2 // register copy zp ZP_WORD:18 jmp breturn //SEG415 div16u::@return breturn: @@ -6365,6 +6397,10 @@ div16u: { rts } //SEG417 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 4 @@ -6471,7 +6507,6 @@ divr16u: { //SEG450 divr16u::@6 b6: //SEG451 [212] (word) rem16u#1 ← (word) divr16u::rem#10 - // (word) rem16u#1 = (word) divr16u::rem#10 // register copy zp ZP_WORD:2 jmp breturn //SEG452 divr16u::@return breturn: @@ -6479,6 +6514,7 @@ divr16u: { rts } //SEG454 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG455 [215] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -6642,6 +6678,7 @@ Removing instruction main_from_b41: Removing instruction bend_from_b41: Removing instruction b1_from_main: Removing instruction sin8u_table_from_b1: +Removing instruction print_str_from_b3: Removing instruction b5_from_b4: Removing instruction print_str_from_b5: Removing instruction b6_from_b5: @@ -6677,10 +6714,12 @@ Removing instruction b2_from_print_sword: Removing instruction print_char_from_b2: Removing instruction b1_from_print_sword: Removing instruction b1_from_b4: +Removing instruction print_word_from_b1: Removing instruction b3_from_print_sbyte: Removing instruction print_char_from_b3: Removing instruction b2_from_b3: Removing instruction b2_from_b5: +Removing instruction print_byte_from_b2: Removing instruction b1_from_print_sbyte: Removing instruction print_char_from_b1: Removing instruction b1_from_b2: @@ -6695,11 +6734,13 @@ Removing instruction b3_from_b7: Removing instruction b4_from_b18: Removing instruction b4_from_b8: Removing instruction breturn: +Removing instruction breturn: Removing instruction b1_from_b3: Removing instruction b2_from_b1: Removing instruction b2_from_b4: Removing instruction b3_from_b2: Removing instruction b3_from_b5: +Removing instruction breturn: Removing instruction b1_from_b1: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction bend: @@ -6708,7 +6749,6 @@ Removing instruction b1: Removing instruction breturn: Removing instruction div16u_from_sin8u_table: Removing instruction b3: -Removing instruction print_str_from_b3: Removing instruction b4: Removing instruction print_word_from_b4: Removing instruction b5: @@ -6745,14 +6785,12 @@ Removing instruction breturn: Removing instruction breturn: Removing instruction b2: Removing instruction b4: -Removing instruction print_word_from_b1: Removing instruction breturn: Removing instruction print_byte_from_print_word: Removing instruction b1: Removing instruction print_byte_from_b1: Removing instruction breturn: Removing instruction b3: -Removing instruction print_byte_from_b2: Removing instruction breturn: Removing instruction b5: Removing instruction mul8u_from_mul8su: @@ -6782,12 +6820,10 @@ Removing instruction b2: Removing instruction breturn: Removing instruction divr16u_from_div16u: Removing instruction b2: -Removing instruction breturn: Removing instruction b1_from_divr16u: Removing instruction b4: Removing instruction b5: Removing instruction b6: -Removing instruction breturn: Removing instruction b1_from_print_cls: Removing instruction breturn: Succesful ASM optimization Pass5UnusedLabelElimination @@ -6804,8 +6840,8 @@ Removing instruction lda #<0 Succesful ASM optimization Pass5UnnecesaryLoadElimination Removing instruction bbegin: Succesful ASM optimization Pass5UnusedLabelElimination -Fixing long branch [163] bcc b1 to bcs -Fixing long branch [169] bcc b1 to bcs +Fixing long branch [168] bcc b1 to bcs +Fixing long branch [174] bcc b1 to bcs FINAL SYMBOL TABLE (label) @41 @@ -7221,6 +7257,11 @@ main: { sintab: .fill $14, 0 } //SEG18 sin8u_table +// Generate unsigned byte sinus table in a min-max range +// sintab - the table to generate into +// tabsize - the number of sinus points (the size of the table) +// min - the minimal value +// max - the maximal value sin8u_table: { .const min = $a .const max = $ff @@ -7237,10 +7278,8 @@ sin8u_table: { //SEG20 [191] phi from sin8u_table to div16u [phi:sin8u_table->div16u] jsr div16u //SEG21 [11] (word) div16u::return#2 ← (word) div16u::return#0 - // (word) div16u::return#2 = (word) div16u::return#0 // register copy zp ZP_WORD:18 //SEG22 sin8u_table::@3 //SEG23 [12] (word) sin8u_table::step#0 ← (word) div16u::return#2 - // (word) sin8u_table::step#0 = (word) div16u::return#2 // register copy zp ZP_WORD:18 //SEG24 [13] call print_str //SEG25 [86] phi from sin8u_table::@3 to print_str [phi:sin8u_table::@3->print_str] //SEG26 [86] phi (byte*) print_char_cursor#105 = ((byte*))(word/signed word/dword/signed dword) 1024 [phi:sin8u_table::@3->print_str#0] -- pbuz1=pbuc1 @@ -7383,7 +7422,6 @@ sin8u_table: { //SEG97 [36] call sin8s jsr sin8s //SEG98 [37] (signed byte) sin8s::return#2 ← (signed byte) sin8s::return#0 - // (signed byte) sin8s::return#2 = (signed byte) sin8s::return#0 // register copy reg byte a //SEG99 sin8u_table::@15 //SEG100 [38] (signed byte) sin8u_table::sinx#0 ← (signed byte) sin8s::return#2 -- vbsz1=vbsaa sta sinx @@ -7392,10 +7430,8 @@ sin8u_table: { //SEG102 [40] call mul8su jsr mul8su //SEG103 [41] (signed word) mul8su::return#2 ← (signed word)(word) mul8su::m#2 - // (signed word) mul8su::return#2 = (signed word)(word) mul8su::m#2 // register copy zp ZP_WORD:15 //SEG104 sin8u_table::@16 //SEG105 [42] (signed word) sin8u_table::sinx_sc#0 ← (signed word) mul8su::return#2 - // (signed word) sin8u_table::sinx_sc#0 = (signed word) mul8su::return#2 // register copy zp ZP_WORD:15 //SEG106 [43] (byte~) sin8u_table::$21 ← > (signed word) sin8u_table::sinx_sc#0 -- vbuaa=_hi_vwsz1 lda sinx_sc+1 //SEG107 [44] (byte) sin8u_table::sinx_tr#0 ← (const byte) sin8u_table::mid#0 + (byte~) sin8u_table::$21 -- vbuxx=vbuc1_plus_vbuaa @@ -7538,6 +7574,7 @@ sin8u_table: { str8: .text " trans: @" } //SEG162 print_ln +// Print a newline print_ln: { //SEG163 [70] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] //SEG164 [70] phi (byte*) print_line_cursor#12 = (byte*) print_line_cursor#23 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy @@ -7565,6 +7602,7 @@ print_ln: { rts } //SEG170 print_byte +// Print a byte as HEX print_byte: { .label b = $a //SEG171 [75] (byte~) print_byte::$0 ← (byte) print_byte::b#8 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 @@ -7598,6 +7636,7 @@ print_byte: { rts } //SEG186 print_char +// Print a single char print_char: { //SEG187 [83] *((byte*) print_char_cursor#64) ← (byte) print_char::ch#5 -- _deref_pbuz1=vbuaa ldy #0 @@ -7612,6 +7651,7 @@ print_char: { rts } //SEG191 print_str +// Print a zero-terminated string print_str: { .label str = $b //SEG192 [87] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -7646,6 +7686,7 @@ print_str: { jmp b1 } //SEG203 print_sword +// Print a signed word as HEX print_sword: { .label w = $b //SEG204 [93] if((signed word) print_sword::w#1>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -7676,7 +7717,6 @@ print_sword: { //SEG216 print_sword::@1 b1: //SEG217 [98] (word~) print_word::w#5 ← (word)(signed word) print_sword::w#3 - // (word~) print_word::w#5 = (word)(signed word) print_sword::w#3 // register copy zp ZP_WORD:11 //SEG218 [99] call print_word //SEG219 [101] phi from print_sword::@1 to print_word [phi:print_sword::@1->print_word] //SEG220 [101] phi (byte*) print_char_cursor#99 = (byte*) print_char_cursor#94 [phi:print_sword::@1->print_word#0] -- register_copy @@ -7687,6 +7727,7 @@ print_sword: { rts } //SEG224 print_word +// Print a word as HEX print_word: { .label w = $b //SEG225 [102] (byte) print_byte::b#1 ← > (word) print_word::w#3 -- vbuz1=_hi_vwuz2 @@ -7711,6 +7752,7 @@ print_word: { rts } //SEG238 print_sbyte +// Print a signed byte as HEX print_sbyte: { .label b = $a //SEG239 [107] if((signed byte) print_sbyte::b#1<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsz1_lt_0_then_la1 @@ -7729,7 +7771,6 @@ print_sbyte: { //SEG248 print_sbyte::@2 b2: //SEG249 [111] (byte~) print_byte::b#10 ← (byte)(signed byte) print_sbyte::b#4 - // (byte~) print_byte::b#10 = (byte)(signed byte) print_sbyte::b#4 // register copy zp ZP_BYTE:10 //SEG250 [112] call print_byte //SEG251 [74] phi from print_sbyte::@2 to print_byte [phi:print_sbyte::@2->print_byte] //SEG252 [74] phi (byte*) print_char_cursor#100 = (byte*) print_char_cursor#18 [phi:print_sbyte::@2->print_byte#0] -- register_copy @@ -7757,6 +7798,8 @@ print_sbyte: { jmp b2 } //SEG264 mul8su +// Multiply a signed byte and an unsigned byte (into a signed word) +// Fixes offsets introduced by using unsigned multiplication mul8su: { .const b = sin8u_table.amplitude+1 .label m = $f @@ -7771,10 +7814,8 @@ mul8su: { lda #b jsr mul8u //SEG270 [119] (word) mul8u::return#2 ← (word) mul8u::res#2 - // (word) mul8u::return#2 = (word) mul8u::res#2 // register copy zp ZP_WORD:15 //SEG271 mul8su::@4 //SEG272 [120] (word) mul8su::m#0 ← (word) mul8u::return#2 - // (word) mul8su::m#0 = (word) mul8u::return#2 // register copy zp ZP_WORD:15 //SEG273 [121] if((signed byte) mul8su::a#0>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mul8su::@1 -- vbsyy_ge_0_then_la1 cpy #0 bpl b1 @@ -7796,6 +7837,8 @@ mul8su: { rts } //SEG284 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .label mb = $b .label res = $f @@ -7853,6 +7896,9 @@ mul8u: { jmp b1 } //SEG308 sin8s +// Calculate signed byte sinus sin(x) +// x: unsigned word input u[4.12] in the interval $0000 - PI2_u4f12 +// result: signed byte sin(x) s[0.7] - using the full range -$7f - $7f sin8s: { .const DIV_6 = $2b .label _6 = $b @@ -7938,10 +7984,8 @@ sin8s: { //SEG333 [182] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#0 [phi:sin8s::@2->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG334 [150] (byte) mulu8_sel::return#0 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#0 = (byte) mulu8_sel::return#12 // register copy reg byte a //SEG335 sin8s::@10 //SEG336 [151] (byte) sin8s::x2#0 ← (byte) mulu8_sel::return#0 - // (byte) sin8s::x2#0 = (byte) mulu8_sel::return#0 // register copy reg byte a //SEG337 [152] (byte) mulu8_sel::v1#1 ← (byte) sin8s::x2#0 -- vbuxx=vbuaa tax //SEG338 [153] (byte) mulu8_sel::v2#1 ← (byte) sin8s::x1#0 -- vbuyy=vbuz1 @@ -7955,7 +7999,6 @@ sin8s: { //SEG343 [182] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#1 [phi:sin8s::@10->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG344 [155] (byte) mulu8_sel::return#1 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#1 = (byte) mulu8_sel::return#12 // register copy reg byte a //SEG345 sin8s::@11 //SEG346 [156] (byte) sin8s::x3#0 ← (byte) mulu8_sel::return#1 -- vbuz1=vbuaa sta x3 @@ -7971,10 +8014,8 @@ sin8s: { //SEG352 [182] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#2 [phi:sin8s::@11->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG353 [159] (byte) mulu8_sel::return#2 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#2 = (byte) mulu8_sel::return#12 // register copy reg byte a //SEG354 sin8s::@12 //SEG355 [160] (byte) sin8s::x3_6#0 ← (byte) mulu8_sel::return#2 - // (byte) sin8s::x3_6#0 = (byte) mulu8_sel::return#2 // register copy reg byte a //SEG356 [161] (byte) sin8s::usinx#0 ← (byte) sin8s::x1#0 - (byte) sin8s::x3_6#0 -- vbuz1=vbuz2_minus_vbuaa eor #$ff sec @@ -7993,10 +8034,8 @@ sin8s: { //SEG363 [182] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#3 [phi:sin8s::@12->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG364 [165] (byte) mulu8_sel::return#10 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#10 = (byte) mulu8_sel::return#12 // register copy reg byte a //SEG365 sin8s::@13 //SEG366 [166] (byte) sin8s::x4#0 ← (byte) mulu8_sel::return#10 - // (byte) sin8s::x4#0 = (byte) mulu8_sel::return#10 // register copy reg byte a //SEG367 [167] (byte) mulu8_sel::v1#4 ← (byte) sin8s::x4#0 -- vbuxx=vbuaa tax //SEG368 [168] (byte) mulu8_sel::v2#4 ← (byte) sin8s::x1#0 -- vbuyy=vbuz1 @@ -8010,10 +8049,8 @@ sin8s: { //SEG373 [182] phi (byte) mulu8_sel::v1#5 = (byte) mulu8_sel::v1#4 [phi:sin8s::@13->mulu8_sel#2] -- register_copy jsr mulu8_sel //SEG374 [170] (byte) mulu8_sel::return#11 ← (byte) mulu8_sel::return#12 - // (byte) mulu8_sel::return#11 = (byte) mulu8_sel::return#12 // register copy reg byte a //SEG375 sin8s::@14 //SEG376 [171] (byte) sin8s::x5#0 ← (byte) mulu8_sel::return#11 - // (byte) sin8s::x5#0 = (byte) mulu8_sel::return#11 // register copy reg byte a //SEG377 [172] (byte) sin8s::x5_128#0 ← (byte) sin8s::x5#0 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuaa_ror_4 lsr lsr @@ -8057,12 +8094,13 @@ sin8s: { jmp b4 } //SEG395 mulu8_sel +// 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: { .label _0 = $f .label _1 = $f .label select = $11 //SEG396 [183] (byte) mul8u::a#2 ← (byte) mulu8_sel::v1#5 - // (byte) mul8u::a#2 = (byte) mulu8_sel::v1#5 // register copy reg byte x //SEG397 [184] (byte) mul8u::b#1 ← (byte) mulu8_sel::v2#5 -- vbuaa=vbuyy tya //SEG398 [185] call mul8u @@ -8071,10 +8109,8 @@ mulu8_sel: { //SEG401 [128] phi (byte) mul8u::b#2 = (byte) mul8u::b#1 [phi:mulu8_sel->mul8u#1] -- register_copy jsr mul8u //SEG402 [186] (word) mul8u::return#3 ← (word) mul8u::res#2 - // (word) mul8u::return#3 = (word) mul8u::res#2 // register copy zp ZP_WORD:15 //SEG403 mulu8_sel::@2 //SEG404 [187] (word~) mulu8_sel::$0 ← (word) mul8u::return#3 - // (word~) mulu8_sel::$0 = (word) mul8u::return#3 // register copy zp ZP_WORD:15 //SEG405 [188] (word~) mulu8_sel::$1 ← (word~) mulu8_sel::$0 << (byte) mulu8_sel::select#5 -- vwuz1=vwuz1_rol_vbuz2 ldy select beq !e+ @@ -8091,21 +8127,27 @@ mulu8_sel: { rts } //SEG409 div16u +// Performs division on two 16 bit unsigned words +// Returns the quotient dividend/divisor. +// The remainder will be set into the global variable rem16u +// Implemented using simple binary division div16u: { .label return = $12 //SEG410 [192] call divr16u //SEG411 [196] phi from div16u to divr16u [phi:div16u->divr16u] jsr divr16u //SEG412 [193] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:18 //SEG413 div16u::@2 //SEG414 [194] (word) div16u::return#0 ← (word) divr16u::return#2 - // (word) div16u::return#0 = (word) divr16u::return#2 // register copy zp ZP_WORD:18 //SEG415 div16u::@return //SEG416 [195] return rts } //SEG417 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = 2 .label dividend = 4 @@ -8194,12 +8236,12 @@ divr16u: { bne b1 //SEG450 divr16u::@6 //SEG451 [212] (word) rem16u#1 ← (word) divr16u::rem#10 - // (word) rem16u#1 = (word) divr16u::rem#10 // register copy zp ZP_WORD:2 //SEG452 divr16u::@return //SEG453 [213] return rts } //SEG454 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 2 //SEG455 [215] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] diff --git a/src/test/ref/summin.log b/src/test/ref/summin.log index bc3d89a30..25606e000 100644 --- a/src/test/ref/summin.log +++ b/src/test/ref/summin.log @@ -483,7 +483,6 @@ main: { ldy #1 jsr sum //SEG14 [6] (byte) sum::return#0 ← (byte) sum::return#3 - // (byte) sum::return#0 = (byte) sum::return#3 // register copy reg byte a jmp b1 //SEG15 main::@1 b1: @@ -498,7 +497,6 @@ main: { ldy #3 jsr sum //SEG21 [9] (byte) sum::return#1 ← (byte) sum::return#3 - // (byte) sum::return#1 = (byte) sum::return#3 // register copy reg byte a jmp b2 //SEG22 main::@2 b2: @@ -513,7 +511,6 @@ main: { ldy #9 jsr sum //SEG28 [12] (byte) sum::return#2 ← (byte) sum::return#3 - // (byte) sum::return#2 = (byte) sum::return#3 // register copy reg byte a jmp b3 //SEG29 main::@3 b3: @@ -650,7 +647,6 @@ main: { ldy #1 jsr sum //SEG14 [6] (byte) sum::return#0 ← (byte) sum::return#3 - // (byte) sum::return#0 = (byte) sum::return#3 // register copy reg byte a //SEG15 main::@1 //SEG16 [7] (byte) main::s1#0 ← (byte) sum::return#0 -- vbuz1=vbuaa sta s1 @@ -662,7 +658,6 @@ main: { ldy #3 jsr sum //SEG21 [9] (byte) sum::return#1 ← (byte) sum::return#3 - // (byte) sum::return#1 = (byte) sum::return#3 // register copy reg byte a //SEG22 main::@2 //SEG23 [10] (byte) main::s2#0 ← (byte) sum::return#1 -- vbuxx=vbuaa tax @@ -674,7 +669,6 @@ main: { ldy #9 jsr sum //SEG28 [12] (byte) sum::return#2 ← (byte) sum::return#3 - // (byte) sum::return#2 = (byte) sum::return#3 // register copy reg byte a //SEG29 main::@3 //SEG30 [13] (byte) main::s3#0 ← (byte) sum::return#2 -- vbuz1=vbuaa sta s3 diff --git a/src/test/ref/test-comparisons.asm b/src/test/ref/test-comparisons.asm index edb1eb415..a6d6e41f1 100644 --- a/src/test/ref/test-comparisons.asm +++ b/src/test/ref/test-comparisons.asm @@ -396,6 +396,7 @@ main: { op19: .text "==@" cs: .byte 7, $c7, $37, $97, $67 } +// Print a newline print_ln: { b1: lda print_line_cursor @@ -434,6 +435,7 @@ printu: { jsr print_char rts } +// Print a single char print_char: { ldy #0 sta (print_char_cursor),y @@ -443,6 +445,7 @@ print_char: { !: rts } +// Print a byte as HEX print_byte: { .label b = $b lda b @@ -460,6 +463,7 @@ print_byte: { jsr print_char rts } +// Print a zero-terminated string print_str: { .label str = 6 b1: @@ -482,6 +486,7 @@ print_str: { !: jmp b1 } +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 4 lda #<$400 diff --git a/src/test/ref/test-comparisons.log b/src/test/ref/test-comparisons.log index 46207dccc..c794c49d0 100644 --- a/src/test/ref/test-comparisons.log +++ b/src/test/ref/test-comparisons.log @@ -4233,6 +4233,7 @@ main: { cs: .byte 7, $c7, $37, $97, $67 } //SEG435 print_ln +// Print a newline print_ln: { //SEG436 [163] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -4346,6 +4347,7 @@ printu: { rts } //SEG478 print_char +// Print a single char print_char: { .label ch = $1f //SEG479 [181] *((byte*) print_char_cursor#54) ← (byte) print_char::ch#5 -- _deref_pbuz1=vbuz2 @@ -4364,6 +4366,7 @@ print_char: { rts } //SEG483 print_byte +// Print a byte as HEX print_byte: { .label _0 = $28 .label _2 = $29 @@ -4409,6 +4412,7 @@ print_byte: { rts } //SEG499 print_str +// Print a zero-terminated string print_str: { .label str = $23 //SEG500 [193] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -4449,6 +4453,7 @@ print_str: { jmp b1_from_b2 } //SEG511 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = $25 //SEG512 [200] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -4802,12 +4807,10 @@ main: { //SEG26 main::@2 b2: //SEG27 [11] (byte) printu::a#0 ← (byte) main::a#10 - // (byte) printu::a#0 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG28 [12] (byte) printu::b#0 ← (byte) main::b#0 -- vbuz1=vbuz2 lda b sta printu.b //SEG29 [13] (byte) printu::res#0 ← (byte) main::r#40 - // (byte) printu::res#0 = (byte) main::r#40 // register copy reg byte x //SEG30 [14] call printu //SEG31 [167] phi from main::@2 to printu [phi:main::@2->printu] printu_from_b2: @@ -4846,9 +4849,7 @@ main: { //SEG45 main::@3 b3: //SEG46 [18] (byte) printu::a#1 ← (byte) main::a#10 - // (byte) printu::a#1 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG47 [19] (byte) printu::res#1 ← (byte) main::r#41 - // (byte) printu::res#1 = (byte) main::r#41 // register copy reg byte x //SEG48 [20] call printu //SEG49 [167] phi from main::@3 to printu [phi:main::@3->printu] printu_from_b3: @@ -4890,13 +4891,11 @@ main: { //SEG63 main::@4 b4: //SEG64 [24] (byte) printu::a#2 ← (byte) main::a#10 - // (byte) printu::a#2 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG65 [25] (byte) printu::b#2 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) -- vbuz1=pbuc1_derefidx_vbuz2 ldy i lda cs,y sta printu.b //SEG66 [26] (byte) printu::res#2 ← (byte) main::r#42 - // (byte) printu::res#2 = (byte) main::r#42 // register copy reg byte x //SEG67 [27] call printu //SEG68 [167] phi from main::@4 to printu [phi:main::@4->printu] printu_from_b4: @@ -4935,12 +4934,10 @@ main: { //SEG82 main::@5 b5: //SEG83 [31] (byte) printu::a#3 ← (byte) main::a#10 - // (byte) printu::a#3 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG84 [32] (byte) printu::b#3 ← (byte) main::a#10 -- vbuz1=vbuz2 lda a sta printu.b //SEG85 [33] (byte) printu::res#3 ← (byte) main::r#43 - // (byte) printu::res#3 = (byte) main::r#43 // register copy reg byte x //SEG86 [34] call printu //SEG87 [167] phi from main::@5 to printu [phi:main::@5->printu] printu_from_b5: @@ -4989,12 +4986,10 @@ main: { //SEG106 main::@6 b6: //SEG107 [40] (byte) printu::a#4 ← (byte) main::a#10 - // (byte) printu::a#4 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG108 [41] (byte) printu::b#4 ← (byte) main::b#0 -- vbuz1=vbuz2 lda b sta printu.b //SEG109 [42] (byte) printu::res#4 ← (byte) main::r#44 - // (byte) printu::res#4 = (byte) main::r#44 // register copy reg byte x //SEG110 [43] (byte*~) print_char_cursor#159 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -5038,9 +5033,7 @@ main: { //SEG126 main::@7 b7: //SEG127 [48] (byte) printu::a#5 ← (byte) main::a#10 - // (byte) printu::a#5 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG128 [49] (byte) printu::res#5 ← (byte) main::r#45 - // (byte) printu::res#5 = (byte) main::r#45 // register copy reg byte x //SEG129 [50] call printu //SEG130 [167] phi from main::@7 to printu [phi:main::@7->printu] printu_from_b7: @@ -5082,13 +5075,11 @@ main: { //SEG144 main::@8 b8: //SEG145 [54] (byte) printu::a#6 ← (byte) main::a#10 - // (byte) printu::a#6 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG146 [55] (byte) printu::b#6 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) -- vbuz1=pbuc1_derefidx_vbuz2 ldy i lda cs,y sta printu.b //SEG147 [56] (byte) printu::res#6 ← (byte) main::r#46 - // (byte) printu::res#6 = (byte) main::r#46 // register copy reg byte x //SEG148 [57] call printu //SEG149 [167] phi from main::@8 to printu [phi:main::@8->printu] printu_from_b8: @@ -5127,12 +5118,10 @@ main: { //SEG163 main::@9 b9: //SEG164 [61] (byte) printu::a#7 ← (byte) main::a#10 - // (byte) printu::a#7 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG165 [62] (byte) printu::b#7 ← (byte) main::a#10 -- vbuz1=vbuz2 lda a sta printu.b //SEG166 [63] (byte) printu::res#7 ← (byte) main::r#47 - // (byte) printu::res#7 = (byte) main::r#47 // register copy reg byte x //SEG167 [64] call printu //SEG168 [167] phi from main::@9 to printu [phi:main::@9->printu] printu_from_b9: @@ -5181,12 +5170,10 @@ main: { //SEG187 main::@10 b10: //SEG188 [70] (byte) printu::a#8 ← (byte) main::a#10 - // (byte) printu::a#8 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG189 [71] (byte) printu::b#8 ← (byte) main::b#0 -- vbuz1=vbuz2 lda b sta printu.b //SEG190 [72] (byte) printu::res#8 ← (byte) main::r#48 - // (byte) printu::res#8 = (byte) main::r#48 // register copy reg byte x //SEG191 [73] (byte*~) print_char_cursor#143 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -5232,9 +5219,7 @@ main: { //SEG207 main::@11 b11: //SEG208 [78] (byte) printu::a#9 ← (byte) main::a#10 - // (byte) printu::a#9 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG209 [79] (byte) printu::res#9 ← (byte) main::r#49 - // (byte) printu::res#9 = (byte) main::r#49 // register copy reg byte x //SEG210 [80] call printu //SEG211 [167] phi from main::@11 to printu [phi:main::@11->printu] printu_from_b11: @@ -5276,13 +5261,11 @@ main: { //SEG225 main::@12 b12: //SEG226 [84] (byte) printu::a#10 ← (byte) main::a#10 - // (byte) printu::a#10 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG227 [85] (byte) printu::b#10 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) -- vbuz1=pbuc1_derefidx_vbuz2 ldy i lda cs,y sta printu.b //SEG228 [86] (byte) printu::res#10 ← (byte) main::r#50 - // (byte) printu::res#10 = (byte) main::r#50 // register copy reg byte x //SEG229 [87] call printu //SEG230 [167] phi from main::@12 to printu [phi:main::@12->printu] printu_from_b12: @@ -5321,12 +5304,10 @@ main: { //SEG244 main::@13 b13: //SEG245 [91] (byte) printu::a#11 ← (byte) main::a#10 - // (byte) printu::a#11 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG246 [92] (byte) printu::b#11 ← (byte) main::a#10 -- vbuz1=vbuz2 lda a sta printu.b //SEG247 [93] (byte) printu::res#11 ← (byte) main::r#51 - // (byte) printu::res#11 = (byte) main::r#51 // register copy reg byte x //SEG248 [94] call printu //SEG249 [167] phi from main::@13 to printu [phi:main::@13->printu] printu_from_b13: @@ -5375,12 +5356,10 @@ main: { //SEG268 main::@14 b14: //SEG269 [100] (byte) printu::a#12 ← (byte) main::a#10 - // (byte) printu::a#12 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG270 [101] (byte) printu::b#12 ← (byte) main::b#0 -- vbuz1=vbuz2 lda b sta printu.b //SEG271 [102] (byte) printu::res#12 ← (byte) main::r#52 - // (byte) printu::res#12 = (byte) main::r#52 // register copy reg byte x //SEG272 [103] (byte*~) print_char_cursor#147 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -5424,9 +5403,7 @@ main: { //SEG288 main::@15 b15: //SEG289 [108] (byte) printu::a#13 ← (byte) main::a#10 - // (byte) printu::a#13 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG290 [109] (byte) printu::res#13 ← (byte) main::r#53 - // (byte) printu::res#13 = (byte) main::r#53 // register copy reg byte x //SEG291 [110] call printu //SEG292 [167] phi from main::@15 to printu [phi:main::@15->printu] printu_from_b15: @@ -5468,13 +5445,11 @@ main: { //SEG306 main::@16 b16: //SEG307 [114] (byte) printu::a#14 ← (byte) main::a#10 - // (byte) printu::a#14 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG308 [115] (byte) printu::b#14 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) -- vbuz1=pbuc1_derefidx_vbuz2 ldy i lda cs,y sta printu.b //SEG309 [116] (byte) printu::res#14 ← (byte) main::r#54 - // (byte) printu::res#14 = (byte) main::r#54 // register copy reg byte x //SEG310 [117] call printu //SEG311 [167] phi from main::@16 to printu [phi:main::@16->printu] printu_from_b16: @@ -5513,12 +5488,10 @@ main: { //SEG325 main::@17 b17: //SEG326 [121] (byte) printu::a#15 ← (byte) main::a#10 - // (byte) printu::a#15 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG327 [122] (byte) printu::b#15 ← (byte) main::a#10 -- vbuz1=vbuz2 lda a sta printu.b //SEG328 [123] (byte) printu::res#15 ← (byte) main::r#55 - // (byte) printu::res#15 = (byte) main::r#55 // register copy reg byte x //SEG329 [124] call printu //SEG330 [167] phi from main::@17 to printu [phi:main::@17->printu] printu_from_b17: @@ -5567,12 +5540,10 @@ main: { //SEG349 main::@18 b18: //SEG350 [130] (byte) printu::a#16 ← (byte) main::a#10 - // (byte) printu::a#16 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG351 [131] (byte) printu::b#16 ← (byte) main::b#0 -- vbuz1=vbuz2 lda b sta printu.b //SEG352 [132] (byte) printu::res#16 ← (byte) main::r#56 - // (byte) printu::res#16 = (byte) main::r#56 // register copy reg byte x //SEG353 [133] (byte*~) print_char_cursor#151 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -5616,9 +5587,7 @@ main: { //SEG369 main::@19 b19: //SEG370 [138] (byte) printu::a#17 ← (byte) main::a#10 - // (byte) printu::a#17 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG371 [139] (byte) printu::res#17 ← (byte) main::r#57 - // (byte) printu::res#17 = (byte) main::r#57 // register copy reg byte x //SEG372 [140] call printu //SEG373 [167] phi from main::@19 to printu [phi:main::@19->printu] printu_from_b19: @@ -5660,13 +5629,11 @@ main: { //SEG387 main::@20 b20: //SEG388 [144] (byte) printu::a#18 ← (byte) main::a#10 - // (byte) printu::a#18 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG389 [145] (byte) printu::b#18 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) -- vbuz1=pbuc1_derefidx_vbuz2 ldy i lda cs,y sta printu.b //SEG390 [146] (byte) printu::res#18 ← (byte) main::r#58 - // (byte) printu::res#18 = (byte) main::r#58 // register copy reg byte x //SEG391 [147] call printu //SEG392 [167] phi from main::@20 to printu [phi:main::@20->printu] printu_from_b20: @@ -5705,12 +5672,10 @@ main: { //SEG406 main::@21 b21: //SEG407 [151] (byte) printu::a#19 ← (byte) main::a#10 - // (byte) printu::a#19 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG408 [152] (byte) printu::b#19 ← (byte) main::a#10 -- vbuz1=vbuz2 lda a sta printu.b //SEG409 [153] (byte) printu::res#19 ← (byte) main::r#59 - // (byte) printu::res#19 = (byte) main::r#59 // register copy reg byte x //SEG410 [154] call printu //SEG411 [167] phi from main::@21 to printu [phi:main::@21->printu] printu_from_b21: @@ -5792,6 +5757,7 @@ main: { cs: .byte 7, $c7, $37, $97, $67 } //SEG435 print_ln +// Print a newline print_ln: { //SEG436 [163] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -5851,7 +5817,6 @@ printu: { //SEG454 printu::@2 b2: //SEG455 [171] (byte*) print_str::str#1 ← (byte[]) printu::op#20 - // (byte*) print_str::str#1 = (byte[]) printu::op#20 // register copy zp ZP_WORD:6 //SEG456 [172] call print_str //SEG457 [192] phi from printu::@2 to print_str [phi:printu::@2->print_str] print_str_from_b2: @@ -5898,6 +5863,7 @@ printu: { rts } //SEG478 print_char +// Print a single char print_char: { //SEG479 [181] *((byte*) print_char_cursor#54) ← (byte) print_char::ch#5 -- _deref_pbuz1=vbuaa ldy #0 @@ -5914,6 +5880,7 @@ print_char: { rts } //SEG483 print_byte +// Print a byte as HEX print_byte: { .label b = $b //SEG484 [185] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 @@ -5953,6 +5920,7 @@ print_byte: { rts } //SEG499 print_str +// Print a zero-terminated string print_str: { .label str = 6 //SEG500 [193] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -5993,6 +5961,7 @@ print_str: { jmp b1_from_b2 } //SEG511 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 4 //SEG512 [200] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -6135,6 +6104,7 @@ Removing instruction b23_from_b1: Removing instruction b2_from_b23: Removing instruction b24_from_b46: Removing instruction b3_from_b24: +Removing instruction printu_from_b3: Removing instruction b25_from_b47: Removing instruction b4_from_b25: Removing instruction b26_from_b48: @@ -6145,6 +6115,7 @@ Removing instruction b27_from_b50: Removing instruction b6_from_b27: Removing instruction b28_from_b51: Removing instruction b7_from_b28: +Removing instruction printu_from_b7: Removing instruction b29_from_b52: Removing instruction b8_from_b29: Removing instruction b30_from_b53: @@ -6155,6 +6126,7 @@ Removing instruction b31_from_b55: Removing instruction b10_from_b31: Removing instruction b32_from_b56: Removing instruction b11_from_b32: +Removing instruction printu_from_b11: Removing instruction b33_from_b57: Removing instruction b12_from_b33: Removing instruction b34_from_b58: @@ -6165,6 +6137,7 @@ Removing instruction b35_from_b60: Removing instruction b14_from_b35: Removing instruction b36_from_b61: Removing instruction b15_from_b36: +Removing instruction printu_from_b15: Removing instruction b37_from_b62: Removing instruction b16_from_b37: Removing instruction b38_from_b63: @@ -6175,6 +6148,7 @@ Removing instruction b39_from_b65: Removing instruction b18_from_b39: Removing instruction b40_from_b66: Removing instruction b19_from_b40: +Removing instruction printu_from_b19: Removing instruction b41_from_b67: Removing instruction b20_from_b41: Removing instruction b42_from_b68: @@ -6185,6 +6159,7 @@ Removing instruction b22_from_b22: Removing instruction b22_from_b70: Removing instruction b1_from_print_ln: Removing instruction b1_from_b1: +Removing instruction print_str_from_b2: Removing instruction b4_from_b3: Removing instruction print_char_from_b4: Removing instruction b1_from_print_str: @@ -6198,7 +6173,6 @@ Removing instruction b23: Removing instruction printu_from_b2: Removing instruction b46: Removing instruction b24: -Removing instruction printu_from_b3: Removing instruction b47: Removing instruction b25: Removing instruction printu_from_b4: @@ -6211,7 +6185,6 @@ Removing instruction b27: Removing instruction printu_from_b6: Removing instruction b51: Removing instruction b28: -Removing instruction printu_from_b7: Removing instruction b52: Removing instruction b29: Removing instruction printu_from_b8: @@ -6224,7 +6197,6 @@ Removing instruction b31: Removing instruction printu_from_b10: Removing instruction b56: Removing instruction b32: -Removing instruction printu_from_b11: Removing instruction b57: Removing instruction b33: Removing instruction printu_from_b12: @@ -6237,7 +6209,6 @@ Removing instruction b35: Removing instruction printu_from_b14: Removing instruction b61: Removing instruction b36: -Removing instruction printu_from_b15: Removing instruction b62: Removing instruction b37: Removing instruction printu_from_b16: @@ -6250,7 +6221,6 @@ Removing instruction b39: Removing instruction printu_from_b18: Removing instruction b66: Removing instruction b40: -Removing instruction printu_from_b19: Removing instruction b67: Removing instruction b41: Removing instruction printu_from_b20: @@ -6265,7 +6235,6 @@ Removing instruction print_char_from_printu: Removing instruction b1: Removing instruction print_byte_from_b1: Removing instruction b2: -Removing instruction print_str_from_b2: Removing instruction b3: Removing instruction print_byte_from_b3: Removing instruction b4: @@ -6659,12 +6628,10 @@ main: { //SEG26 main::@2 b2: //SEG27 [11] (byte) printu::a#0 ← (byte) main::a#10 - // (byte) printu::a#0 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG28 [12] (byte) printu::b#0 ← (byte) main::b#0 -- vbuz1=vbuz2 lda b sta printu.b //SEG29 [13] (byte) printu::res#0 ← (byte) main::r#40 - // (byte) printu::res#0 = (byte) main::r#40 // register copy reg byte x //SEG30 [14] call printu //SEG31 [167] phi from main::@2 to printu [phi:main::@2->printu] //SEG32 [167] phi (byte) printu::res#20 = (byte) printu::res#0 [phi:main::@2->printu#0] -- register_copy @@ -6695,9 +6662,7 @@ main: { //SEG45 main::@3 b3: //SEG46 [18] (byte) printu::a#1 ← (byte) main::a#10 - // (byte) printu::a#1 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG47 [19] (byte) printu::res#1 ← (byte) main::r#41 - // (byte) printu::res#1 = (byte) main::r#41 // register copy reg byte x //SEG48 [20] call printu //SEG49 [167] phi from main::@3 to printu [phi:main::@3->printu] //SEG50 [167] phi (byte) printu::res#20 = (byte) printu::res#1 [phi:main::@3->printu#0] -- register_copy @@ -6731,13 +6696,11 @@ main: { //SEG63 main::@4 b4: //SEG64 [24] (byte) printu::a#2 ← (byte) main::a#10 - // (byte) printu::a#2 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG65 [25] (byte) printu::b#2 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) -- vbuz1=pbuc1_derefidx_vbuz2 ldy i lda cs,y sta printu.b //SEG66 [26] (byte) printu::res#2 ← (byte) main::r#42 - // (byte) printu::res#2 = (byte) main::r#42 // register copy reg byte x //SEG67 [27] call printu //SEG68 [167] phi from main::@4 to printu [phi:main::@4->printu] //SEG69 [167] phi (byte) printu::res#20 = (byte) printu::res#2 [phi:main::@4->printu#0] -- register_copy @@ -6768,12 +6731,10 @@ main: { //SEG82 main::@5 b5: //SEG83 [31] (byte) printu::a#3 ← (byte) main::a#10 - // (byte) printu::a#3 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG84 [32] (byte) printu::b#3 ← (byte) main::a#10 -- vbuz1=vbuz2 lda a sta printu.b //SEG85 [33] (byte) printu::res#3 ← (byte) main::r#43 - // (byte) printu::res#3 = (byte) main::r#43 // register copy reg byte x //SEG86 [34] call printu //SEG87 [167] phi from main::@5 to printu [phi:main::@5->printu] //SEG88 [167] phi (byte) printu::res#20 = (byte) printu::res#3 [phi:main::@5->printu#0] -- register_copy @@ -6810,12 +6771,10 @@ main: { //SEG106 main::@6 b6: //SEG107 [40] (byte) printu::a#4 ← (byte) main::a#10 - // (byte) printu::a#4 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG108 [41] (byte) printu::b#4 ← (byte) main::b#0 -- vbuz1=vbuz2 lda b sta printu.b //SEG109 [42] (byte) printu::res#4 ← (byte) main::r#44 - // (byte) printu::res#4 = (byte) main::r#44 // register copy reg byte x //SEG110 [43] (byte*~) print_char_cursor#159 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -6851,9 +6810,7 @@ main: { //SEG126 main::@7 b7: //SEG127 [48] (byte) printu::a#5 ← (byte) main::a#10 - // (byte) printu::a#5 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG128 [49] (byte) printu::res#5 ← (byte) main::r#45 - // (byte) printu::res#5 = (byte) main::r#45 // register copy reg byte x //SEG129 [50] call printu //SEG130 [167] phi from main::@7 to printu [phi:main::@7->printu] //SEG131 [167] phi (byte) printu::res#20 = (byte) printu::res#5 [phi:main::@7->printu#0] -- register_copy @@ -6887,13 +6844,11 @@ main: { //SEG144 main::@8 b8: //SEG145 [54] (byte) printu::a#6 ← (byte) main::a#10 - // (byte) printu::a#6 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG146 [55] (byte) printu::b#6 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) -- vbuz1=pbuc1_derefidx_vbuz2 ldy i lda cs,y sta printu.b //SEG147 [56] (byte) printu::res#6 ← (byte) main::r#46 - // (byte) printu::res#6 = (byte) main::r#46 // register copy reg byte x //SEG148 [57] call printu //SEG149 [167] phi from main::@8 to printu [phi:main::@8->printu] //SEG150 [167] phi (byte) printu::res#20 = (byte) printu::res#6 [phi:main::@8->printu#0] -- register_copy @@ -6924,12 +6879,10 @@ main: { //SEG163 main::@9 b9: //SEG164 [61] (byte) printu::a#7 ← (byte) main::a#10 - // (byte) printu::a#7 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG165 [62] (byte) printu::b#7 ← (byte) main::a#10 -- vbuz1=vbuz2 lda a sta printu.b //SEG166 [63] (byte) printu::res#7 ← (byte) main::r#47 - // (byte) printu::res#7 = (byte) main::r#47 // register copy reg byte x //SEG167 [64] call printu //SEG168 [167] phi from main::@9 to printu [phi:main::@9->printu] //SEG169 [167] phi (byte) printu::res#20 = (byte) printu::res#7 [phi:main::@9->printu#0] -- register_copy @@ -6966,12 +6919,10 @@ main: { //SEG187 main::@10 b10: //SEG188 [70] (byte) printu::a#8 ← (byte) main::a#10 - // (byte) printu::a#8 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG189 [71] (byte) printu::b#8 ← (byte) main::b#0 -- vbuz1=vbuz2 lda b sta printu.b //SEG190 [72] (byte) printu::res#8 ← (byte) main::r#48 - // (byte) printu::res#8 = (byte) main::r#48 // register copy reg byte x //SEG191 [73] (byte*~) print_char_cursor#143 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -7009,9 +6960,7 @@ main: { //SEG207 main::@11 b11: //SEG208 [78] (byte) printu::a#9 ← (byte) main::a#10 - // (byte) printu::a#9 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG209 [79] (byte) printu::res#9 ← (byte) main::r#49 - // (byte) printu::res#9 = (byte) main::r#49 // register copy reg byte x //SEG210 [80] call printu //SEG211 [167] phi from main::@11 to printu [phi:main::@11->printu] //SEG212 [167] phi (byte) printu::res#20 = (byte) printu::res#9 [phi:main::@11->printu#0] -- register_copy @@ -7045,13 +6994,11 @@ main: { //SEG225 main::@12 b12: //SEG226 [84] (byte) printu::a#10 ← (byte) main::a#10 - // (byte) printu::a#10 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG227 [85] (byte) printu::b#10 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) -- vbuz1=pbuc1_derefidx_vbuz2 ldy i lda cs,y sta printu.b //SEG228 [86] (byte) printu::res#10 ← (byte) main::r#50 - // (byte) printu::res#10 = (byte) main::r#50 // register copy reg byte x //SEG229 [87] call printu //SEG230 [167] phi from main::@12 to printu [phi:main::@12->printu] //SEG231 [167] phi (byte) printu::res#20 = (byte) printu::res#10 [phi:main::@12->printu#0] -- register_copy @@ -7082,12 +7029,10 @@ main: { //SEG244 main::@13 b13: //SEG245 [91] (byte) printu::a#11 ← (byte) main::a#10 - // (byte) printu::a#11 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG246 [92] (byte) printu::b#11 ← (byte) main::a#10 -- vbuz1=vbuz2 lda a sta printu.b //SEG247 [93] (byte) printu::res#11 ← (byte) main::r#51 - // (byte) printu::res#11 = (byte) main::r#51 // register copy reg byte x //SEG248 [94] call printu //SEG249 [167] phi from main::@13 to printu [phi:main::@13->printu] //SEG250 [167] phi (byte) printu::res#20 = (byte) printu::res#11 [phi:main::@13->printu#0] -- register_copy @@ -7124,12 +7069,10 @@ main: { //SEG268 main::@14 b14: //SEG269 [100] (byte) printu::a#12 ← (byte) main::a#10 - // (byte) printu::a#12 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG270 [101] (byte) printu::b#12 ← (byte) main::b#0 -- vbuz1=vbuz2 lda b sta printu.b //SEG271 [102] (byte) printu::res#12 ← (byte) main::r#52 - // (byte) printu::res#12 = (byte) main::r#52 // register copy reg byte x //SEG272 [103] (byte*~) print_char_cursor#147 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -7165,9 +7108,7 @@ main: { //SEG288 main::@15 b15: //SEG289 [108] (byte) printu::a#13 ← (byte) main::a#10 - // (byte) printu::a#13 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG290 [109] (byte) printu::res#13 ← (byte) main::r#53 - // (byte) printu::res#13 = (byte) main::r#53 // register copy reg byte x //SEG291 [110] call printu //SEG292 [167] phi from main::@15 to printu [phi:main::@15->printu] //SEG293 [167] phi (byte) printu::res#20 = (byte) printu::res#13 [phi:main::@15->printu#0] -- register_copy @@ -7201,13 +7142,11 @@ main: { //SEG306 main::@16 b16: //SEG307 [114] (byte) printu::a#14 ← (byte) main::a#10 - // (byte) printu::a#14 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG308 [115] (byte) printu::b#14 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) -- vbuz1=pbuc1_derefidx_vbuz2 ldy i lda cs,y sta printu.b //SEG309 [116] (byte) printu::res#14 ← (byte) main::r#54 - // (byte) printu::res#14 = (byte) main::r#54 // register copy reg byte x //SEG310 [117] call printu //SEG311 [167] phi from main::@16 to printu [phi:main::@16->printu] //SEG312 [167] phi (byte) printu::res#20 = (byte) printu::res#14 [phi:main::@16->printu#0] -- register_copy @@ -7238,12 +7177,10 @@ main: { //SEG325 main::@17 b17: //SEG326 [121] (byte) printu::a#15 ← (byte) main::a#10 - // (byte) printu::a#15 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG327 [122] (byte) printu::b#15 ← (byte) main::a#10 -- vbuz1=vbuz2 lda a sta printu.b //SEG328 [123] (byte) printu::res#15 ← (byte) main::r#55 - // (byte) printu::res#15 = (byte) main::r#55 // register copy reg byte x //SEG329 [124] call printu //SEG330 [167] phi from main::@17 to printu [phi:main::@17->printu] //SEG331 [167] phi (byte) printu::res#20 = (byte) printu::res#15 [phi:main::@17->printu#0] -- register_copy @@ -7280,12 +7217,10 @@ main: { //SEG349 main::@18 b18: //SEG350 [130] (byte) printu::a#16 ← (byte) main::a#10 - // (byte) printu::a#16 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG351 [131] (byte) printu::b#16 ← (byte) main::b#0 -- vbuz1=vbuz2 lda b sta printu.b //SEG352 [132] (byte) printu::res#16 ← (byte) main::r#56 - // (byte) printu::res#16 = (byte) main::r#56 // register copy reg byte x //SEG353 [133] (byte*~) print_char_cursor#151 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -7321,9 +7256,7 @@ main: { //SEG369 main::@19 b19: //SEG370 [138] (byte) printu::a#17 ← (byte) main::a#10 - // (byte) printu::a#17 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG371 [139] (byte) printu::res#17 ← (byte) main::r#57 - // (byte) printu::res#17 = (byte) main::r#57 // register copy reg byte x //SEG372 [140] call printu //SEG373 [167] phi from main::@19 to printu [phi:main::@19->printu] //SEG374 [167] phi (byte) printu::res#20 = (byte) printu::res#17 [phi:main::@19->printu#0] -- register_copy @@ -7357,13 +7290,11 @@ main: { //SEG387 main::@20 b20: //SEG388 [144] (byte) printu::a#18 ← (byte) main::a#10 - // (byte) printu::a#18 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG389 [145] (byte) printu::b#18 ← *((const byte[5]) main::cs#0 + (byte) main::i#10) -- vbuz1=pbuc1_derefidx_vbuz2 ldy i lda cs,y sta printu.b //SEG390 [146] (byte) printu::res#18 ← (byte) main::r#58 - // (byte) printu::res#18 = (byte) main::r#58 // register copy reg byte x //SEG391 [147] call printu //SEG392 [167] phi from main::@20 to printu [phi:main::@20->printu] //SEG393 [167] phi (byte) printu::res#20 = (byte) printu::res#18 [phi:main::@20->printu#0] -- register_copy @@ -7394,12 +7325,10 @@ main: { //SEG406 main::@21 b21: //SEG407 [151] (byte) printu::a#19 ← (byte) main::a#10 - // (byte) printu::a#19 = (byte) main::a#10 // register copy zp ZP_BYTE:2 //SEG408 [152] (byte) printu::b#19 ← (byte) main::a#10 -- vbuz1=vbuz2 lda a sta printu.b //SEG409 [153] (byte) printu::res#19 ← (byte) main::r#59 - // (byte) printu::res#19 = (byte) main::r#59 // register copy reg byte x //SEG410 [154] call printu //SEG411 [167] phi from main::@21 to printu [phi:main::@21->printu] //SEG412 [167] phi (byte) printu::res#20 = (byte) printu::res#19 [phi:main::@21->printu#0] -- register_copy @@ -7470,6 +7399,7 @@ main: { cs: .byte 7, $c7, $37, $97, $67 } //SEG435 print_ln +// Print a newline print_ln: { //SEG436 [163] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] //SEG437 [163] phi (byte*) print_line_cursor#13 = (byte*) print_line_cursor#25 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy @@ -7518,7 +7448,6 @@ printu: { jsr print_byte //SEG454 printu::@2 //SEG455 [171] (byte*) print_str::str#1 ← (byte[]) printu::op#20 - // (byte*) print_str::str#1 = (byte[]) printu::op#20 // register copy zp ZP_WORD:6 //SEG456 [172] call print_str //SEG457 [192] phi from printu::@2 to print_str [phi:printu::@2->print_str] jsr print_str @@ -7552,6 +7481,7 @@ printu: { rts } //SEG478 print_char +// Print a single char print_char: { //SEG479 [181] *((byte*) print_char_cursor#54) ← (byte) print_char::ch#5 -- _deref_pbuz1=vbuaa ldy #0 @@ -7566,6 +7496,7 @@ print_char: { rts } //SEG483 print_byte +// Print a byte as HEX print_byte: { .label b = $b //SEG484 [185] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 @@ -7599,6 +7530,7 @@ print_byte: { rts } //SEG499 print_str +// Print a zero-terminated string print_str: { .label str = 6 //SEG500 [193] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -7633,6 +7565,7 @@ print_str: { jmp b1 } //SEG511 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 4 //SEG512 [200] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] diff --git a/src/test/ref/test-division.asm b/src/test/ref/test-division.asm index 86eb89335..1b6974e12 100644 --- a/src/test/ref/test-division.asm +++ b/src/test/ref/test-division.asm @@ -80,6 +80,7 @@ test_16s: { dividends: .word $7fff, $7fff, -$7fff, -$7fff, $7fff, -$7fff divisors: .word 5, -7, $b, -$d, -$11, $13 } +// Print a newline print_ln: { b1: lda print_line_cursor @@ -99,6 +100,7 @@ print_ln: { !: rts } +// Print a signed word as HEX print_sword: { .label w = 5 lda w+1 @@ -118,6 +120,7 @@ print_sword: { jsr print_word rts } +// Print a word as HEX print_word: { .label w = 5 lda w+1 @@ -128,6 +131,7 @@ print_word: { jsr print_byte rts } +// Print a byte as HEX print_byte: { .label b = 7 lda b @@ -145,6 +149,7 @@ print_byte: { jsr print_char rts } +// Print a single char print_char: { ldy #0 sta (print_char_cursor),y @@ -154,6 +159,7 @@ print_char: { !: rts } +// Print a zero-terminated string print_str: { .label str = 5 b1: @@ -176,6 +182,12 @@ print_str: { !: jmp b1 } +// Perform division on two signed 16-bit numbers +// Returns dividend/divisor. +// The remainder will be set into the global variable rem16s. +// 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 div16s: { .label return = $e .label dividend = 5 @@ -191,6 +203,11 @@ div16s: { jsr divr16s rts } +// Perform division on two signed 16-bit numbers with an initial remainder. +// Returns dividend/divisor. The remainder will be set into the global variable rem16s. +// 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: { .const rem = 0 .label _5 = 8 @@ -267,6 +284,10 @@ divr16s: { ldy #1 jmp b2 } +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = $a .label dividend = 8 @@ -374,6 +395,7 @@ test_8s: { dividends: .byte $7f, -$7f, -$7f, $7f, $7f, $7f divisors: .byte 5, 7, -$b, -$d, $11, $13 } +// Print a signed byte as HEX print_sbyte: { .label b = 7 lda b @@ -393,6 +415,12 @@ print_sbyte: { sta b jmp b2 } +// Perform division on two signed 8-bit numbers +// Returns dividend/divisor. +// The remainder will be set into the global variable rem8s. +// 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 div8s: { .label neg = $10 cpy #0 @@ -443,6 +471,10 @@ div8s: { sta neg jmp b2 } +// Performs division on two 8 bit unsigned bytes +// Returns dividend/divisor. +// The remainder will be set into the global variable rem8u +// Implemented using simple binary division div8u: { sta divr8u.dividend stx divr8u.divisor @@ -450,6 +482,10 @@ div8u: { lda divr8u.return rts } +// Performs division on two 8 bit unsigned bytes and an initial remainder +// Returns dividend/divisor. +// The final remainder will be set into the global variable rem8u +// Implemented using simple binary division divr8u: { .label dividend = $11 .label divisor = $16 @@ -555,6 +591,10 @@ test_16u: { dividends: .word $ffff, $ffff, $ffff, $ffff, $ffff, $ffff divisors: .word 5, 7, $b, $d, $11, $13 } +// Performs division on two 16 bit unsigned words +// Returns the quotient dividend/divisor. +// The remainder will be set into the global variable rem16u +// Implemented using simple binary division div16u: { .label return = $e .label dividend = 5 @@ -636,6 +676,7 @@ test_8u: { dividends: .byte $ff, $ff, $ff, $ff, $ff, $ff divisors: .byte 5, 7, $b, $d, $11, $13 } +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 3 lda #<$400 diff --git a/src/test/ref/test-division.log b/src/test/ref/test-division.log index dfe8beb28..169426a1f 100644 --- a/src/test/ref/test-division.log +++ b/src/test/ref/test-division.log @@ -4738,6 +4738,7 @@ test_16s: { divisors: .word 5, -7, $b, -$d, -$11, $13 } //SEG93 print_ln +// Print a newline print_ln: { //SEG94 [45] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -4770,6 +4771,7 @@ print_ln: { rts } //SEG101 print_sword +// Print a signed word as HEX print_sword: { .label w = 5 //SEG102 [50] if((signed word) print_sword::w#5>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -4827,6 +4829,7 @@ print_sword: { rts } //SEG122 print_word +// Print a word as HEX print_word: { .label w = 7 //SEG123 [59] (byte) print_byte::b#1 ← > (word) print_word::w#5 -- vbuz1=_hi_vwuz2 @@ -4857,6 +4860,7 @@ print_word: { rts } //SEG136 print_byte +// Print a byte as HEX print_byte: { .label _0 = $40 .label _2 = $41 @@ -4902,6 +4906,7 @@ print_byte: { rts } //SEG152 print_char +// Print a single char print_char: { .label ch = $a //SEG153 [73] *((byte*) print_char_cursor#82) ← (byte) print_char::ch#5 -- _deref_pbuz1=vbuz2 @@ -4920,6 +4925,7 @@ print_char: { rts } //SEG157 print_str +// Print a zero-terminated string print_str: { .label str = $d //SEG158 [77] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -4960,6 +4966,12 @@ print_str: { jmp b1_from_b2 } //SEG169 div16s +// Perform division on two signed 16-bit numbers +// Returns dividend/divisor. +// The remainder will be set into the global variable rem16s. +// 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 div16s: { .label return = $48 .label dividend = $38 @@ -4997,6 +5009,11 @@ div16s: { rts } //SEG178 divr16s +// Perform division on two signed 16-bit numbers with an initial remainder. +// Returns dividend/divisor. The remainder will be set into the global variable rem16s. +// 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: { .const rem = 0 .label _5 = $50 @@ -5192,6 +5209,10 @@ divr16s: { jmp b2 } //SEG228 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label _1 = $52 .label _2 = $53 @@ -5478,6 +5499,7 @@ test_8s: { divisors: .byte 5, 7, -$b, -$d, $11, $13 } //SEG328 print_sbyte +// Print a signed byte as HEX print_sbyte: { .label b = $24 //SEG329 [161] if((signed byte) print_sbyte::b#10<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsz1_lt_0_then_la1 @@ -5542,6 +5564,12 @@ print_sbyte: { jmp b2_from_b5 } //SEG354 div8s +// Perform division on two signed 8-bit numbers +// Returns dividend/divisor. +// The remainder will be set into the global variable rem8s. +// 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 div8s: { .label _2 = $5f .label _6 = $5e @@ -5683,6 +5711,10 @@ div8s: { jmp b2 } //SEG400 div8u +// Performs division on two 8 bit unsigned bytes +// Returns dividend/divisor. +// The remainder will be set into the global variable rem8u +// Implemented using simple binary division div8u: { .label return = $62 .label dividend = $2a @@ -5715,6 +5747,10 @@ div8u: { rts } //SEG410 divr8u +// Performs division on two 8 bit unsigned bytes and an initial remainder +// Returns dividend/divisor. +// The final remainder will be set into the global variable rem8u +// Implemented using simple binary division divr8u: { .label _1 = $63 .label dividend = $2d @@ -6003,6 +6039,10 @@ test_16u: { divisors: .word 5, 7, $b, $d, $11, $13 } //SEG509 div16u +// Performs division on two 16 bit unsigned words +// Returns the quotient dividend/divisor. +// The remainder will be set into the global variable rem16u +// Implemented using simple binary division div16u: { .label return = $73 .label dividend = $69 @@ -6232,6 +6272,7 @@ test_8u: { divisors: .byte 5, 7, $b, $d, $11, $13 } //SEG593 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = $32 //SEG594 [283] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -6807,20 +6848,15 @@ test_16s: { lda divisors+1,y sta divisor+1 //SEG38 [19] (signed word) div16s::dividend#0 ← (signed word) test_16s::dividend#0 - // (signed word) div16s::dividend#0 = (signed word) test_16s::dividend#0 // register copy zp ZP_WORD:5 //SEG39 [20] (signed word) div16s::divisor#0 ← (signed word) test_16s::divisor#0 - // (signed word) div16s::divisor#0 = (signed word) test_16s::divisor#0 // register copy zp ZP_WORD:19 //SEG40 [21] call div16s jsr div16s //SEG41 [22] (signed word) div16s::return#2 ← (signed word) div16s::return#0 - // (signed word) div16s::return#2 = (signed word) div16s::return#0 // register copy zp ZP_WORD:14 jmp b3 //SEG42 test_16s::@3 b3: //SEG43 [23] (signed word) test_16s::res#0 ← (signed word) div16s::return#2 - // (signed word) test_16s::res#0 = (signed word) div16s::return#2 // register copy zp ZP_WORD:14 //SEG44 [24] (signed word) print_sword::w#1 ← (signed word) test_16s::dividend#0 - // (signed word) print_sword::w#1 = (signed word) test_16s::dividend#0 // register copy zp ZP_WORD:5 //SEG45 [25] (byte*~) print_char_cursor#159 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -6950,6 +6986,7 @@ test_16s: { divisors: .word 5, -7, $b, -$d, -$11, $13 } //SEG93 print_ln +// Print a newline print_ln: { //SEG94 [45] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -6982,6 +7019,7 @@ print_ln: { rts } //SEG101 print_sword +// Print a signed word as HEX print_sword: { .label w = 5 //SEG102 [50] if((signed word) print_sword::w#5>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -7021,7 +7059,6 @@ print_sword: { //SEG114 print_sword::@1 b1: //SEG115 [55] (word~) print_word::w#7 ← (word)(signed word) print_sword::w#6 - // (word~) print_word::w#7 = (word)(signed word) print_sword::w#6 // register copy zp ZP_WORD:5 //SEG116 [56] call print_word //SEG117 [58] phi from print_sword::@1 to print_word [phi:print_sword::@1->print_word] print_word_from_b1: @@ -7035,6 +7072,7 @@ print_sword: { rts } //SEG122 print_word +// Print a word as HEX print_word: { .label w = 5 //SEG123 [59] (byte) print_byte::b#1 ← > (word) print_word::w#5 -- vbuz1=_hi_vwuz2 @@ -7065,6 +7103,7 @@ print_word: { rts } //SEG136 print_byte +// Print a byte as HEX print_byte: { .label b = 7 //SEG137 [65] (byte~) print_byte::$0 ← (byte) print_byte::b#7 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 @@ -7104,6 +7143,7 @@ print_byte: { rts } //SEG152 print_char +// Print a single char print_char: { //SEG153 [73] *((byte*) print_char_cursor#82) ← (byte) print_char::ch#5 -- _deref_pbuz1=vbuaa ldy #0 @@ -7120,6 +7160,7 @@ print_char: { rts } //SEG157 print_str +// Print a zero-terminated string print_str: { .label str = 5 //SEG158 [77] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -7160,6 +7201,12 @@ print_str: { jmp b1_from_b2 } //SEG169 div16s +// Perform division on two signed 16-bit numbers +// Returns dividend/divisor. +// The remainder will be set into the global variable rem16s. +// 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 div16s: { .label return = $e .label dividend = 5 @@ -7177,12 +7224,10 @@ div16s: { //SEG172 [85] call divr16s jsr divr16s //SEG173 [86] (signed word) divr16s::return#3 ← (signed word) divr16s::return#2 - // (signed word) divr16s::return#3 = (signed word) divr16s::return#2 // register copy zp ZP_WORD:14 jmp b2 //SEG174 div16s::@2 b2: //SEG175 [87] (signed word) div16s::return#0 ← (signed word) divr16s::return#3 - // (signed word) div16s::return#0 = (signed word) divr16s::return#3 // register copy zp ZP_WORD:14 jmp breturn //SEG176 div16s::@return breturn: @@ -7190,6 +7235,11 @@ div16s: { rts } //SEG178 divr16s +// Perform division on two signed 16-bit numbers with an initial remainder. +// Returns dividend/divisor. The remainder will be set into the global variable rem16s. +// 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: { .const rem = 0 .label _5 = 8 @@ -7208,7 +7258,6 @@ divr16s: { //SEG180 divr16s::@17 b17: //SEG181 [90] (word~) divr16s::dividendu#8 ← (word)(signed word) divr16s::dividend#0 - // (word~) divr16s::dividendu#8 = (word)(signed word) divr16s::dividend#0 // register copy zp ZP_WORD:8 //SEG182 [91] phi from divr16s::@17 to divr16s::@2 [phi:divr16s::@17->divr16s::@2] b2_from_b17: //SEG183 [91] phi (word) divr16s::remu#3 = ((word))(const signed word) divr16s::rem#0 [phi:divr16s::@17->divr16s::@2#0] -- vwuz1=vbuc1 @@ -7229,7 +7278,6 @@ divr16s: { //SEG188 divr16s::@18 b18: //SEG189 [93] (word~) divr16s::divisoru#5 ← (word)(signed word) divr16s::divisor#0 - // (word~) divr16s::divisoru#5 = (word)(signed word) divr16s::divisor#0 // register copy zp ZP_WORD:12 //SEG190 [94] phi from divr16s::@18 divr16s::@3 to divr16s::@4 [phi:divr16s::@18/divr16s::@3->divr16s::@4] b4_from_b18: b4_from_b3: @@ -7239,11 +7287,8 @@ divr16s: { //SEG193 divr16s::@4 b4: //SEG194 [95] (word) divr16u::dividend#2 ← (word) divr16s::dividendu#3 - // (word) divr16u::dividend#2 = (word) divr16s::dividendu#3 // register copy zp ZP_WORD:8 //SEG195 [96] (word) divr16u::divisor#1 ← (word) divr16s::divisoru#3 - // (word) divr16u::divisor#1 = (word) divr16s::divisoru#3 // register copy zp ZP_WORD:12 //SEG196 [97] (word) divr16u::rem#4 ← (word) divr16s::remu#3 - // (word) divr16u::rem#4 = (word) divr16s::remu#3 // register copy zp ZP_WORD:10 //SEG197 [98] call divr16u //SEG198 [113] phi from divr16s::@4 to divr16u [phi:divr16s::@4->divr16u] divr16u_from_b4: @@ -7252,12 +7297,10 @@ divr16s: { //SEG201 [113] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:divr16s::@4->divr16u#2] -- register_copy jsr divr16u //SEG202 [99] (word) divr16u::return#3 ← (word) divr16u::return#0 - // (word) divr16u::return#3 = (word) divr16u::return#0 // register copy zp ZP_WORD:14 jmp b15 //SEG203 divr16s::@15 b15: //SEG204 [100] (word) divr16s::resultu#0 ← (word) divr16u::return#3 - // (word) divr16s::resultu#0 = (word) divr16u::return#3 // register copy zp ZP_WORD:14 //SEG205 [101] if((byte) divr16s::neg#4==(byte/signed byte/word/signed word/dword/signed dword) 0) goto divr16s::@19 -- vbuyy_eq_0_then_la1 cpy #0 beq b19 @@ -7297,9 +7340,7 @@ divr16s: { //SEG214 divr16s::@19 b19: //SEG215 [106] (signed word~) divr16s::return#7 ← (signed word)(word) divr16s::resultu#0 - // (signed word~) divr16s::return#7 = (signed word)(word) divr16s::resultu#0 // register copy zp ZP_WORD:14 //SEG216 [107] (signed word~) rem16s#37 ← (signed word)(word) rem16u#1 - // (signed word~) rem16s#37 = (signed word)(word) rem16u#1 // register copy zp ZP_WORD:10 jmp breturn_from_b19 //SEG217 divr16s::@3 b3: @@ -7318,7 +7359,6 @@ divr16s: { eor #1 tay //SEG220 [110] (word~) divr16s::divisoru#4 ← (word)(signed word~) divr16s::$11 - // (word~) divr16s::divisoru#4 = (word)(signed word~) divr16s::$11 // register copy zp ZP_WORD:12 jmp b4_from_b3 //SEG221 divr16s::@1 b1: @@ -7333,7 +7373,6 @@ divr16s: { adc #0 sta _5+1 //SEG223 [112] (word~) divr16s::dividendu#7 ← (word)(signed word~) divr16s::$5 - // (word~) divr16s::dividendu#7 = (word)(signed word~) divr16s::$5 // register copy zp ZP_WORD:8 //SEG224 [91] phi from divr16s::@1 to divr16s::@2 [phi:divr16s::@1->divr16s::@2] b2_from_b1: //SEG225 [91] phi (word) divr16s::remu#3 = ((word))-(const signed word) divr16s::rem#0 [phi:divr16s::@1->divr16s::@2#0] -- vwuz1=vbuc1 @@ -7347,6 +7386,10 @@ divr16s: { jmp b2 } //SEG228 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = $a .label dividend = 8 @@ -7446,7 +7489,6 @@ divr16u: { //SEG261 divr16u::@6 b6: //SEG262 [129] (word) rem16u#1 ← (word) divr16u::rem#11 - // (word) rem16u#1 = (word) divr16u::rem#11 // register copy zp ZP_WORD:10 jmp breturn //SEG263 divr16u::@return breturn: @@ -7486,14 +7528,12 @@ test_8s: { //SEG275 [137] call div8s jsr div8s //SEG276 [138] (signed byte) div8s::return#3 ← (signed byte) div8s::return#2 - // (signed byte) div8s::return#3 = (signed byte) div8s::return#2 // register copy reg byte a jmp b3 //SEG277 test_8s::@3 b3: //SEG278 [139] (signed byte) test_8s::res#0 ← (signed byte) div8s::return#3 -- vbsz1=vbsaa sta res //SEG279 [140] (signed byte) print_sbyte::b#1 ← (signed byte) test_8s::dividend#0 - // (signed byte) print_sbyte::b#1 = (signed byte) test_8s::dividend#0 // register copy zp ZP_BYTE:7 //SEG280 [141] (byte*~) print_char_cursor#184 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -7613,6 +7653,7 @@ test_8s: { divisors: .byte 5, 7, -$b, -$d, $11, $13 } //SEG328 print_sbyte +// Print a signed byte as HEX print_sbyte: { .label b = 7 //SEG329 [161] if((signed byte) print_sbyte::b#10<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsz1_lt_0_then_la1 @@ -7638,7 +7679,6 @@ print_sbyte: { //SEG338 print_sbyte::@2 b2: //SEG339 [165] (byte~) print_byte::b#9 ← (byte)(signed byte) print_sbyte::b#7 - // (byte~) print_byte::b#9 = (byte)(signed byte) print_sbyte::b#7 // register copy zp ZP_BYTE:7 //SEG340 [166] call print_byte //SEG341 [64] phi from print_sbyte::@2 to print_byte [phi:print_sbyte::@2->print_byte] print_byte_from_b2: @@ -7674,6 +7714,12 @@ print_sbyte: { jmp b2_from_b5 } //SEG354 div8s +// Perform division on two signed 8-bit numbers +// Returns dividend/divisor. +// The remainder will be set into the global variable rem8s. +// 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 div8s: { .label neg = $10 //SEG355 [171] if((signed byte) div8s::dividend#0<(byte/signed byte/word/signed word/dword/signed dword) 0) goto div8s::@1 -- vbsyy_lt_0_then_la1 @@ -7683,7 +7729,6 @@ div8s: { //SEG356 div8s::@16 b16: //SEG357 [172] (byte~) div8s::dividendu#8 ← (byte)(signed byte) div8s::dividend#0 - // (byte~) div8s::dividendu#8 = (byte)(signed byte) div8s::dividend#0 // register copy reg byte y //SEG358 [173] phi from div8s::@16 to div8s::@2 [phi:div8s::@16->div8s::@2] b2_from_b16: //SEG359 [173] phi (byte) div8s::dividendu#3 = (byte~) div8s::dividendu#8 [phi:div8s::@16->div8s::@2#0] -- register_copy @@ -7700,7 +7745,6 @@ div8s: { //SEG363 div8s::@17 b17: //SEG364 [175] (byte~) div8s::divisoru#5 ← (byte)(signed byte) div8s::divisor#0 - // (byte~) div8s::divisoru#5 = (byte)(signed byte) div8s::divisor#0 // register copy reg byte x //SEG365 [176] phi from div8s::@17 div8s::@3 to div8s::@4 [phi:div8s::@17/div8s::@3->div8s::@4] b4_from_b17: b4_from_b3: @@ -7712,7 +7756,6 @@ div8s: { //SEG369 [177] (byte) div8u::dividend#0 ← (byte) div8s::dividendu#3 -- vbuaa=vbuyy tya //SEG370 [178] (byte) div8u::divisor#0 ← (byte) div8s::divisoru#3 - // (byte) div8u::divisor#0 = (byte) div8s::divisoru#3 // register copy reg byte x //SEG371 [179] call div8u //SEG372 [194] phi from div8s::@4 to div8u [phi:div8s::@4->div8u] div8u_from_b4: @@ -7720,7 +7763,6 @@ div8s: { //SEG374 [194] phi (byte) div8u::dividend#2 = (byte) div8u::dividend#0 [phi:div8s::@4->div8u#1] -- register_copy jsr div8u //SEG375 [180] (byte) div8u::return#2 ← (byte) div8u::return#0 - // (byte) div8u::return#2 = (byte) div8u::return#0 // register copy reg byte a jmp b15 //SEG376 div8s::@15 b15: @@ -7759,7 +7801,6 @@ div8s: { //SEG388 [187] (signed byte~) div8s::return#7 ← (signed byte)(byte) div8s::resultu#0 -- vbsaa=vbsyy tya //SEG389 [188] (signed byte~) rem8s#33 ← (signed byte)(byte) rem8u#17 - // (signed byte~) rem8s#33 = (signed byte)(byte) rem8u#17 // register copy reg byte x jmp breturn_from_b18 //SEG390 div8s::@3 b3: @@ -7774,7 +7815,6 @@ div8s: { eor #1 sta neg //SEG393 [191] (byte~) div8s::divisoru#4 ← (byte)(signed byte~) div8s::$6 - // (byte~) div8s::divisoru#4 = (byte)(signed byte~) div8s::$6 // register copy reg byte x jmp b4_from_b3 //SEG394 div8s::@1 b1: @@ -7794,6 +7834,10 @@ div8s: { jmp b2 } //SEG400 div8u +// Performs division on two 8 bit unsigned bytes +// Returns dividend/divisor. +// The remainder will be set into the global variable rem8u +// Implemented using simple binary division div8u: { //SEG401 [195] (byte) divr8u::dividend#0 ← (byte) div8u::dividend#2 -- vbuz1=vbuaa sta divr8u.dividend @@ -7809,7 +7853,6 @@ div8u: { //SEG406 div8u::@2 b2: //SEG407 [199] (byte) div8u::return#0 ← (byte) divr8u::return#0 - // (byte) div8u::return#0 = (byte) divr8u::return#0 // register copy reg byte a jmp breturn //SEG408 div8u::@return breturn: @@ -7817,6 +7860,10 @@ div8u: { rts } //SEG410 divr8u +// Performs division on two 8 bit unsigned bytes and an initial remainder +// Returns dividend/divisor. +// The final remainder will be set into the global variable rem8u +// Implemented using simple binary division divr8u: { .label dividend = $11 .label divisor = $16 @@ -7939,20 +7986,15 @@ test_16u: { lda divisors+1,y sta divisor+1 //SEG454 [222] (word) div16u::dividend#0 ← (word) test_16u::dividend#0 - // (word) div16u::dividend#0 = (word) test_16u::dividend#0 // register copy zp ZP_WORD:5 //SEG455 [223] (word) div16u::divisor#0 ← (word) test_16u::divisor#0 - // (word) div16u::divisor#0 = (word) test_16u::divisor#0 // register copy zp ZP_WORD:12 //SEG456 [224] call div16u jsr div16u //SEG457 [225] (word) div16u::return#2 ← (word) div16u::return#0 - // (word) div16u::return#2 = (word) div16u::return#0 // register copy zp ZP_WORD:14 jmp b3 //SEG458 test_16u::@3 b3: //SEG459 [226] (word) test_16u::res#0 ← (word) div16u::return#2 - // (word) test_16u::res#0 = (word) div16u::return#2 // register copy zp ZP_WORD:14 //SEG460 [227] (word) print_word::w#1 ← (word) test_16u::dividend#0 - // (word) print_word::w#1 = (word) test_16u::dividend#0 // register copy zp ZP_WORD:5 //SEG461 [228] (byte*~) print_char_cursor#166 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -8082,6 +8124,10 @@ test_16u: { divisors: .word 5, 7, $b, $d, $11, $13 } //SEG509 div16u +// Performs division on two 16 bit unsigned words +// Returns the quotient dividend/divisor. +// The remainder will be set into the global variable rem16u +// Implemented using simple binary division div16u: { .label return = $e .label dividend = 5 @@ -8092,7 +8138,6 @@ div16u: { lda dividend+1 sta divr16u.dividend+1 //SEG511 [248] (word) divr16u::divisor#0 ← (word) div16u::divisor#0 - // (word) divr16u::divisor#0 = (word) div16u::divisor#0 // register copy zp ZP_WORD:12 //SEG512 [249] call divr16u //SEG513 [113] phi from div16u to divr16u [phi:div16u->divr16u] divr16u_from_div16u: @@ -8105,12 +8150,10 @@ div16u: { sta divr16u.rem+1 jsr divr16u //SEG517 [250] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:14 jmp b2 //SEG518 div16u::@2 b2: //SEG519 [251] (word) div16u::return#0 ← (word) divr16u::return#2 - // (word) div16u::return#0 = (word) divr16u::return#2 // register copy zp ZP_WORD:14 jmp breturn //SEG520 div16u::@return breturn: @@ -8160,14 +8203,12 @@ test_8u: { //SEG535 [194] phi (byte) div8u::dividend#2 = (byte) div8u::dividend#1 [phi:test_8u::@1->div8u#1] -- register_copy jsr div8u //SEG536 [260] (byte) div8u::return#3 ← (byte) div8u::return#0 - // (byte) div8u::return#3 = (byte) div8u::return#0 // register copy reg byte a jmp b3 //SEG537 test_8u::@3 b3: //SEG538 [261] (byte) test_8u::res#0 ← (byte) div8u::return#3 -- vbuz1=vbuaa sta res //SEG539 [262] (byte) print_byte::b#3 ← (byte) test_8u::dividend#0 - // (byte) print_byte::b#3 = (byte) test_8u::dividend#0 // register copy zp ZP_BYTE:7 //SEG540 [263] call print_byte //SEG541 [64] phi from test_8u::@3 to print_byte [phi:test_8u::@3->print_byte] print_byte_from_b3: @@ -8295,6 +8336,7 @@ test_8u: { divisors: .byte 5, 7, $b, $d, $11, $13 } //SEG593 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 3 //SEG594 [283] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -8505,10 +8547,15 @@ Removing instruction b2_from_print_sword: Removing instruction print_char_from_b2: Removing instruction b1_from_print_sword: Removing instruction b1_from_b4: +Removing instruction print_word_from_b1: Removing instruction b1_from_print_str: Removing instruction b1_from_b2: +Removing instruction breturn: +Removing instruction b2_from_b17: +Removing instruction b18: Removing instruction b4_from_b18: Removing instruction b4_from_b3: +Removing instruction divr16u_from_b4: Removing instruction breturn_from_b11: Removing instruction breturn_from_b19: Removing instruction b1_from_b3: @@ -8516,6 +8563,7 @@ Removing instruction b2_from_b1: Removing instruction b2_from_b4: Removing instruction b3_from_b2: Removing instruction b3_from_b5: +Removing instruction breturn: Removing instruction b1_from_b11: Removing instruction b4_from_b3: Removing instruction print_str_from_b4: @@ -8529,12 +8577,16 @@ Removing instruction b3_from_print_sbyte: Removing instruction print_char_from_b3: Removing instruction b2_from_b3: Removing instruction b2_from_b5: +Removing instruction print_byte_from_b2: Removing instruction b1_from_print_sbyte: Removing instruction print_char_from_b1: +Removing instruction b2_from_b16: +Removing instruction b17: Removing instruction b4_from_b17: Removing instruction b4_from_b3: Removing instruction breturn_from_b11: Removing instruction breturn_from_b18: +Removing instruction breturn: Removing instruction b1_from_b3: Removing instruction b2_from_b1: Removing instruction b2_from_b4: @@ -8549,6 +8601,7 @@ Removing instruction b8_from_b7: Removing instruction print_str_from_b8: Removing instruction b10_from_b9: Removing instruction print_ln_from_b10: +Removing instruction breturn: Removing instruction b4_from_b3: Removing instruction print_str_from_b4: Removing instruction b6_from_b5: @@ -8584,7 +8637,6 @@ Removing instruction breturn: Removing instruction breturn: Removing instruction b2: Removing instruction b4: -Removing instruction print_word_from_b1: Removing instruction breturn: Removing instruction print_byte_from_print_word: Removing instruction b1: @@ -8597,11 +8649,7 @@ Removing instruction breturn: Removing instruction breturn: Removing instruction breturn: Removing instruction b2: -Removing instruction breturn: Removing instruction b17: -Removing instruction b2_from_b17: -Removing instruction b18: -Removing instruction divr16u_from_b4: Removing instruction b15: Removing instruction b11: Removing instruction b2_from_b1: @@ -8609,7 +8657,6 @@ Removing instruction b1_from_divr16u: Removing instruction b4: Removing instruction b5: Removing instruction b6: -Removing instruction breturn: Removing instruction b1_from_test_8s: Removing instruction b3: Removing instruction print_sbyte_from_b3: @@ -8626,19 +8673,15 @@ Removing instruction b10: Removing instruction b11: Removing instruction breturn: Removing instruction b3: -Removing instruction print_byte_from_b2: Removing instruction breturn: Removing instruction b5: Removing instruction b16: -Removing instruction b2_from_b16: -Removing instruction b17: Removing instruction div8u_from_b4: Removing instruction b15: Removing instruction b11: Removing instruction b2_from_b1: Removing instruction divr8u_from_div8u: Removing instruction b2: -Removing instruction breturn: Removing instruction b1_from_divr8u: Removing instruction b4: Removing instruction b5: @@ -8661,7 +8704,6 @@ Removing instruction b11: Removing instruction breturn: Removing instruction divr16u_from_div16u: Removing instruction b2: -Removing instruction breturn: Removing instruction b1_from_test_8u: Removing instruction div8u_from_b1: Removing instruction b3: @@ -9234,18 +9276,13 @@ test_16s: { lda divisors+1,y sta divisor+1 //SEG38 [19] (signed word) div16s::dividend#0 ← (signed word) test_16s::dividend#0 - // (signed word) div16s::dividend#0 = (signed word) test_16s::dividend#0 // register copy zp ZP_WORD:5 //SEG39 [20] (signed word) div16s::divisor#0 ← (signed word) test_16s::divisor#0 - // (signed word) div16s::divisor#0 = (signed word) test_16s::divisor#0 // register copy zp ZP_WORD:19 //SEG40 [21] call div16s jsr div16s //SEG41 [22] (signed word) div16s::return#2 ← (signed word) div16s::return#0 - // (signed word) div16s::return#2 = (signed word) div16s::return#0 // register copy zp ZP_WORD:14 //SEG42 test_16s::@3 //SEG43 [23] (signed word) test_16s::res#0 ← (signed word) div16s::return#2 - // (signed word) test_16s::res#0 = (signed word) div16s::return#2 // register copy zp ZP_WORD:14 //SEG44 [24] (signed word) print_sword::w#1 ← (signed word) test_16s::dividend#0 - // (signed word) print_sword::w#1 = (signed word) test_16s::dividend#0 // register copy zp ZP_WORD:5 //SEG45 [25] (byte*~) print_char_cursor#159 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -9344,6 +9381,7 @@ test_16s: { divisors: .word 5, -7, $b, -$d, -$11, $13 } //SEG93 print_ln +// Print a newline print_ln: { //SEG94 [45] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] //SEG95 [45] phi (byte*) print_line_cursor#20 = (byte*) print_line_cursor#39 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy @@ -9371,6 +9409,7 @@ print_ln: { rts } //SEG101 print_sword +// Print a signed word as HEX print_sword: { .label w = 5 //SEG102 [50] if((signed word) print_sword::w#5>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -9401,7 +9440,6 @@ print_sword: { //SEG114 print_sword::@1 b1: //SEG115 [55] (word~) print_word::w#7 ← (word)(signed word) print_sword::w#6 - // (word~) print_word::w#7 = (word)(signed word) print_sword::w#6 // register copy zp ZP_WORD:5 //SEG116 [56] call print_word //SEG117 [58] phi from print_sword::@1 to print_word [phi:print_sword::@1->print_word] //SEG118 [58] phi (byte*) print_char_cursor#135 = (byte*) print_char_cursor#130 [phi:print_sword::@1->print_word#0] -- register_copy @@ -9412,6 +9450,7 @@ print_sword: { rts } //SEG122 print_word +// Print a word as HEX print_word: { .label w = 5 //SEG123 [59] (byte) print_byte::b#1 ← > (word) print_word::w#5 -- vbuz1=_hi_vwuz2 @@ -9436,6 +9475,7 @@ print_word: { rts } //SEG136 print_byte +// Print a byte as HEX print_byte: { .label b = 7 //SEG137 [65] (byte~) print_byte::$0 ← (byte) print_byte::b#7 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4 @@ -9469,6 +9509,7 @@ print_byte: { rts } //SEG152 print_char +// Print a single char print_char: { //SEG153 [73] *((byte*) print_char_cursor#82) ← (byte) print_char::ch#5 -- _deref_pbuz1=vbuaa ldy #0 @@ -9483,6 +9524,7 @@ print_char: { rts } //SEG157 print_str +// Print a zero-terminated string print_str: { .label str = 5 //SEG158 [77] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -9517,6 +9559,12 @@ print_str: { jmp b1 } //SEG169 div16s +// Perform division on two signed 16-bit numbers +// Returns dividend/divisor. +// The remainder will be set into the global variable rem16s. +// 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 div16s: { .label return = $e .label dividend = 5 @@ -9534,15 +9582,18 @@ div16s: { //SEG172 [85] call divr16s jsr divr16s //SEG173 [86] (signed word) divr16s::return#3 ← (signed word) divr16s::return#2 - // (signed word) divr16s::return#3 = (signed word) divr16s::return#2 // register copy zp ZP_WORD:14 //SEG174 div16s::@2 //SEG175 [87] (signed word) div16s::return#0 ← (signed word) divr16s::return#3 - // (signed word) div16s::return#0 = (signed word) divr16s::return#3 // register copy zp ZP_WORD:14 //SEG176 div16s::@return //SEG177 [88] return rts } //SEG178 divr16s +// Perform division on two signed 16-bit numbers with an initial remainder. +// Returns dividend/divisor. The remainder will be set into the global variable rem16s. +// 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: { .const rem = 0 .label _5 = 8 @@ -9559,7 +9610,6 @@ divr16s: { bmi b1 //SEG180 divr16s::@17 //SEG181 [90] (word~) divr16s::dividendu#8 ← (word)(signed word) divr16s::dividend#0 - // (word~) divr16s::dividendu#8 = (word)(signed word) divr16s::dividend#0 // register copy zp ZP_WORD:8 //SEG182 [91] phi from divr16s::@17 to divr16s::@2 [phi:divr16s::@17->divr16s::@2] //SEG183 [91] phi (word) divr16s::remu#3 = ((word))(const signed word) divr16s::rem#0 [phi:divr16s::@17->divr16s::@2#0] -- vwuz1=vbuc1 lda #divr16s::@4] //SEG191 [94] phi (byte) divr16s::neg#4 = (byte) divr16s::neg#3 [phi:divr16s::@18/divr16s::@3->divr16s::@4#0] -- register_copy //SEG192 [94] phi (word) divr16s::divisoru#3 = (word~) divr16s::divisoru#5 [phi:divr16s::@18/divr16s::@3->divr16s::@4#1] -- register_copy //SEG193 divr16s::@4 b4: //SEG194 [95] (word) divr16u::dividend#2 ← (word) divr16s::dividendu#3 - // (word) divr16u::dividend#2 = (word) divr16s::dividendu#3 // register copy zp ZP_WORD:8 //SEG195 [96] (word) divr16u::divisor#1 ← (word) divr16s::divisoru#3 - // (word) divr16u::divisor#1 = (word) divr16s::divisoru#3 // register copy zp ZP_WORD:12 //SEG196 [97] (word) divr16u::rem#4 ← (word) divr16s::remu#3 - // (word) divr16u::rem#4 = (word) divr16s::remu#3 // register copy zp ZP_WORD:10 //SEG197 [98] call divr16u //SEG198 [113] phi from divr16s::@4 to divr16u [phi:divr16s::@4->divr16u] //SEG199 [113] phi (word) divr16u::divisor#6 = (word) divr16u::divisor#1 [phi:divr16s::@4->divr16u#0] -- register_copy @@ -9595,10 +9641,8 @@ divr16s: { //SEG201 [113] phi (word) divr16u::rem#10 = (word) divr16u::rem#4 [phi:divr16s::@4->divr16u#2] -- register_copy jsr divr16u //SEG202 [99] (word) divr16u::return#3 ← (word) divr16u::return#0 - // (word) divr16u::return#3 = (word) divr16u::return#0 // register copy zp ZP_WORD:14 //SEG203 divr16s::@15 //SEG204 [100] (word) divr16s::resultu#0 ← (word) divr16u::return#3 - // (word) divr16s::resultu#0 = (word) divr16u::return#3 // register copy zp ZP_WORD:14 //SEG205 [101] if((byte) divr16s::neg#4==(byte/signed byte/word/signed word/dword/signed dword) 0) goto divr16s::@19 -- vbuyy_eq_0_then_la1 cpy #0 beq breturn @@ -9632,9 +9676,7 @@ divr16s: { rts //SEG214 divr16s::@19 //SEG215 [106] (signed word~) divr16s::return#7 ← (signed word)(word) divr16s::resultu#0 - // (signed word~) divr16s::return#7 = (signed word)(word) divr16s::resultu#0 // register copy zp ZP_WORD:14 //SEG216 [107] (signed word~) rem16s#37 ← (signed word)(word) rem16u#1 - // (signed word~) rem16s#37 = (signed word)(word) rem16u#1 // register copy zp ZP_WORD:10 //SEG217 divr16s::@3 b3: //SEG218 [108] (signed word~) divr16s::$11 ← - (signed word) divr16s::divisor#0 -- vwsz1=_neg_vwsz1 @@ -9652,7 +9694,6 @@ divr16s: { eor #1 tay //SEG220 [110] (word~) divr16s::divisoru#4 ← (word)(signed word~) divr16s::$11 - // (word~) divr16s::divisoru#4 = (word)(signed word~) divr16s::$11 // register copy zp ZP_WORD:12 jmp b4 //SEG221 divr16s::@1 b1: @@ -9667,7 +9708,6 @@ divr16s: { adc #0 sta _5+1 //SEG223 [112] (word~) divr16s::dividendu#7 ← (word)(signed word~) divr16s::$5 - // (word~) divr16s::dividendu#7 = (word)(signed word~) divr16s::$5 // register copy zp ZP_WORD:8 //SEG224 [91] phi from divr16s::@1 to divr16s::@2 [phi:divr16s::@1->divr16s::@2] //SEG225 [91] phi (word) divr16s::remu#3 = ((word))-(const signed word) divr16s::rem#0 [phi:divr16s::@1->divr16s::@2#0] -- vwuz1=vbuc1 lda #<-rem @@ -9680,6 +9720,10 @@ divr16s: { jmp b2 } //SEG228 divr16u +// Performs division on two 16 bit unsigned words and an initial remainder +// Returns the quotient dividend/divisor. +// The final remainder will be set into the global variable rem16u +// Implemented using simple binary division divr16u: { .label rem = $a .label dividend = 8 @@ -9762,7 +9806,6 @@ divr16u: { bne b1 //SEG261 divr16u::@6 //SEG262 [129] (word) rem16u#1 ← (word) divr16u::rem#11 - // (word) rem16u#1 = (word) divr16u::rem#11 // register copy zp ZP_WORD:10 //SEG263 divr16u::@return //SEG264 [130] return rts @@ -9795,12 +9838,10 @@ test_8s: { //SEG275 [137] call div8s jsr div8s //SEG276 [138] (signed byte) div8s::return#3 ← (signed byte) div8s::return#2 - // (signed byte) div8s::return#3 = (signed byte) div8s::return#2 // register copy reg byte a //SEG277 test_8s::@3 //SEG278 [139] (signed byte) test_8s::res#0 ← (signed byte) div8s::return#3 -- vbsz1=vbsaa sta res //SEG279 [140] (signed byte) print_sbyte::b#1 ← (signed byte) test_8s::dividend#0 - // (signed byte) print_sbyte::b#1 = (signed byte) test_8s::dividend#0 // register copy zp ZP_BYTE:7 //SEG280 [141] (byte*~) print_char_cursor#184 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -9890,6 +9931,7 @@ test_8s: { divisors: .byte 5, 7, -$b, -$d, $11, $13 } //SEG328 print_sbyte +// Print a signed byte as HEX print_sbyte: { .label b = 7 //SEG329 [161] if((signed byte) print_sbyte::b#10<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsz1_lt_0_then_la1 @@ -9908,7 +9950,6 @@ print_sbyte: { //SEG338 print_sbyte::@2 b2: //SEG339 [165] (byte~) print_byte::b#9 ← (byte)(signed byte) print_sbyte::b#7 - // (byte~) print_byte::b#9 = (byte)(signed byte) print_sbyte::b#7 // register copy zp ZP_BYTE:7 //SEG340 [166] call print_byte //SEG341 [64] phi from print_sbyte::@2 to print_byte [phi:print_sbyte::@2->print_byte] //SEG342 [64] phi (byte*) print_char_cursor#136 = (byte*) print_char_cursor#18 [phi:print_sbyte::@2->print_byte#0] -- register_copy @@ -9936,6 +9977,12 @@ print_sbyte: { jmp b2 } //SEG354 div8s +// Perform division on two signed 8-bit numbers +// Returns dividend/divisor. +// The remainder will be set into the global variable rem8s. +// 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 div8s: { .label neg = $10 //SEG355 [171] if((signed byte) div8s::dividend#0<(byte/signed byte/word/signed word/dword/signed dword) 0) goto div8s::@1 -- vbsyy_lt_0_then_la1 @@ -9943,7 +9990,6 @@ div8s: { bmi b1 //SEG356 div8s::@16 //SEG357 [172] (byte~) div8s::dividendu#8 ← (byte)(signed byte) div8s::dividend#0 - // (byte~) div8s::dividendu#8 = (byte)(signed byte) div8s::dividend#0 // register copy reg byte y //SEG358 [173] phi from div8s::@16 to div8s::@2 [phi:div8s::@16->div8s::@2] //SEG359 [173] phi (byte) div8s::dividendu#3 = (byte~) div8s::dividendu#8 [phi:div8s::@16->div8s::@2#0] -- register_copy //SEG360 [173] phi (byte) div8s::neg#3 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:div8s::@16->div8s::@2#1] -- vbuz1=vbuc1 @@ -9956,7 +10002,6 @@ div8s: { bmi b3 //SEG363 div8s::@17 //SEG364 [175] (byte~) div8s::divisoru#5 ← (byte)(signed byte) div8s::divisor#0 - // (byte~) div8s::divisoru#5 = (byte)(signed byte) div8s::divisor#0 // register copy reg byte x //SEG365 [176] phi from div8s::@17 div8s::@3 to div8s::@4 [phi:div8s::@17/div8s::@3->div8s::@4] //SEG366 [176] phi (byte) div8s::neg#4 = (byte) div8s::neg#3 [phi:div8s::@17/div8s::@3->div8s::@4#0] -- register_copy //SEG367 [176] phi (byte) div8s::divisoru#3 = (byte~) div8s::divisoru#5 [phi:div8s::@17/div8s::@3->div8s::@4#1] -- register_copy @@ -9965,14 +10010,12 @@ div8s: { //SEG369 [177] (byte) div8u::dividend#0 ← (byte) div8s::dividendu#3 -- vbuaa=vbuyy tya //SEG370 [178] (byte) div8u::divisor#0 ← (byte) div8s::divisoru#3 - // (byte) div8u::divisor#0 = (byte) div8s::divisoru#3 // register copy reg byte x //SEG371 [179] call div8u //SEG372 [194] phi from div8s::@4 to div8u [phi:div8s::@4->div8u] //SEG373 [194] phi (byte) div8u::divisor#2 = (byte) div8u::divisor#0 [phi:div8s::@4->div8u#0] -- register_copy //SEG374 [194] phi (byte) div8u::dividend#2 = (byte) div8u::dividend#0 [phi:div8s::@4->div8u#1] -- register_copy jsr div8u //SEG375 [180] (byte) div8u::return#2 ← (byte) div8u::return#0 - // (byte) div8u::return#2 = (byte) div8u::return#0 // register copy reg byte a //SEG376 div8s::@15 //SEG377 [181] (byte) div8s::resultu#0 ← (byte) div8u::return#2 -- vbuyy=vbuaa tay @@ -10004,7 +10047,6 @@ div8s: { //SEG388 [187] (signed byte~) div8s::return#7 ← (signed byte)(byte) div8s::resultu#0 -- vbsaa=vbsyy tya //SEG389 [188] (signed byte~) rem8s#33 ← (signed byte)(byte) rem8u#17 - // (signed byte~) rem8s#33 = (signed byte)(byte) rem8u#17 // register copy reg byte x jmp breturn //SEG390 div8s::@3 b3: @@ -10019,7 +10061,6 @@ div8s: { eor #1 sta neg //SEG393 [191] (byte~) div8s::divisoru#4 ← (byte)(signed byte~) div8s::$6 - // (byte~) div8s::divisoru#4 = (byte)(signed byte~) div8s::$6 // register copy reg byte x jmp b4 //SEG394 div8s::@1 b1: @@ -10038,6 +10079,10 @@ div8s: { jmp b2 } //SEG400 div8u +// Performs division on two 8 bit unsigned bytes +// Returns dividend/divisor. +// The remainder will be set into the global variable rem8u +// Implemented using simple binary division div8u: { //SEG401 [195] (byte) divr8u::dividend#0 ← (byte) div8u::dividend#2 -- vbuz1=vbuaa sta divr8u.dividend @@ -10050,12 +10095,15 @@ div8u: { lda divr8u.return //SEG406 div8u::@2 //SEG407 [199] (byte) div8u::return#0 ← (byte) divr8u::return#0 - // (byte) div8u::return#0 = (byte) divr8u::return#0 // register copy reg byte a //SEG408 div8u::@return //SEG409 [200] return rts } //SEG410 divr8u +// Performs division on two 8 bit unsigned bytes and an initial remainder +// Returns dividend/divisor. +// The final remainder will be set into the global variable rem8u +// Implemented using simple binary division divr8u: { .label dividend = $11 .label divisor = $16 @@ -10155,18 +10203,13 @@ test_16u: { lda divisors+1,y sta divisor+1 //SEG454 [222] (word) div16u::dividend#0 ← (word) test_16u::dividend#0 - // (word) div16u::dividend#0 = (word) test_16u::dividend#0 // register copy zp ZP_WORD:5 //SEG455 [223] (word) div16u::divisor#0 ← (word) test_16u::divisor#0 - // (word) div16u::divisor#0 = (word) test_16u::divisor#0 // register copy zp ZP_WORD:12 //SEG456 [224] call div16u jsr div16u //SEG457 [225] (word) div16u::return#2 ← (word) div16u::return#0 - // (word) div16u::return#2 = (word) div16u::return#0 // register copy zp ZP_WORD:14 //SEG458 test_16u::@3 //SEG459 [226] (word) test_16u::res#0 ← (word) div16u::return#2 - // (word) test_16u::res#0 = (word) div16u::return#2 // register copy zp ZP_WORD:14 //SEG460 [227] (word) print_word::w#1 ← (word) test_16u::dividend#0 - // (word) print_word::w#1 = (word) test_16u::dividend#0 // register copy zp ZP_WORD:5 //SEG461 [228] (byte*~) print_char_cursor#166 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 lda print_line_cursor sta print_char_cursor @@ -10265,6 +10308,10 @@ test_16u: { divisors: .word 5, 7, $b, $d, $11, $13 } //SEG509 div16u +// Performs division on two 16 bit unsigned words +// Returns the quotient dividend/divisor. +// The remainder will be set into the global variable rem16u +// Implemented using simple binary division div16u: { .label return = $e .label dividend = 5 @@ -10275,7 +10322,6 @@ div16u: { lda dividend+1 sta divr16u.dividend+1 //SEG511 [248] (word) divr16u::divisor#0 ← (word) div16u::divisor#0 - // (word) divr16u::divisor#0 = (word) div16u::divisor#0 // register copy zp ZP_WORD:12 //SEG512 [249] call divr16u //SEG513 [113] phi from div16u to divr16u [phi:div16u->divr16u] //SEG514 [113] phi (word) divr16u::divisor#6 = (word) divr16u::divisor#0 [phi:div16u->divr16u#0] -- register_copy @@ -10286,10 +10332,8 @@ div16u: { sta divr16u.rem+1 jsr divr16u //SEG517 [250] (word) divr16u::return#2 ← (word) divr16u::return#0 - // (word) divr16u::return#2 = (word) divr16u::return#0 // register copy zp ZP_WORD:14 //SEG518 div16u::@2 //SEG519 [251] (word) div16u::return#0 ← (word) divr16u::return#2 - // (word) div16u::return#0 = (word) divr16u::return#2 // register copy zp ZP_WORD:14 //SEG520 div16u::@return //SEG521 [252] return rts @@ -10333,12 +10377,10 @@ test_8u: { //SEG535 [194] phi (byte) div8u::dividend#2 = (byte) div8u::dividend#1 [phi:test_8u::@1->div8u#1] -- register_copy jsr div8u //SEG536 [260] (byte) div8u::return#3 ← (byte) div8u::return#0 - // (byte) div8u::return#3 = (byte) div8u::return#0 // register copy reg byte a //SEG537 test_8u::@3 //SEG538 [261] (byte) test_8u::res#0 ← (byte) div8u::return#3 -- vbuz1=vbuaa sta res //SEG539 [262] (byte) print_byte::b#3 ← (byte) test_8u::dividend#0 - // (byte) print_byte::b#3 = (byte) test_8u::dividend#0 // register copy zp ZP_BYTE:7 //SEG540 [263] call print_byte //SEG541 [64] phi from test_8u::@3 to print_byte [phi:test_8u::@3->print_byte] //SEG542 [64] phi (byte*) print_char_cursor#136 = (byte*) print_char_cursor#138 [phi:test_8u::@3->print_byte#0] -- register_copy @@ -10435,6 +10477,7 @@ test_8u: { divisors: .byte 5, 7, $b, $d, $11, $13 } //SEG593 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 3 //SEG594 [283] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] diff --git a/src/test/ref/test-kasm.asm b/src/test/ref/test-kasm.asm index ac6f7bbc3..c93ac3be3 100644 --- a/src/test/ref/test-kasm.asm +++ b/src/test/ref/test-kasm.asm @@ -3,6 +3,7 @@ .pc = $80d "Program" .byte 1, 2, 3 +// Test inline KickAssembler code main: { b2: inc $d020 diff --git a/src/test/ref/test-kasm.log b/src/test/ref/test-kasm.log index d07db78e8..a8923855e 100644 --- a/src/test/ref/test-kasm.log +++ b/src/test/ref/test-kasm.log @@ -103,6 +103,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Test inline KickAssembler code main: { jmp b2 //SEG10 main::@2 @@ -146,6 +147,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Test inline KickAssembler code main: { jmp b2 //SEG10 main::@2 @@ -200,6 +202,7 @@ Score: 2846 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Test inline KickAssembler code main: { //SEG10 main::@2 b2: diff --git a/src/test/ref/test-keyboard-space.asm b/src/test/ref/test-keyboard-space.asm index f98789ea3..bf06fd9f0 100644 --- a/src/test/ref/test-keyboard-space.asm +++ b/src/test/ref/test-keyboard-space.asm @@ -27,6 +27,10 @@ main: { sta BGCOL jmp b4 } +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { .const colidx = KEY_SPACE&7 .label rowidx = KEY_SPACE>>3 @@ -34,6 +38,11 @@ keyboard_key_pressed: { and keyboard_matrix_col_bitmask+colidx rts } +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { lda keyboard_matrix_row_bitmask+keyboard_key_pressed.rowidx sta CIA1_PORT_A @@ -41,6 +50,7 @@ keyboard_matrix_read: { eor #$ff rts } +// Initialize keyboard reading by setting CIA#$ Data Direction Registers keyboard_init: { lda #$ff sta CIA1_PORT_A_DDR diff --git a/src/test/ref/test-keyboard-space.log b/src/test/ref/test-keyboard-space.log index ef732d6b3..1649b171e 100644 --- a/src/test/ref/test-keyboard-space.log +++ b/src/test/ref/test-keyboard-space.log @@ -1166,6 +1166,10 @@ main: { jmp b4 } //SEG25 keyboard_key_pressed +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { .const colidx = KEY_SPACE&7 .label rowidx = KEY_SPACE>>3 @@ -1194,6 +1198,11 @@ keyboard_key_pressed: { rts } //SEG33 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { .label return = 7 .label return_2 = 4 @@ -1211,6 +1220,7 @@ keyboard_matrix_read: { rts } //SEG38 keyboard_init +// Initialize keyboard reading by setting CIA#$ Data Direction Registers keyboard_init: { //SEG39 [23] *((const byte*) CIA1_PORT_A_DDR#0) ← (byte/word/signed word/dword/signed dword) 255 -- _deref_pbuc1=vbuc2 lda #$ff @@ -1308,12 +1318,10 @@ main: { keyboard_key_pressed_from_b9: jsr keyboard_key_pressed //SEG17 [9] (byte) keyboard_key_pressed::return#2 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#2 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b14 //SEG18 main::@14 b14: //SEG19 [10] (byte~) main::$2 ← (byte) keyboard_key_pressed::return#2 - // (byte~) main::$2 = (byte) keyboard_key_pressed::return#2 // register copy reg byte a //SEG20 [11] if((byte~) main::$2!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@5 -- vbuaa_neq_0_then_la1 cmp #0 bne b5 @@ -1332,18 +1340,20 @@ main: { jmp b4 } //SEG25 keyboard_key_pressed +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { .const colidx = KEY_SPACE&7 .label rowidx = KEY_SPACE>>3 //SEG26 [15] call keyboard_matrix_read jsr keyboard_matrix_read //SEG27 [16] (byte) keyboard_matrix_read::return#2 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#2 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a jmp b2 //SEG28 keyboard_key_pressed::@2 b2: //SEG29 [17] (byte~) keyboard_key_pressed::$2 ← (byte) keyboard_matrix_read::return#2 - // (byte~) keyboard_key_pressed::$2 = (byte) keyboard_matrix_read::return#2 // register copy reg byte a //SEG30 [18] (byte) keyboard_key_pressed::return#0 ← (byte~) keyboard_key_pressed::$2 & *((const byte[8]) keyboard_matrix_col_bitmask#0+(const byte) keyboard_key_pressed::colidx#0) -- vbuaa=vbuaa_band__deref_pbuc1 and keyboard_matrix_col_bitmask+colidx jmp breturn @@ -1353,6 +1363,11 @@ keyboard_key_pressed: { rts } //SEG33 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { //SEG34 [20] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0+(const byte) keyboard_key_pressed::rowidx#0) -- _deref_pbuc1=_deref_pbuc2 lda keyboard_matrix_row_bitmask+keyboard_key_pressed.rowidx @@ -1367,6 +1382,7 @@ keyboard_matrix_read: { rts } //SEG38 keyboard_init +// Initialize keyboard reading by setting CIA#$ Data Direction Registers keyboard_init: { //SEG39 [23] *((const byte*) CIA1_PORT_A_DDR#0) ← (byte/word/signed word/dword/signed dword) 255 -- _deref_pbuc1=vbuc2 lda #$ff @@ -1664,10 +1680,8 @@ main: { //SEG16 [14] phi from main::@9 to keyboard_key_pressed [phi:main::@9->keyboard_key_pressed] jsr keyboard_key_pressed //SEG17 [9] (byte) keyboard_key_pressed::return#2 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#2 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG18 main::@14 //SEG19 [10] (byte~) main::$2 ← (byte) keyboard_key_pressed::return#2 - // (byte~) main::$2 = (byte) keyboard_key_pressed::return#2 // register copy reg byte a //SEG20 [11] if((byte~) main::$2!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@5 -- vbuaa_neq_0_then_la1 cmp #0 bne b5 @@ -1684,16 +1698,18 @@ main: { jmp b4 } //SEG25 keyboard_key_pressed +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { .const colidx = KEY_SPACE&7 .label rowidx = KEY_SPACE>>3 //SEG26 [15] call keyboard_matrix_read jsr keyboard_matrix_read //SEG27 [16] (byte) keyboard_matrix_read::return#2 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#2 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a //SEG28 keyboard_key_pressed::@2 //SEG29 [17] (byte~) keyboard_key_pressed::$2 ← (byte) keyboard_matrix_read::return#2 - // (byte~) keyboard_key_pressed::$2 = (byte) keyboard_matrix_read::return#2 // register copy reg byte a //SEG30 [18] (byte) keyboard_key_pressed::return#0 ← (byte~) keyboard_key_pressed::$2 & *((const byte[8]) keyboard_matrix_col_bitmask#0+(const byte) keyboard_key_pressed::colidx#0) -- vbuaa=vbuaa_band__deref_pbuc1 and keyboard_matrix_col_bitmask+colidx //SEG31 keyboard_key_pressed::@return @@ -1701,6 +1717,11 @@ keyboard_key_pressed: { rts } //SEG33 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { //SEG34 [20] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0+(const byte) keyboard_key_pressed::rowidx#0) -- _deref_pbuc1=_deref_pbuc2 lda keyboard_matrix_row_bitmask+keyboard_key_pressed.rowidx @@ -1713,6 +1734,7 @@ keyboard_matrix_read: { rts } //SEG38 keyboard_init +// Initialize keyboard reading by setting CIA#$ Data Direction Registers keyboard_init: { //SEG39 [23] *((const byte*) CIA1_PORT_A_DDR#0) ← (byte/word/signed word/dword/signed dword) 255 -- _deref_pbuc1=vbuc2 lda #$ff diff --git a/src/test/ref/test-keyboard.asm b/src/test/ref/test-keyboard.asm index de1a2345d..d372d34c2 100644 --- a/src/test/ref/test-keyboard.asm +++ b/src/test/ref/test-keyboard.asm @@ -165,6 +165,10 @@ main: { sta (screen),y jmp b9 } +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { .label colidx = 5 tya @@ -180,6 +184,11 @@ keyboard_key_pressed: { and keyboard_matrix_col_bitmask,y rts } +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { lda keyboard_matrix_row_bitmask,y sta CIA1_PORT_A @@ -187,10 +196,15 @@ keyboard_matrix_read: { eor #$ff rts } +// Get the keycode corresponding to a specific screen code character +// ch is the character to get the key code for ($00-$3f) +// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled. +// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) . keyboard_get_keycode: { lda keyboard_char_keycodes,y rts } +// Initialize keyboard reading by setting CIA#$ Data Direction Registers keyboard_init: { lda #$ff sta CIA1_PORT_A_DDR diff --git a/src/test/ref/test-keyboard.log b/src/test/ref/test-keyboard.log index 629de0912..326613e74 100644 --- a/src/test/ref/test-keyboard.log +++ b/src/test/ref/test-keyboard.log @@ -1946,6 +1946,10 @@ main: { jmp b9 } //SEG94 keyboard_key_pressed +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { .label _2 = $19 .label colidx = $16 @@ -1992,6 +1996,11 @@ keyboard_key_pressed: { rts } //SEG107 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { .label return = $1b .label rowid = $b @@ -2012,6 +2021,10 @@ keyboard_matrix_read: { rts } //SEG112 keyboard_get_keycode +// Get the keycode corresponding to a specific screen code character +// ch is the character to get the key code for ($00-$3f) +// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled. +// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) . keyboard_get_keycode: { .label return = $1c .label ch = $10 @@ -2027,6 +2040,7 @@ keyboard_get_keycode: { rts } //SEG116 keyboard_init +// Initialize keyboard reading by setting CIA#$ Data Direction Registers keyboard_init: { //SEG117 [63] *((const byte*) CIA1_PORT_A_DDR#0) ← (byte/word/signed word/dword/signed dword) 255 -- _deref_pbuc1=vbuc2 lda #$ff @@ -2299,7 +2313,6 @@ main: { //SEG33 [57] phi (byte) keyboard_matrix_read::rowid#2 = (byte) keyboard_matrix_read::rowid#1 [phi:main::@6->keyboard_matrix_read#0] -- register_copy jsr keyboard_matrix_read //SEG34 [15] (byte) keyboard_matrix_read::return#3 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#3 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a jmp b28 //SEG35 main::@28 b28: @@ -2390,12 +2403,10 @@ main: { //SEG66 [30] call keyboard_get_keycode jsr keyboard_get_keycode //SEG67 [31] (byte) keyboard_get_keycode::return#2 ← (byte) keyboard_get_keycode::return#0 - // (byte) keyboard_get_keycode::return#2 = (byte) keyboard_get_keycode::return#0 // register copy reg byte a jmp b29 //SEG68 main::@29 b29: //SEG69 [32] (byte) main::key#0 ← (byte) keyboard_get_keycode::return#2 - // (byte) main::key#0 = (byte) keyboard_get_keycode::return#2 // register copy reg byte a //SEG70 [33] if((byte) main::key#0==(byte/signed byte/word/signed word/dword/signed dword) 63) goto main::@11 -- vbuaa_eq_vbuc1_then_la1 cmp #$3f beq b11_from_b29 @@ -2407,12 +2418,10 @@ main: { //SEG73 [35] call keyboard_key_pressed jsr keyboard_key_pressed //SEG74 [36] (byte) keyboard_key_pressed::return#2 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#2 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a jmp b30 //SEG75 main::@30 b30: //SEG76 [37] (byte~) main::$15 ← (byte) keyboard_key_pressed::return#2 - // (byte~) main::$15 = (byte) keyboard_key_pressed::return#2 // register copy reg byte a //SEG77 [38] if((byte~) main::$15==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@11 -- vbuaa_eq_0_then_la1 cmp #0 beq b11_from_b30 @@ -2466,6 +2475,10 @@ main: { jmp b9 } //SEG94 keyboard_key_pressed +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { .label colidx = 5 //SEG95 [49] (byte) keyboard_key_pressed::colidx#0 ← (byte) keyboard_key_pressed::key#0 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuz1=vbuyy_band_vbuc1 @@ -2485,12 +2498,10 @@ keyboard_key_pressed: { //SEG100 [57] phi (byte) keyboard_matrix_read::rowid#2 = (byte) keyboard_matrix_read::rowid#0 [phi:keyboard_key_pressed->keyboard_matrix_read#0] -- register_copy jsr keyboard_matrix_read //SEG101 [53] (byte) keyboard_matrix_read::return#2 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#2 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a jmp b2 //SEG102 keyboard_key_pressed::@2 b2: //SEG103 [54] (byte~) keyboard_key_pressed::$2 ← (byte) keyboard_matrix_read::return#2 - // (byte~) keyboard_key_pressed::$2 = (byte) keyboard_matrix_read::return#2 // register copy reg byte a //SEG104 [55] (byte) keyboard_key_pressed::return#0 ← (byte~) keyboard_key_pressed::$2 & *((const byte[8]) keyboard_matrix_col_bitmask#0 + (byte) keyboard_key_pressed::colidx#0) -- vbuaa=vbuaa_band_pbuc1_derefidx_vbuz1 ldy colidx and keyboard_matrix_col_bitmask,y @@ -2501,6 +2512,11 @@ keyboard_key_pressed: { rts } //SEG107 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { //SEG108 [58] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0 + (byte) keyboard_matrix_read::rowid#2) -- _deref_pbuc1=pbuc2_derefidx_vbuyy lda keyboard_matrix_row_bitmask,y @@ -2515,6 +2531,10 @@ keyboard_matrix_read: { rts } //SEG112 keyboard_get_keycode +// Get the keycode corresponding to a specific screen code character +// ch is the character to get the key code for ($00-$3f) +// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled. +// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) . keyboard_get_keycode: { //SEG113 [61] (byte) keyboard_get_keycode::return#0 ← *((const byte[]) keyboard_char_keycodes#0 + (byte) keyboard_get_keycode::ch#0) -- vbuaa=pbuc1_derefidx_vbuyy lda keyboard_char_keycodes,y @@ -2525,6 +2545,7 @@ keyboard_get_keycode: { rts } //SEG116 keyboard_init +// Initialize keyboard reading by setting CIA#$ Data Direction Registers keyboard_init: { //SEG117 [63] *((const byte*) CIA1_PORT_A_DDR#0) ← (byte/word/signed word/dword/signed dword) 255 -- _deref_pbuc1=vbuc2 lda #$ff @@ -3083,7 +3104,6 @@ main: { //SEG33 [57] phi (byte) keyboard_matrix_read::rowid#2 = (byte) keyboard_matrix_read::rowid#1 [phi:main::@6->keyboard_matrix_read#0] -- register_copy jsr keyboard_matrix_read //SEG34 [15] (byte) keyboard_matrix_read::return#3 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#3 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a //SEG35 main::@28 //SEG36 [16] (byte) main::row_pressed_bits#0 ← (byte) keyboard_matrix_read::return#3 -- vbuxx=vbuaa tax @@ -3157,10 +3177,8 @@ main: { //SEG66 [30] call keyboard_get_keycode jsr keyboard_get_keycode //SEG67 [31] (byte) keyboard_get_keycode::return#2 ← (byte) keyboard_get_keycode::return#0 - // (byte) keyboard_get_keycode::return#2 = (byte) keyboard_get_keycode::return#0 // register copy reg byte a //SEG68 main::@29 //SEG69 [32] (byte) main::key#0 ← (byte) keyboard_get_keycode::return#2 - // (byte) main::key#0 = (byte) keyboard_get_keycode::return#2 // register copy reg byte a //SEG70 [33] if((byte) main::key#0==(byte/signed byte/word/signed word/dword/signed dword) 63) goto main::@11 -- vbuaa_eq_vbuc1_then_la1 cmp #$3f beq b11 @@ -3170,10 +3188,8 @@ main: { //SEG73 [35] call keyboard_key_pressed jsr keyboard_key_pressed //SEG74 [36] (byte) keyboard_key_pressed::return#2 ← (byte) keyboard_key_pressed::return#0 - // (byte) keyboard_key_pressed::return#2 = (byte) keyboard_key_pressed::return#0 // register copy reg byte a //SEG75 main::@30 //SEG76 [37] (byte~) main::$15 ← (byte) keyboard_key_pressed::return#2 - // (byte~) main::$15 = (byte) keyboard_key_pressed::return#2 // register copy reg byte a //SEG77 [38] if((byte~) main::$15==(byte/signed byte/word/signed word/dword/signed dword) 0) goto main::@11 -- vbuaa_eq_0_then_la1 cmp #0 beq b11 @@ -3218,6 +3234,10 @@ main: { jmp b9 } //SEG94 keyboard_key_pressed +// Determines whether a specific key is currently pressed by accessing the matrix directly +// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7) +// All keys exist as as KEY_XXX constants. +// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed keyboard_key_pressed: { .label colidx = 5 //SEG95 [49] (byte) keyboard_key_pressed::colidx#0 ← (byte) keyboard_key_pressed::key#0 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuz1=vbuyy_band_vbuc1 @@ -3236,10 +3256,8 @@ keyboard_key_pressed: { //SEG100 [57] phi (byte) keyboard_matrix_read::rowid#2 = (byte) keyboard_matrix_read::rowid#0 [phi:keyboard_key_pressed->keyboard_matrix_read#0] -- register_copy jsr keyboard_matrix_read //SEG101 [53] (byte) keyboard_matrix_read::return#2 ← (byte) keyboard_matrix_read::return#0 - // (byte) keyboard_matrix_read::return#2 = (byte) keyboard_matrix_read::return#0 // register copy reg byte a //SEG102 keyboard_key_pressed::@2 //SEG103 [54] (byte~) keyboard_key_pressed::$2 ← (byte) keyboard_matrix_read::return#2 - // (byte~) keyboard_key_pressed::$2 = (byte) keyboard_matrix_read::return#2 // register copy reg byte a //SEG104 [55] (byte) keyboard_key_pressed::return#0 ← (byte~) keyboard_key_pressed::$2 & *((const byte[8]) keyboard_matrix_col_bitmask#0 + (byte) keyboard_key_pressed::colidx#0) -- vbuaa=vbuaa_band_pbuc1_derefidx_vbuz1 ldy colidx and keyboard_matrix_col_bitmask,y @@ -3248,6 +3266,11 @@ keyboard_key_pressed: { rts } //SEG107 keyboard_matrix_read +// Read a single row of the keyboard matrix +// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs. +// Returns the keys pressed on the row as bits according to the C64 key matrix. +// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write +// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader. keyboard_matrix_read: { //SEG108 [58] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0 + (byte) keyboard_matrix_read::rowid#2) -- _deref_pbuc1=pbuc2_derefidx_vbuyy lda keyboard_matrix_row_bitmask,y @@ -3260,6 +3283,10 @@ keyboard_matrix_read: { rts } //SEG112 keyboard_get_keycode +// Get the keycode corresponding to a specific screen code character +// ch is the character to get the key code for ($00-$3f) +// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled. +// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) . keyboard_get_keycode: { //SEG113 [61] (byte) keyboard_get_keycode::return#0 ← *((const byte[]) keyboard_char_keycodes#0 + (byte) keyboard_get_keycode::ch#0) -- vbuaa=pbuc1_derefidx_vbuyy lda keyboard_char_keycodes,y @@ -3268,6 +3295,7 @@ keyboard_get_keycode: { rts } //SEG116 keyboard_init +// Initialize keyboard reading by setting CIA#$ Data Direction Registers keyboard_init: { //SEG117 [63] *((const byte*) CIA1_PORT_A_DDR#0) ← (byte/word/signed word/dword/signed dword) 255 -- _deref_pbuc1=vbuc2 lda #$ff diff --git a/src/test/ref/test-lowhigh.asm b/src/test/ref/test-lowhigh.asm index 81b2f132a..9065e2247 100644 --- a/src/test/ref/test-lowhigh.asm +++ b/src/test/ref/test-lowhigh.asm @@ -154,6 +154,7 @@ main: { sta print_char_cursor+1 jmp b1 } +// Print a newline print_ln: { b1: lda print_line_cursor @@ -173,6 +174,7 @@ print_ln: { !: rts } +// Print a byte as HEX print_byte: { txa lsr @@ -189,6 +191,7 @@ print_byte: { jsr print_char rts } +// Print a single char print_char: { ldy #0 sta (print_char_cursor),y @@ -198,6 +201,7 @@ print_char: { !: rts } +// Print a word as HEX print_word: { .label w = $a lda w+1 @@ -208,6 +212,7 @@ print_word: { jsr print_byte rts } +// Print a dword as HEX print_dword: { .label dw = $c lda dw+2 @@ -222,6 +227,7 @@ print_dword: { jsr print_word rts } +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 6 lda #<$400 diff --git a/src/test/ref/test-lowhigh.log b/src/test/ref/test-lowhigh.log index b30c4a2bc..1a6476660 100644 --- a/src/test/ref/test-lowhigh.log +++ b/src/test/ref/test-lowhigh.log @@ -1457,6 +1457,7 @@ main: { jmp b1 } //SEG118 print_ln +// Print a newline print_ln: { //SEG119 [52] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -1489,6 +1490,7 @@ print_ln: { rts } //SEG126 print_byte +// Print a byte as HEX print_byte: { .label _0 = $30 .label _2 = $31 @@ -1534,6 +1536,7 @@ print_byte: { rts } //SEG142 print_char +// Print a single char print_char: { .label ch = 9 //SEG143 [65] *((byte*) print_char_cursor#44) ← (byte) print_char::ch#8 -- _deref_pbuz1=vbuz2 @@ -1552,6 +1555,7 @@ print_char: { rts } //SEG147 print_word +// Print a word as HEX print_word: { .label w = $c //SEG148 [69] (byte) print_byte::b#0 ← > (word) print_word::w#4 -- vbuz1=_hi_vwuz2 @@ -1582,6 +1586,7 @@ print_word: { rts } //SEG161 print_dword +// Print a dword as HEX print_dword: { .label dw = $24 //SEG162 [74] (word) print_word::w#0 ← > (dword) print_dword::dw#0 -- vwuz1=_hi_vduz2 @@ -1616,6 +1621,7 @@ print_dword: { rts } //SEG175 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = $e //SEG176 [80] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -1896,7 +1902,6 @@ main: { lda _33+1 sta dw2+1 //SEG25 [15] (dword) print_dword::dw#0 ← (dword) main::dw2#10 - // (dword) print_dword::dw#0 = (dword) main::dw2#10 // register copy zp ZP_DWORD:12 //SEG26 [16] call print_dword jsr print_dword //SEG27 [17] phi from main::@1 to main::@4 [phi:main::@1->main::@4] @@ -2121,6 +2126,7 @@ main: { jmp b1 } //SEG118 print_ln +// Print a newline print_ln: { //SEG119 [52] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -2153,6 +2159,7 @@ print_ln: { rts } //SEG126 print_byte +// Print a byte as HEX print_byte: { //SEG127 [57] (byte~) print_byte::$0 ← (byte) print_byte::b#6 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -2191,6 +2198,7 @@ print_byte: { rts } //SEG142 print_char +// Print a single char print_char: { //SEG143 [65] *((byte*) print_char_cursor#44) ← (byte) print_char::ch#8 -- _deref_pbuz1=vbuaa ldy #0 @@ -2207,6 +2215,7 @@ print_char: { rts } //SEG147 print_word +// Print a word as HEX print_word: { .label w = $a //SEG148 [69] (byte) print_byte::b#0 ← > (word) print_word::w#4 -- vbuxx=_hi_vwuz1 @@ -2237,6 +2246,7 @@ print_word: { rts } //SEG161 print_dword +// Print a dword as HEX print_dword: { .label dw = $c //SEG162 [74] (word) print_word::w#0 ← > (dword) print_dword::dw#0 -- vwuz1=_hi_vduz2 @@ -2271,6 +2281,7 @@ print_dword: { rts } //SEG175 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 6 //SEG176 [80] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -2634,7 +2645,6 @@ main: { lda _33+1 sta dw2+1 //SEG25 [15] (dword) print_dword::dw#0 ← (dword) main::dw2#10 - // (dword) print_dword::dw#0 = (dword) main::dw2#10 // register copy zp ZP_DWORD:12 //SEG26 [16] call print_dword jsr print_dword //SEG27 [17] phi from main::@1 to main::@4 [phi:main::@1->main::@4] @@ -2806,6 +2816,7 @@ main: { jmp b1 } //SEG118 print_ln +// Print a newline print_ln: { //SEG119 [52] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] //SEG120 [52] phi (byte*) print_line_cursor#9 = (byte*) print_line_cursor#19 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy @@ -2833,6 +2844,7 @@ print_ln: { rts } //SEG126 print_byte +// Print a byte as HEX print_byte: { //SEG127 [57] (byte~) print_byte::$0 ← (byte) print_byte::b#6 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -2865,6 +2877,7 @@ print_byte: { rts } //SEG142 print_char +// Print a single char print_char: { //SEG143 [65] *((byte*) print_char_cursor#44) ← (byte) print_char::ch#8 -- _deref_pbuz1=vbuaa ldy #0 @@ -2879,6 +2892,7 @@ print_char: { rts } //SEG147 print_word +// Print a word as HEX print_word: { .label w = $a //SEG148 [69] (byte) print_byte::b#0 ← > (word) print_word::w#4 -- vbuxx=_hi_vwuz1 @@ -2903,6 +2917,7 @@ print_word: { rts } //SEG161 print_dword +// Print a dword as HEX print_dword: { .label dw = $c //SEG162 [74] (word) print_word::w#0 ← > (dword) print_dword::dw#0 -- vwuz1=_hi_vduz2 @@ -2931,6 +2946,7 @@ print_dword: { rts } //SEG175 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 6 //SEG176 [80] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] diff --git a/src/test/ref/test-multiply-16bit.asm b/src/test/ref/test-multiply-16bit.asm index fa6d6b19d..03cf08343 100644 --- a/src/test/ref/test-multiply-16bit.asm +++ b/src/test/ref/test-multiply-16bit.asm @@ -13,6 +13,7 @@ main: { jsr mul16s_compare rts } +// Perform many possible word multiplications (slow and fast) and compare the results mul16s_compare: { .label a = 3 .label b = 5 @@ -124,6 +125,7 @@ mul16s_compare: { str: .text ".@" str1: .text "signed word multiply results match!@" } +// Print a newline print_ln: { b1: lda print_line_cursor @@ -143,6 +145,7 @@ print_ln: { !: rts } +// Print a zero-terminated string print_str: { .label str = 9 b1: @@ -229,6 +232,7 @@ mul16s_error: { str3: .text " / normal:@" str4: .text " / fast:@" } +// Print a signed dword as HEX print_sdword: { .label dw = $b lda dw+3 @@ -256,6 +260,7 @@ print_sdword: { jsr print_dword rts } +// Print a dword as HEX print_dword: { .label dw = $b lda dw+2 @@ -270,6 +275,7 @@ print_dword: { jsr print_word rts } +// Print a word as HEX print_word: { .label w = 3 lda w+1 @@ -280,6 +286,7 @@ print_word: { jsr print_byte rts } +// Print a byte as HEX print_byte: { txa lsr @@ -296,6 +303,7 @@ print_byte: { jsr print_char rts } +// Print a single char print_char: { ldy #0 sta (print_char_cursor),y @@ -305,6 +313,7 @@ print_char: { !: rts } +// Print a signed word as HEX print_sword: { .label w = 3 lda w+1 @@ -324,6 +333,8 @@ print_sword: { jsr print_word rts } +// Fast multiply two signed words to a signed double word result +// Fixes offsets introduced by using unsigned multiplication mulf16s: { .label _5 = 3 .label _6 = 9 @@ -390,6 +401,8 @@ mulf16s: { b2: rts } +// Fast multiply two unsigned words to a double word result +// Done in assembler to utilize fast addition A+X mulf16u: { .label memA = $f8 .label memB = $fa @@ -507,6 +520,8 @@ mulf16u: { sta return+3 rts } +// Multiply of two signed words to a signed double word +// Fixes offsets introduced by using unsigned multiplication mul16s: { .label _5 = 3 .label _6 = 9 @@ -573,6 +588,7 @@ mul16s: { b2: rts } +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label mb = $11 .label a = 9 @@ -624,6 +640,8 @@ mul16u: { rol mb+3 jmp b1 } +// Slow multiplication of signed words +// Perform a signed multiplication by repeated addition/subtraction muls16s: { .label m = $b .label j = 9 @@ -731,6 +749,7 @@ muls16s: { bne b5 jmp b4 } +// Perform many possible word multiplications (slow and fast) and compare the results mul16u_compare: { .label a = $15 .label b = $17 @@ -918,6 +937,8 @@ mul16u_error: { str3: .text " / normal:@" str4: .text " / fast:@" } +// Slow multiplication of unsigned words +// Calculate an unsigned multiplication by repeated addition muls16u: { .label return = $b .label m = $b @@ -970,6 +991,7 @@ muls16u: { b1: rts } +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label sqr1_hi = 5 .label sqr = 7 @@ -1076,6 +1098,7 @@ mulf_init: { sta mulf_sqr2_hi+$1ff rts } +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 3 lda #<$400 diff --git a/src/test/ref/test-multiply-16bit.log b/src/test/ref/test-multiply-16bit.log index 427bc5ae3..b7cea2bf1 100644 --- a/src/test/ref/test-multiply-16bit.log +++ b/src/test/ref/test-multiply-16bit.log @@ -4778,6 +4778,7 @@ main: { rts } //SEG25 mul16s_compare +// Perform many possible word multiplications (slow and fast) and compare the results mul16s_compare: { .label a = 3 .label b = 5 @@ -5141,6 +5142,7 @@ mul16s_compare: { str1: .text "signed word multiply results match!@" } //SEG123 print_ln +// Print a newline print_ln: { //SEG124 [60] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -5173,6 +5175,7 @@ print_ln: { rts } //SEG131 print_str +// Print a zero-terminated string print_str: { .label str = $b //SEG132 [65] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -5389,6 +5392,7 @@ mul16s_error: { str4: .text " / fast:@" } //SEG205 print_sdword +// Print a signed dword as HEX print_sdword: { .label dw = $d //SEG206 [95] if((signed dword) print_sdword::dw#4>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sdword::@1 -- vdsz1_ge_0_then_la1 @@ -5458,6 +5462,7 @@ print_sdword: { rts } //SEG226 print_dword +// Print a dword as HEX print_dword: { .label dw = $11 //SEG227 [104] (word) print_word::w#1 ← > (dword) print_dword::dw#4 -- vwuz1=_hi_vduz2 @@ -5492,6 +5497,7 @@ print_dword: { rts } //SEG240 print_word +// Print a word as HEX print_word: { .label w = $15 //SEG241 [110] (byte) print_byte::b#0 ← > (word) print_word::w#5 -- vbuz1=_hi_vwuz2 @@ -5522,6 +5528,7 @@ print_word: { rts } //SEG254 print_byte +// Print a byte as HEX print_byte: { .label _0 = $8e .label _2 = $8f @@ -5567,6 +5574,7 @@ print_byte: { rts } //SEG270 print_char +// Print a single char print_char: { .label ch = $18 //SEG271 [124] *((byte*) print_char_cursor#84) ← (byte) print_char::ch#4 -- _deref_pbuz1=vbuz2 @@ -5585,6 +5593,7 @@ print_char: { rts } //SEG275 print_sword +// Print a signed word as HEX print_sword: { .label w = $1b //SEG276 [128] if((signed word) print_sword::w#3>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -5642,6 +5651,8 @@ print_sword: { rts } //SEG296 mulf16s +// Fast multiply two signed words to a signed double word result +// Fixes offsets introduced by using unsigned multiplication mulf16s: { .label _5 = $94 .label _6 = $96 @@ -5779,6 +5790,8 @@ mulf16s: { rts } //SEG327 mulf16u +// Fast multiply two unsigned words to a double word result +// Done in assembler to utilize fast addition A+X mulf16u: { .label memA = $f8 .label memB = $fa @@ -5907,6 +5920,8 @@ mulf16u: { rts } //SEG334 mul16s +// Multiply of two signed words to a signed double word +// Fixes offsets introduced by using unsigned multiplication mul16s: { .label _5 = $ac .label _6 = $ae @@ -6044,6 +6059,7 @@ mul16s: { rts } //SEG365 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label _1 = $bc .label mb = $31 @@ -6135,6 +6151,8 @@ mul16u: { jmp b1 } //SEG389 muls16s +// Slow multiplication of signed words +// Perform a signed multiplication by repeated addition/subtraction muls16s: { .label m = $37 .label j = $35 @@ -6296,6 +6314,7 @@ muls16s: { jmp b4_from_b5 } //SEG420 mul16u_compare +// Perform many possible word multiplications (slow and fast) and compare the results mul16u_compare: { .label a = $3e .label b = $40 @@ -6855,6 +6874,8 @@ mul16u_error: { str4: .text " / fast:@" } //SEG590 muls16u +// Slow multiplication of unsigned words +// Calculate an unsigned multiplication by repeated addition muls16u: { .label return = $46 .label m = $46 @@ -6939,6 +6960,7 @@ muls16u: { rts } //SEG609 mulf_init +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label _2 = $e9 .label _5 = $ea @@ -7150,6 +7172,7 @@ mulf_init: { jmp b4 } //SEG671 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = $58 //SEG672 [309] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -7796,6 +7819,7 @@ main: { rts } //SEG25 mul16s_compare +// Perform many possible word multiplications (slow and fast) and compare the results mul16s_compare: { .label a = 3 .label b = 5 @@ -7876,44 +7900,32 @@ mul16s_compare: { adc #>$ffd sta b+1 //SEG53 [19] (signed word) muls16s::a#0 ← (signed word) mul16s_compare::a#1 - // (signed word) muls16s::a#0 = (signed word) mul16s_compare::a#1 // register copy zp ZP_WORD:3 //SEG54 [20] (signed word) muls16s::b#0 ← (signed word) mul16s_compare::b#1 - // (signed word) muls16s::b#0 = (signed word) mul16s_compare::b#1 // register copy zp ZP_WORD:5 //SEG55 [21] call muls16s jsr muls16s //SEG56 [22] (signed dword) muls16s::return#2 ← (signed dword) muls16s::return#0 - // (signed dword) muls16s::return#2 = (signed dword) muls16s::return#0 // register copy zp ZP_DWORD:11 jmp b13 //SEG57 mul16s_compare::@13 b13: //SEG58 [23] (signed dword) mul16s_compare::ms#0 ← (signed dword) muls16s::return#2 - // (signed dword) mul16s_compare::ms#0 = (signed dword) muls16s::return#2 // register copy zp ZP_DWORD:11 //SEG59 [24] (signed word) mul16s::a#0 ← (signed word) mul16s_compare::a#1 - // (signed word) mul16s::a#0 = (signed word) mul16s_compare::a#1 // register copy zp ZP_WORD:3 //SEG60 [25] (signed word) mul16s::b#0 ← (signed word) mul16s_compare::b#1 - // (signed word) mul16s::b#0 = (signed word) mul16s_compare::b#1 // register copy zp ZP_WORD:5 //SEG61 [26] call mul16s jsr mul16s //SEG62 [27] (signed dword) mul16s::return#2 ← (signed dword) mul16s::return#0 - // (signed dword) mul16s::return#2 = (signed dword) mul16s::return#0 // register copy zp ZP_DWORD:25 jmp b14 //SEG63 mul16s_compare::@14 b14: //SEG64 [28] (signed dword) mul16s_compare::mn#0 ← (signed dword) mul16s::return#2 - // (signed dword) mul16s_compare::mn#0 = (signed dword) mul16s::return#2 // register copy zp ZP_DWORD:25 //SEG65 [29] (signed word) mulf16s::a#0 ← (signed word) mul16s_compare::a#1 - // (signed word) mulf16s::a#0 = (signed word) mul16s_compare::a#1 // register copy zp ZP_WORD:3 //SEG66 [30] (signed word) mulf16s::b#0 ← (signed word) mul16s_compare::b#1 - // (signed word) mulf16s::b#0 = (signed word) mul16s_compare::b#1 // register copy zp ZP_WORD:5 //SEG67 [31] call mulf16s jsr mulf16s //SEG68 [32] (signed dword) mulf16s::return#2 ← (signed dword) mulf16s::return#0 - // (signed dword) mulf16s::return#2 = (signed dword) mulf16s::return#0 // register copy zp ZP_DWORD:17 jmp b15 //SEG69 mul16s_compare::@15 b15: //SEG70 [33] (signed dword) mul16s_compare::mf#0 ← (signed dword) mulf16s::return#2 - // (signed dword) mul16s_compare::mf#0 = (signed dword) mulf16s::return#2 // register copy zp ZP_DWORD:17 //SEG71 [34] if((signed dword) mul16s_compare::ms#0==(signed dword) mul16s_compare::mf#0) goto mul16s_compare::@3 -- vdsz1_eq_vdsz2_then_la1 lda ms cmp mf @@ -7976,15 +7988,10 @@ mul16s_compare: { lda #2 sta BGCOL //SEG86 [41] (signed word) mul16s_error::a#0 ← (signed word) mul16s_compare::a#1 - // (signed word) mul16s_error::a#0 = (signed word) mul16s_compare::a#1 // register copy zp ZP_WORD:3 //SEG87 [42] (signed word) mul16s_error::b#0 ← (signed word) mul16s_compare::b#1 - // (signed word) mul16s_error::b#0 = (signed word) mul16s_compare::b#1 // register copy zp ZP_WORD:5 //SEG88 [43] (signed dword) mul16s_error::ms#0 ← (signed dword) mul16s_compare::ms#0 - // (signed dword) mul16s_error::ms#0 = (signed dword) mul16s_compare::ms#0 // register copy zp ZP_DWORD:11 //SEG89 [44] (signed dword) mul16s_error::mn#0 ← (signed dword) mul16s_compare::mn#0 - // (signed dword) mul16s_error::mn#0 = (signed dword) mul16s_compare::mn#0 // register copy zp ZP_DWORD:25 //SEG90 [45] (signed dword) mul16s_error::mf#0 ← (signed dword) mul16s_compare::mf#0 - // (signed dword) mul16s_error::mf#0 = (signed dword) mul16s_compare::mf#0 // register copy zp ZP_DWORD:17 //SEG91 [46] call mul16s_error //SEG92 [71] phi from mul16s_compare::@8 to mul16s_error [phi:mul16s_compare::@8->mul16s_error] mul16s_error_from_b8: @@ -8064,6 +8071,7 @@ mul16s_compare: { str1: .text "signed word multiply results match!@" } //SEG123 print_ln +// Print a newline print_ln: { //SEG124 [60] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -8096,6 +8104,7 @@ print_ln: { rts } //SEG131 print_str +// Print a zero-terminated string print_str: { .label str = 9 //SEG132 [65] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -8156,7 +8165,6 @@ mul16s_error: { //SEG148 mul16s_error::@1 b1: //SEG149 [73] (signed word) print_sword::w#1 ← (signed word) mul16s_error::a#0 - // (signed word) print_sword::w#1 = (signed word) mul16s_error::a#0 // register copy zp ZP_WORD:3 //SEG150 [74] call print_sword //SEG151 [127] phi from mul16s_error::@1 to print_sword [phi:mul16s_error::@1->print_sword] print_sword_from_b1: @@ -8209,7 +8217,6 @@ mul16s_error: { //SEG170 mul16s_error::@5 b5: //SEG171 [81] (signed dword) print_sdword::dw#1 ← (signed dword) mul16s_error::ms#0 - // (signed dword) print_sdword::dw#1 = (signed dword) mul16s_error::ms#0 // register copy zp ZP_DWORD:11 //SEG172 [82] call print_sdword //SEG173 [94] phi from mul16s_error::@5 to print_sdword [phi:mul16s_error::@5->print_sdword] print_sdword_from_b5: @@ -8302,6 +8309,7 @@ mul16s_error: { str4: .text " / fast:@" } //SEG205 print_sdword +// Print a signed dword as HEX print_sdword: { .label dw = $b //SEG206 [95] if((signed dword) print_sdword::dw#4>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sdword::@1 -- vdsz1_ge_0_then_la1 @@ -8362,6 +8370,7 @@ print_sdword: { rts } //SEG226 print_dword +// Print a dword as HEX print_dword: { .label dw = $b //SEG227 [104] (word) print_word::w#1 ← > (dword) print_dword::dw#4 -- vwuz1=_hi_vduz2 @@ -8396,6 +8405,7 @@ print_dword: { rts } //SEG240 print_word +// Print a word as HEX print_word: { .label w = 3 //SEG241 [110] (byte) print_byte::b#0 ← > (word) print_word::w#5 -- vbuxx=_hi_vwuz1 @@ -8426,6 +8436,7 @@ print_word: { rts } //SEG254 print_byte +// Print a byte as HEX print_byte: { //SEG255 [116] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -8464,6 +8475,7 @@ print_byte: { rts } //SEG270 print_char +// Print a single char print_char: { //SEG271 [124] *((byte*) print_char_cursor#84) ← (byte) print_char::ch#4 -- _deref_pbuz1=vbuaa ldy #0 @@ -8480,6 +8492,7 @@ print_char: { rts } //SEG275 print_sword +// Print a signed word as HEX print_sword: { .label w = 3 //SEG276 [128] if((signed word) print_sword::w#3>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -8519,7 +8532,6 @@ print_sword: { //SEG288 print_sword::@1 b1: //SEG289 [133] (word~) print_word::w#11 ← (word)(signed word) print_sword::w#4 - // (word~) print_word::w#11 = (word)(signed word) print_sword::w#4 // register copy zp ZP_WORD:3 //SEG290 [134] call print_word //SEG291 [109] phi from print_sword::@1 to print_word [phi:print_sword::@1->print_word] print_word_from_b1: @@ -8533,6 +8545,8 @@ print_sword: { rts } //SEG296 mulf16s +// Fast multiply two signed words to a signed double word result +// Fixes offsets introduced by using unsigned multiplication mulf16s: { .label _5 = 3 .label _6 = 9 @@ -8561,12 +8575,10 @@ mulf16s: { //SEG302 [155] phi (word) mulf16u::a#2 = (word~) mulf16u::a#4 [phi:mulf16s->mulf16u#1] -- register_copy jsr mulf16u //SEG303 [139] (dword) mulf16u::return#2 ← (dword) mulf16u::return#0 - // (dword) mulf16u::return#2 = (dword) mulf16u::return#0 // register copy zp ZP_DWORD:17 jmp b6 //SEG304 mulf16s::@6 b6: //SEG305 [140] (dword) mulf16s::m#0 ← (dword) mulf16u::return#2 - // (dword) mulf16s::m#0 = (dword) mulf16u::return#2 // register copy zp ZP_DWORD:17 //SEG306 [141] if((signed word) mulf16s::a#0>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mulf16s::@1 -- vwsz1_ge_0_then_la1 lda a+1 bpl b1_from_b6 @@ -8647,6 +8659,8 @@ mulf16s: { rts } //SEG327 mulf16u +// Fast multiply two unsigned words to a double word result +// Done in assembler to utilize fast addition A+X mulf16u: { .label memA = $f8 .label memB = $fa @@ -8773,6 +8787,8 @@ mulf16u: { rts } //SEG334 mul16s +// Multiply of two signed words to a signed double word +// Fixes offsets introduced by using unsigned multiplication mul16s: { .label _5 = 3 .label _6 = 9 @@ -8801,12 +8817,10 @@ mul16s: { //SEG340 [180] phi (word) mul16u::b#2 = (word~) mul16u::b#3 [phi:mul16s->mul16u#1] -- register_copy jsr mul16u //SEG341 [164] (dword) mul16u::return#2 ← (dword) mul16u::res#2 - // (dword) mul16u::return#2 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:25 jmp b6 //SEG342 mul16s::@6 b6: //SEG343 [165] (dword) mul16s::m#0 ← (dword) mul16u::return#2 - // (dword) mul16s::m#0 = (dword) mul16u::return#2 // register copy zp ZP_DWORD:25 //SEG344 [166] if((signed word) mul16s::a#0>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mul16s::@1 -- vwsz1_ge_0_then_la1 lda a+1 bpl b1_from_b6 @@ -8887,6 +8901,7 @@ mul16s: { rts } //SEG365 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label mb = $11 .label a = 9 @@ -8974,6 +8989,8 @@ mul16u: { jmp b1 } //SEG389 muls16s +// Slow multiplication of signed words +// Perform a signed multiplication by repeated addition/subtraction muls16s: { .label m = $b .label j = 9 @@ -9134,6 +9151,7 @@ muls16s: { jmp b4_from_b5 } //SEG420 mul16u_compare +// Perform many possible word multiplications (slow and fast) and compare the results mul16u_compare: { .label a = $15 .label b = $17 @@ -9213,25 +9231,20 @@ mul16u_compare: { adc #>$ffd sta b+1 //SEG447 [209] (word) muls16u::a#0 ← (word) mul16u_compare::a#1 - // (word) muls16u::a#0 = (word) mul16u_compare::a#1 // register copy zp ZP_WORD:21 //SEG448 [210] (word) muls16u::b#0 ← (word) mul16u_compare::b#1 - // (word) muls16u::b#0 = (word) mul16u_compare::b#1 // register copy zp ZP_WORD:23 //SEG449 [211] call muls16u jsr muls16u //SEG450 [212] (dword) muls16u::return#2 ← (dword) muls16u::return#0 - // (dword) muls16u::return#2 = (dword) muls16u::return#0 // register copy zp ZP_DWORD:11 jmp b13 //SEG451 mul16u_compare::@13 b13: //SEG452 [213] (dword) mul16u_compare::ms#0 ← (dword) muls16u::return#2 - // (dword) mul16u_compare::ms#0 = (dword) muls16u::return#2 // register copy zp ZP_DWORD:11 //SEG453 [214] (word) mul16u::a#2 ← (word) mul16u_compare::a#1 -- vwuz1=vwuz2 lda a sta mul16u.a lda a+1 sta mul16u.a+1 //SEG454 [215] (word) mul16u::b#1 ← (word) mul16u_compare::b#1 - // (word) mul16u::b#1 = (word) mul16u_compare::b#1 // register copy zp ZP_WORD:23 //SEG455 [216] call mul16u //SEG456 [180] phi from mul16u_compare::@13 to mul16u [phi:mul16u_compare::@13->mul16u] mul16u_from_b13: @@ -9239,16 +9252,12 @@ mul16u_compare: { //SEG458 [180] phi (word) mul16u::b#2 = (word) mul16u::b#1 [phi:mul16u_compare::@13->mul16u#1] -- register_copy jsr mul16u //SEG459 [217] (dword) mul16u::return#3 ← (dword) mul16u::res#2 - // (dword) mul16u::return#3 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:25 jmp b14 //SEG460 mul16u_compare::@14 b14: //SEG461 [218] (dword) mul16u_compare::mn#0 ← (dword) mul16u::return#3 - // (dword) mul16u_compare::mn#0 = (dword) mul16u::return#3 // register copy zp ZP_DWORD:25 //SEG462 [219] (word) mulf16u::a#1 ← (word) mul16u_compare::a#1 - // (word) mulf16u::a#1 = (word) mul16u_compare::a#1 // register copy zp ZP_WORD:21 //SEG463 [220] (word) mulf16u::b#1 ← (word) mul16u_compare::b#1 - // (word) mulf16u::b#1 = (word) mul16u_compare::b#1 // register copy zp ZP_WORD:23 //SEG464 [221] call mulf16u //SEG465 [155] phi from mul16u_compare::@14 to mulf16u [phi:mul16u_compare::@14->mulf16u] mulf16u_from_b14: @@ -9256,12 +9265,10 @@ mul16u_compare: { //SEG467 [155] phi (word) mulf16u::a#2 = (word) mulf16u::a#1 [phi:mul16u_compare::@14->mulf16u#1] -- register_copy jsr mulf16u //SEG468 [222] (dword) mulf16u::return#3 ← (dword) mulf16u::return#0 - // (dword) mulf16u::return#3 = (dword) mulf16u::return#0 // register copy zp ZP_DWORD:17 jmp b15 //SEG469 mul16u_compare::@15 b15: //SEG470 [223] (dword) mul16u_compare::mf#0 ← (dword) mulf16u::return#3 - // (dword) mul16u_compare::mf#0 = (dword) mulf16u::return#3 // register copy zp ZP_DWORD:17 //SEG471 [224] if((dword) mul16u_compare::ms#0==(dword) mul16u_compare::mf#0) goto mul16u_compare::@3 -- vduz1_eq_vduz2_then_la1 lda ms cmp mf @@ -9329,13 +9336,9 @@ mul16u_compare: { lda a+1 sta mul16u_error.a+1 //SEG487 [232] (word) mul16u_error::b#0 ← (word) mul16u_compare::b#1 - // (word) mul16u_error::b#0 = (word) mul16u_compare::b#1 // register copy zp ZP_WORD:23 //SEG488 [233] (dword) mul16u_error::ms#0 ← (dword) mul16u_compare::ms#0 - // (dword) mul16u_error::ms#0 = (dword) mul16u_compare::ms#0 // register copy zp ZP_DWORD:11 //SEG489 [234] (dword) mul16u_error::mn#0 ← (dword) mul16u_compare::mn#0 - // (dword) mul16u_error::mn#0 = (dword) mul16u_compare::mn#0 // register copy zp ZP_DWORD:25 //SEG490 [235] (dword) mul16u_error::mf#0 ← (dword) mul16u_compare::mf#0 - // (dword) mul16u_error::mf#0 = (dword) mul16u_compare::mf#0 // register copy zp ZP_DWORD:17 //SEG491 [236] call mul16u_error //SEG492 [249] phi from mul16u_compare::@8 to mul16u_error [phi:mul16u_compare::@8->mul16u_error] mul16u_error_from_b8: @@ -9439,7 +9442,6 @@ mul16u_error: { //SEG528 mul16u_error::@1 b1: //SEG529 [251] (word) print_word::w#3 ← (word) mul16u_error::a#0 - // (word) print_word::w#3 = (word) mul16u_error::a#0 // register copy zp ZP_WORD:3 //SEG530 [252] call print_word //SEG531 [109] phi from mul16u_error::@1 to print_word [phi:mul16u_error::@1->print_word] print_word_from_b1: @@ -9494,7 +9496,6 @@ mul16u_error: { //SEG552 mul16u_error::@5 b5: //SEG553 [259] (dword) print_dword::dw#1 ← (dword) mul16u_error::ms#0 - // (dword) print_dword::dw#1 = (dword) mul16u_error::ms#0 // register copy zp ZP_DWORD:11 //SEG554 [260] call print_dword //SEG555 [103] phi from mul16u_error::@5 to print_dword [phi:mul16u_error::@5->print_dword] print_dword_from_b5: @@ -9594,6 +9595,8 @@ mul16u_error: { str4: .text " / fast:@" } //SEG590 muls16u +// Slow multiplication of unsigned words +// Calculate an unsigned multiplication by repeated addition muls16u: { .label return = $b .label m = $b @@ -9677,6 +9680,7 @@ muls16u: { rts } //SEG609 mulf_init +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label sqr1_hi = 5 .label sqr = 7 @@ -9872,6 +9876,7 @@ mulf_init: { jmp b4 } //SEG671 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 3 //SEG672 [309] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -10109,10 +10114,12 @@ Removing instruction b1_from_print_ln: Removing instruction b1_from_b1: Removing instruction b1_from_print_str: Removing instruction b1_from_b2: +Removing instruction print_sword_from_b1: Removing instruction b2_from_b1: Removing instruction print_str_from_b2: Removing instruction b4_from_b3: Removing instruction print_str_from_b4: +Removing instruction print_sdword_from_b5: Removing instruction b6_from_b5: Removing instruction print_str_from_b6: Removing instruction b8_from_b7: @@ -10128,6 +10135,7 @@ Removing instruction b2_from_print_sword: Removing instruction print_char_from_b2: Removing instruction b1_from_print_sword: Removing instruction b1_from_b4: +Removing instruction print_word_from_b1: Removing instruction b1_from_b3: Removing instruction b1_from_b6: Removing instruction b2_from_b1: @@ -10147,6 +10155,7 @@ Removing instruction b5_from_b5: Removing instruction b1_from_b10: Removing instruction print_str_from_b1: Removing instruction b2_from_b5: +Removing instruction mulf16u_from_b14: Removing instruction b6_from_b15: Removing instruction b3_from_b6: Removing instruction b11_from_b10: @@ -10155,10 +10164,12 @@ Removing instruction b18_from_b17: Removing instruction print_ln_from_b18: Removing instruction b22_from_b3: Removing instruction b4_from_b22: +Removing instruction print_word_from_b1: Removing instruction b2_from_b1: Removing instruction print_str_from_b2: Removing instruction b4_from_b3: Removing instruction print_str_from_b4: +Removing instruction print_dword_from_b5: Removing instruction b6_from_b5: Removing instruction print_str_from_b6: Removing instruction b8_from_b7: @@ -10199,13 +10210,11 @@ Removing instruction breturn: Removing instruction breturn: Removing instruction print_str_from_mul16s_error: Removing instruction b1: -Removing instruction print_sword_from_b1: Removing instruction b2: Removing instruction b3: Removing instruction print_sword_from_b3: Removing instruction b4: Removing instruction b5: -Removing instruction print_sdword_from_b5: Removing instruction b6: Removing instruction b7: Removing instruction print_sdword_from_b7: @@ -10232,7 +10241,6 @@ Removing instruction breturn: Removing instruction breturn: Removing instruction b2: Removing instruction b4: -Removing instruction print_word_from_b1: Removing instruction breturn: Removing instruction mulf16u_from_mulf16s: Removing instruction b6: @@ -10254,7 +10262,6 @@ Removing instruction b2_from_b1: Removing instruction b13: Removing instruction mul16u_from_b13: Removing instruction b14: -Removing instruction mulf16u_from_b14: Removing instruction b15: Removing instruction b6: Removing instruction b4_from_b3: @@ -10267,13 +10274,11 @@ Removing instruction print_str_from_b17: Removing instruction b18: Removing instruction print_str_from_mul16u_error: Removing instruction b1: -Removing instruction print_word_from_b1: Removing instruction b2: Removing instruction b3: Removing instruction print_word_from_b3: Removing instruction b4: Removing instruction b5: -Removing instruction print_dword_from_b5: Removing instruction b6: Removing instruction b7: Removing instruction print_dword_from_b7: @@ -10332,8 +10337,8 @@ Removing unreachable instruction jmp b4 Removing unreachable instruction jmp b4 Removing unreachable instruction jmp b4 Succesful ASM optimization Pass5UnreachableCodeElimination -Fixing long branch [108] bne b1 to beq -Fixing long branch [830] bne b1 to beq +Fixing long branch [109] bne b1 to beq +Fixing long branch [849] bne b1 to beq FINAL SYMBOL TABLE (label) @40 @@ -10845,6 +10850,7 @@ main: { rts } //SEG25 mul16s_compare +// Perform many possible word multiplications (slow and fast) and compare the results mul16s_compare: { .label a = 3 .label b = 5 @@ -10916,38 +10922,26 @@ mul16s_compare: { adc #>$ffd sta b+1 //SEG53 [19] (signed word) muls16s::a#0 ← (signed word) mul16s_compare::a#1 - // (signed word) muls16s::a#0 = (signed word) mul16s_compare::a#1 // register copy zp ZP_WORD:3 //SEG54 [20] (signed word) muls16s::b#0 ← (signed word) mul16s_compare::b#1 - // (signed word) muls16s::b#0 = (signed word) mul16s_compare::b#1 // register copy zp ZP_WORD:5 //SEG55 [21] call muls16s jsr muls16s //SEG56 [22] (signed dword) muls16s::return#2 ← (signed dword) muls16s::return#0 - // (signed dword) muls16s::return#2 = (signed dword) muls16s::return#0 // register copy zp ZP_DWORD:11 //SEG57 mul16s_compare::@13 //SEG58 [23] (signed dword) mul16s_compare::ms#0 ← (signed dword) muls16s::return#2 - // (signed dword) mul16s_compare::ms#0 = (signed dword) muls16s::return#2 // register copy zp ZP_DWORD:11 //SEG59 [24] (signed word) mul16s::a#0 ← (signed word) mul16s_compare::a#1 - // (signed word) mul16s::a#0 = (signed word) mul16s_compare::a#1 // register copy zp ZP_WORD:3 //SEG60 [25] (signed word) mul16s::b#0 ← (signed word) mul16s_compare::b#1 - // (signed word) mul16s::b#0 = (signed word) mul16s_compare::b#1 // register copy zp ZP_WORD:5 //SEG61 [26] call mul16s jsr mul16s //SEG62 [27] (signed dword) mul16s::return#2 ← (signed dword) mul16s::return#0 - // (signed dword) mul16s::return#2 = (signed dword) mul16s::return#0 // register copy zp ZP_DWORD:25 //SEG63 mul16s_compare::@14 //SEG64 [28] (signed dword) mul16s_compare::mn#0 ← (signed dword) mul16s::return#2 - // (signed dword) mul16s_compare::mn#0 = (signed dword) mul16s::return#2 // register copy zp ZP_DWORD:25 //SEG65 [29] (signed word) mulf16s::a#0 ← (signed word) mul16s_compare::a#1 - // (signed word) mulf16s::a#0 = (signed word) mul16s_compare::a#1 // register copy zp ZP_WORD:3 //SEG66 [30] (signed word) mulf16s::b#0 ← (signed word) mul16s_compare::b#1 - // (signed word) mulf16s::b#0 = (signed word) mul16s_compare::b#1 // register copy zp ZP_WORD:5 //SEG67 [31] call mulf16s jsr mulf16s //SEG68 [32] (signed dword) mulf16s::return#2 ← (signed dword) mulf16s::return#0 - // (signed dword) mulf16s::return#2 = (signed dword) mulf16s::return#0 // register copy zp ZP_DWORD:17 //SEG69 mul16s_compare::@15 //SEG70 [33] (signed dword) mul16s_compare::mf#0 ← (signed dword) mulf16s::return#2 - // (signed dword) mul16s_compare::mf#0 = (signed dword) mulf16s::return#2 // register copy zp ZP_DWORD:17 //SEG71 [34] if((signed dword) mul16s_compare::ms#0==(signed dword) mul16s_compare::mf#0) goto mul16s_compare::@3 -- vdsz1_eq_vdsz2_then_la1 lda ms cmp mf @@ -11001,15 +10995,10 @@ mul16s_compare: { lda #2 sta BGCOL //SEG86 [41] (signed word) mul16s_error::a#0 ← (signed word) mul16s_compare::a#1 - // (signed word) mul16s_error::a#0 = (signed word) mul16s_compare::a#1 // register copy zp ZP_WORD:3 //SEG87 [42] (signed word) mul16s_error::b#0 ← (signed word) mul16s_compare::b#1 - // (signed word) mul16s_error::b#0 = (signed word) mul16s_compare::b#1 // register copy zp ZP_WORD:5 //SEG88 [43] (signed dword) mul16s_error::ms#0 ← (signed dword) mul16s_compare::ms#0 - // (signed dword) mul16s_error::ms#0 = (signed dword) mul16s_compare::ms#0 // register copy zp ZP_DWORD:11 //SEG89 [44] (signed dword) mul16s_error::mn#0 ← (signed dword) mul16s_compare::mn#0 - // (signed dword) mul16s_error::mn#0 = (signed dword) mul16s_compare::mn#0 // register copy zp ZP_DWORD:25 //SEG90 [45] (signed dword) mul16s_error::mf#0 ← (signed dword) mul16s_compare::mf#0 - // (signed dword) mul16s_error::mf#0 = (signed dword) mul16s_compare::mf#0 // register copy zp ZP_DWORD:17 //SEG91 [46] call mul16s_error //SEG92 [71] phi from mul16s_compare::@8 to mul16s_error [phi:mul16s_compare::@8->mul16s_error] jsr mul16s_error @@ -11071,6 +11060,7 @@ mul16s_compare: { str1: .text "signed word multiply results match!@" } //SEG123 print_ln +// Print a newline print_ln: { //SEG124 [60] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] //SEG125 [60] phi (byte*) print_line_cursor#22 = (byte*) print_line_cursor#43 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy @@ -11098,6 +11088,7 @@ print_ln: { rts } //SEG131 print_str +// Print a zero-terminated string print_str: { .label str = 9 //SEG132 [65] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -11149,7 +11140,6 @@ mul16s_error: { jsr print_str //SEG148 mul16s_error::@1 //SEG149 [73] (signed word) print_sword::w#1 ← (signed word) mul16s_error::a#0 - // (signed word) print_sword::w#1 = (signed word) mul16s_error::a#0 // register copy zp ZP_WORD:3 //SEG150 [74] call print_sword //SEG151 [127] phi from mul16s_error::@1 to print_sword [phi:mul16s_error::@1->print_sword] //SEG152 [127] phi (signed word) print_sword::w#3 = (signed word) print_sword::w#1 [phi:mul16s_error::@1->print_sword#0] -- register_copy @@ -11188,7 +11178,6 @@ mul16s_error: { jsr print_str //SEG170 mul16s_error::@5 //SEG171 [81] (signed dword) print_sdword::dw#1 ← (signed dword) mul16s_error::ms#0 - // (signed dword) print_sdword::dw#1 = (signed dword) mul16s_error::ms#0 // register copy zp ZP_DWORD:11 //SEG172 [82] call print_sdword //SEG173 [94] phi from mul16s_error::@5 to print_sdword [phi:mul16s_error::@5->print_sdword] //SEG174 [94] phi (signed dword) print_sdword::dw#4 = (signed dword) print_sdword::dw#1 [phi:mul16s_error::@5->print_sdword#0] -- register_copy @@ -11260,6 +11249,7 @@ mul16s_error: { str4: .text " / fast:@" } //SEG205 print_sdword +// Print a signed dword as HEX print_sdword: { .label dw = $b //SEG206 [95] if((signed dword) print_sdword::dw#4>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sdword::@1 -- vdsz1_ge_0_then_la1 @@ -11308,6 +11298,7 @@ print_sdword: { rts } //SEG226 print_dword +// Print a dword as HEX print_dword: { .label dw = $b //SEG227 [104] (word) print_word::w#1 ← > (dword) print_dword::dw#4 -- vwuz1=_hi_vduz2 @@ -11336,6 +11327,7 @@ print_dword: { rts } //SEG240 print_word +// Print a word as HEX print_word: { .label w = 3 //SEG241 [110] (byte) print_byte::b#0 ← > (word) print_word::w#5 -- vbuxx=_hi_vwuz1 @@ -11360,6 +11352,7 @@ print_word: { rts } //SEG254 print_byte +// Print a byte as HEX print_byte: { //SEG255 [116] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -11392,6 +11385,7 @@ print_byte: { rts } //SEG270 print_char +// Print a single char print_char: { //SEG271 [124] *((byte*) print_char_cursor#84) ← (byte) print_char::ch#4 -- _deref_pbuz1=vbuaa ldy #0 @@ -11406,6 +11400,7 @@ print_char: { rts } //SEG275 print_sword +// Print a signed word as HEX print_sword: { .label w = 3 //SEG276 [128] if((signed word) print_sword::w#3>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -11436,7 +11431,6 @@ print_sword: { //SEG288 print_sword::@1 b1: //SEG289 [133] (word~) print_word::w#11 ← (word)(signed word) print_sword::w#4 - // (word~) print_word::w#11 = (word)(signed word) print_sword::w#4 // register copy zp ZP_WORD:3 //SEG290 [134] call print_word //SEG291 [109] phi from print_sword::@1 to print_word [phi:print_sword::@1->print_word] //SEG292 [109] phi (byte*) print_char_cursor#132 = (byte*) print_char_cursor#130 [phi:print_sword::@1->print_word#0] -- register_copy @@ -11447,6 +11441,8 @@ print_sword: { rts } //SEG296 mulf16s +// Fast multiply two signed words to a signed double word result +// Fixes offsets introduced by using unsigned multiplication mulf16s: { .label _5 = 3 .label _6 = 9 @@ -11474,10 +11470,8 @@ mulf16s: { //SEG302 [155] phi (word) mulf16u::a#2 = (word~) mulf16u::a#4 [phi:mulf16s->mulf16u#1] -- register_copy jsr mulf16u //SEG303 [139] (dword) mulf16u::return#2 ← (dword) mulf16u::return#0 - // (dword) mulf16u::return#2 = (dword) mulf16u::return#0 // register copy zp ZP_DWORD:17 //SEG304 mulf16s::@6 //SEG305 [140] (dword) mulf16s::m#0 ← (dword) mulf16u::return#2 - // (dword) mulf16s::m#0 = (dword) mulf16u::return#2 // register copy zp ZP_DWORD:17 //SEG306 [141] if((signed word) mulf16s::a#0>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mulf16s::@1 -- vwsz1_ge_0_then_la1 lda a+1 bpl b1 @@ -11546,6 +11540,8 @@ mulf16s: { rts } //SEG327 mulf16u +// Fast multiply two unsigned words to a double word result +// Done in assembler to utilize fast addition A+X mulf16u: { .label memA = $f8 .label memB = $fa @@ -11670,6 +11666,8 @@ mulf16u: { rts } //SEG334 mul16s +// Multiply of two signed words to a signed double word +// Fixes offsets introduced by using unsigned multiplication mul16s: { .label _5 = 3 .label _6 = 9 @@ -11697,10 +11695,8 @@ mul16s: { //SEG340 [180] phi (word) mul16u::b#2 = (word~) mul16u::b#3 [phi:mul16s->mul16u#1] -- register_copy jsr mul16u //SEG341 [164] (dword) mul16u::return#2 ← (dword) mul16u::res#2 - // (dword) mul16u::return#2 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:25 //SEG342 mul16s::@6 //SEG343 [165] (dword) mul16s::m#0 ← (dword) mul16u::return#2 - // (dword) mul16s::m#0 = (dword) mul16u::return#2 // register copy zp ZP_DWORD:25 //SEG344 [166] if((signed word) mul16s::a#0>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mul16s::@1 -- vwsz1_ge_0_then_la1 lda a+1 bpl b1 @@ -11769,6 +11765,7 @@ mul16s: { rts } //SEG365 mul16u +// Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word mul16u: { .label mb = $11 .label a = 9 @@ -11844,6 +11841,8 @@ mul16u: { jmp b1 } //SEG389 muls16s +// Slow multiplication of signed words +// Perform a signed multiplication by repeated addition/subtraction muls16s: { .label m = $b .label j = 9 @@ -11982,6 +11981,7 @@ muls16s: { jmp b4 } //SEG420 mul16u_compare +// Perform many possible word multiplications (slow and fast) and compare the results mul16u_compare: { .label a = $15 .label b = $17 @@ -12048,47 +12048,36 @@ mul16u_compare: { adc #>$ffd sta b+1 //SEG447 [209] (word) muls16u::a#0 ← (word) mul16u_compare::a#1 - // (word) muls16u::a#0 = (word) mul16u_compare::a#1 // register copy zp ZP_WORD:21 //SEG448 [210] (word) muls16u::b#0 ← (word) mul16u_compare::b#1 - // (word) muls16u::b#0 = (word) mul16u_compare::b#1 // register copy zp ZP_WORD:23 //SEG449 [211] call muls16u jsr muls16u //SEG450 [212] (dword) muls16u::return#2 ← (dword) muls16u::return#0 - // (dword) muls16u::return#2 = (dword) muls16u::return#0 // register copy zp ZP_DWORD:11 //SEG451 mul16u_compare::@13 //SEG452 [213] (dword) mul16u_compare::ms#0 ← (dword) muls16u::return#2 - // (dword) mul16u_compare::ms#0 = (dword) muls16u::return#2 // register copy zp ZP_DWORD:11 //SEG453 [214] (word) mul16u::a#2 ← (word) mul16u_compare::a#1 -- vwuz1=vwuz2 lda a sta mul16u.a lda a+1 sta mul16u.a+1 //SEG454 [215] (word) mul16u::b#1 ← (word) mul16u_compare::b#1 - // (word) mul16u::b#1 = (word) mul16u_compare::b#1 // register copy zp ZP_WORD:23 //SEG455 [216] call mul16u //SEG456 [180] phi from mul16u_compare::@13 to mul16u [phi:mul16u_compare::@13->mul16u] //SEG457 [180] phi (word) mul16u::a#6 = (word) mul16u::a#2 [phi:mul16u_compare::@13->mul16u#0] -- register_copy //SEG458 [180] phi (word) mul16u::b#2 = (word) mul16u::b#1 [phi:mul16u_compare::@13->mul16u#1] -- register_copy jsr mul16u //SEG459 [217] (dword) mul16u::return#3 ← (dword) mul16u::res#2 - // (dword) mul16u::return#3 = (dword) mul16u::res#2 // register copy zp ZP_DWORD:25 //SEG460 mul16u_compare::@14 //SEG461 [218] (dword) mul16u_compare::mn#0 ← (dword) mul16u::return#3 - // (dword) mul16u_compare::mn#0 = (dword) mul16u::return#3 // register copy zp ZP_DWORD:25 //SEG462 [219] (word) mulf16u::a#1 ← (word) mul16u_compare::a#1 - // (word) mulf16u::a#1 = (word) mul16u_compare::a#1 // register copy zp ZP_WORD:21 //SEG463 [220] (word) mulf16u::b#1 ← (word) mul16u_compare::b#1 - // (word) mulf16u::b#1 = (word) mul16u_compare::b#1 // register copy zp ZP_WORD:23 //SEG464 [221] call mulf16u //SEG465 [155] phi from mul16u_compare::@14 to mulf16u [phi:mul16u_compare::@14->mulf16u] //SEG466 [155] phi (word) mulf16u::b#2 = (word) mulf16u::b#1 [phi:mul16u_compare::@14->mulf16u#0] -- register_copy //SEG467 [155] phi (word) mulf16u::a#2 = (word) mulf16u::a#1 [phi:mul16u_compare::@14->mulf16u#1] -- register_copy jsr mulf16u //SEG468 [222] (dword) mulf16u::return#3 ← (dword) mulf16u::return#0 - // (dword) mulf16u::return#3 = (dword) mulf16u::return#0 // register copy zp ZP_DWORD:17 //SEG469 mul16u_compare::@15 //SEG470 [223] (dword) mul16u_compare::mf#0 ← (dword) mulf16u::return#3 - // (dword) mul16u_compare::mf#0 = (dword) mulf16u::return#3 // register copy zp ZP_DWORD:17 //SEG471 [224] if((dword) mul16u_compare::ms#0==(dword) mul16u_compare::mf#0) goto mul16u_compare::@3 -- vduz1_eq_vduz2_then_la1 lda ms cmp mf @@ -12147,13 +12136,9 @@ mul16u_compare: { lda a+1 sta mul16u_error.a+1 //SEG487 [232] (word) mul16u_error::b#0 ← (word) mul16u_compare::b#1 - // (word) mul16u_error::b#0 = (word) mul16u_compare::b#1 // register copy zp ZP_WORD:23 //SEG488 [233] (dword) mul16u_error::ms#0 ← (dword) mul16u_compare::ms#0 - // (dword) mul16u_error::ms#0 = (dword) mul16u_compare::ms#0 // register copy zp ZP_DWORD:11 //SEG489 [234] (dword) mul16u_error::mn#0 ← (dword) mul16u_compare::mn#0 - // (dword) mul16u_error::mn#0 = (dword) mul16u_compare::mn#0 // register copy zp ZP_DWORD:25 //SEG490 [235] (dword) mul16u_error::mf#0 ← (dword) mul16u_compare::mf#0 - // (dword) mul16u_error::mf#0 = (dword) mul16u_compare::mf#0 // register copy zp ZP_DWORD:17 //SEG491 [236] call mul16u_error //SEG492 [249] phi from mul16u_compare::@8 to mul16u_error [phi:mul16u_compare::@8->mul16u_error] jsr mul16u_error @@ -12236,7 +12221,6 @@ mul16u_error: { jsr print_str //SEG528 mul16u_error::@1 //SEG529 [251] (word) print_word::w#3 ← (word) mul16u_error::a#0 - // (word) print_word::w#3 = (word) mul16u_error::a#0 // register copy zp ZP_WORD:3 //SEG530 [252] call print_word //SEG531 [109] phi from mul16u_error::@1 to print_word [phi:mul16u_error::@1->print_word] //SEG532 [109] phi (byte*) print_char_cursor#132 = (byte*) print_char_cursor#128 [phi:mul16u_error::@1->print_word#0] -- register_copy @@ -12277,7 +12261,6 @@ mul16u_error: { jsr print_str //SEG552 mul16u_error::@5 //SEG553 [259] (dword) print_dword::dw#1 ← (dword) mul16u_error::ms#0 - // (dword) print_dword::dw#1 = (dword) mul16u_error::ms#0 // register copy zp ZP_DWORD:11 //SEG554 [260] call print_dword //SEG555 [103] phi from mul16u_error::@5 to print_dword [phi:mul16u_error::@5->print_dword] //SEG556 [103] phi (byte*) print_char_cursor#133 = (byte*) print_char_cursor#128 [phi:mul16u_error::@5->print_dword#0] -- register_copy @@ -12356,6 +12339,8 @@ mul16u_error: { str4: .text " / fast:@" } //SEG590 muls16u +// Slow multiplication of unsigned words +// Calculate an unsigned multiplication by repeated addition muls16u: { .label return = $b .label m = $b @@ -12427,6 +12412,7 @@ muls16u: { rts } //SEG609 mulf_init +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label sqr1_hi = 5 .label sqr = 7 @@ -12595,6 +12581,7 @@ mulf_init: { //SEG670 [301] phi (byte) mulf_init::dir#3 = (byte) mulf_init::dir#2 [phi:mulf_init::@12->mulf_init::@4#0] -- register_copy } //SEG671 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 3 //SEG672 [309] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] diff --git a/src/test/ref/test-multiply-8bit.asm b/src/test/ref/test-multiply-8bit.asm index f99c95a91..015bec0a2 100644 --- a/src/test/ref/test-multiply-8bit.asm +++ b/src/test/ref/test-multiply-8bit.asm @@ -15,6 +15,7 @@ main: { jsr mul8s_compare rts } +// Perform all possible signed byte multiplications (slow and fast) and compare the results mul8s_compare: { .label ms = 8 .label mf = $e @@ -85,6 +86,7 @@ mul8s_compare: { jmp breturn str: .text "signed multiply results match!@" } +// Print a newline print_ln: { b1: lda print_line_cursor @@ -104,6 +106,7 @@ print_ln: { !: rts } +// Print a zero-terminated string print_str: { .label str = 6 b1: @@ -182,6 +185,7 @@ mul8s_error: { str3: .text " / normal:@" str4: .text " / fast:@" } +// Print a signed word as HEX print_sword: { .label w = 8 lda w+1 @@ -201,6 +205,7 @@ print_sword: { jsr print_word rts } +// Print a word as HEX print_word: { .label w = 8 lda w+1 @@ -211,6 +216,7 @@ print_word: { jsr print_byte rts } +// Print a byte as HEX print_byte: { txa lsr @@ -227,6 +233,7 @@ print_byte: { jsr print_char rts } +// Print a single char print_char: { ldy #0 sta (print_char_cursor),y @@ -236,6 +243,7 @@ print_char: { !: rts } +// Print a signed byte as HEX print_sbyte: { cpx #0 bmi b1 @@ -254,6 +262,8 @@ print_sbyte: { tax jmp b2 } +// Multiply of two signed bytes to a signed word +// Fixes offsets introduced by using unsigned multiplication mul8s: { .label m = $c .label a = 2 @@ -279,6 +289,8 @@ mul8s: { b2: rts } +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .label mb = 6 .label res = $c @@ -312,6 +324,7 @@ mul8u: { rol mb+1 jmp b1 } +// Fast multiply two signed bytes to a word result mulf8s: { .label return = $e jsr mulf8u_prepare @@ -319,6 +332,8 @@ mulf8s: { 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: { .label memA = $fd .label m = $e @@ -344,6 +359,8 @@ mulf8s_prepared: { 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: { .label resL = $fe .label memB = $ff @@ -366,6 +383,7 @@ mulf8u_prepared: { sta return+1 rts } +// Prepare for fast multiply with an unsigned byte to a word result mulf8u_prepare: { .label memA = $fd sta memA @@ -376,6 +394,8 @@ mulf8u_prepare: { sta mulf8u_prepared.sm4+1 rts } +// Slow multiplication of signed bytes +// Perform a signed multiplication by repeated addition/subtraction muls8s: { .label m = 8 .label return = 8 @@ -438,6 +458,7 @@ muls8s: { bne b5 jmp b4 } +// Perform all possible byte multiplications (slow and fast) and compare the results mul8u_compare: { .label ms = 8 .label mf = $e @@ -557,12 +578,15 @@ mul8u_error: { str3: .text " / normal:@" str4: .text " / fast:@" } +// Fast multiply two unsigned bytes to a word result mulf8u: { .label return = $e jsr mulf8u_prepare jsr mulf8u_prepared rts } +// Slow multiplication of unsigned bytes +// Calculate an unsigned multiplication by repeated addition muls8u: { .label return = 8 .label m = 8 @@ -593,6 +617,8 @@ muls8u: { b1: rts } +// Compare the ASM-based mul tables with the KC-based mul tables +// Red screen on failure - green on success mulf_tables_cmp: { .label asm_sqr = 8 .label kc_sqr = 4 @@ -677,6 +703,8 @@ mulf_tables_cmp: { str1: .text " / @" str2: .text "multiply tables match!@" } +// Initialize the multiplication tables using ASM code from +// http://codebase64.org/doku.php?id=base:seriously_fast_multiplication mulf_init_asm: { .label mem = $ff ldx #0 @@ -727,6 +755,7 @@ mulf_init_asm: { sta mem rts } +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label sqr1_hi = 6 .label sqr = 8 @@ -833,6 +862,7 @@ mulf_init: { sta mulf_sqr2_hi+$1ff rts } +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 4 lda #<$400 diff --git a/src/test/ref/test-multiply-8bit.log b/src/test/ref/test-multiply-8bit.log index 52ee12f6f..5d3f37254 100644 --- a/src/test/ref/test-multiply-8bit.log +++ b/src/test/ref/test-multiply-8bit.log @@ -5030,6 +5030,7 @@ main: { rts } //SEG33 mul8s_compare +// Perform all possible signed byte multiplications (slow and fast) and compare the results mul8s_compare: { .label ms = $40 .label mf = $46 @@ -5266,6 +5267,7 @@ mul8s_compare: { str: .text "signed multiply results match!@" } //SEG108 print_ln +// Print a newline print_ln: { //SEG109 [59] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -5298,6 +5300,7 @@ print_ln: { rts } //SEG116 print_str +// Print a zero-terminated string print_str: { .label str = 7 //SEG117 [64] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -5503,6 +5506,7 @@ mul8s_error: { str4: .text " / fast:@" } //SEG191 print_sword +// Print a signed word as HEX print_sword: { .label w = 9 //SEG192 [94] if((signed word) print_sword::w#4>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -5560,6 +5564,7 @@ print_sword: { rts } //SEG212 print_word +// Print a word as HEX print_word: { .label w = $b //SEG213 [103] (byte) print_byte::b#1 ← > (word) print_word::w#6 -- vbuz1=_hi_vwuz2 @@ -5590,6 +5595,7 @@ print_word: { rts } //SEG226 print_byte +// Print a byte as HEX print_byte: { .label _0 = $56 .label _2 = $57 @@ -5635,6 +5641,7 @@ print_byte: { rts } //SEG242 print_char +// Print a single char print_char: { .label ch = $e //SEG243 [117] *((byte*) print_char_cursor#84) ← (byte) print_char::ch#5 -- _deref_pbuz1=vbuz2 @@ -5653,6 +5660,7 @@ print_char: { rts } //SEG247 print_sbyte +// Print a signed byte as HEX print_sbyte: { .label b = $11 //SEG248 [121] if((signed byte) print_sbyte::b#3<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsz1_lt_0_then_la1 @@ -5717,6 +5725,8 @@ print_sbyte: { jmp b2_from_b5 } //SEG273 mul8s +// Multiply of two signed bytes to a signed word +// Fixes offsets introduced by using unsigned multiplication mul8s: { .label _5 = $5a .label _6 = $5b @@ -5816,6 +5826,8 @@ mul8s: { rts } //SEG303 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .label _1 = $60 .label mb = $18 @@ -5891,6 +5903,7 @@ mul8u: { jmp b1 } //SEG327 mulf8s +// Fast multiply two signed bytes to a word result mulf8s: { .label return = $64 .label a = $42 @@ -5935,6 +5948,8 @@ mulf8s: { rts } //SEG341 mulf8s_prepared +// 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: { .label memA = $fd .label _4 = $68 @@ -6030,6 +6045,8 @@ mulf8s_prepared: { rts } //SEG369 mulf8u_prepared +// 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: { .label resL = $fe .label memB = $ff @@ -6065,6 +6082,7 @@ mulf8u_prepared: { rts } //SEG375 mulf8u_prepare +// Prepare for fast multiply with an unsigned byte to a word result mulf8u_prepare: { .label memA = $fd .label a = $1d @@ -6085,6 +6103,8 @@ mulf8u_prepare: { rts } //SEG380 muls8s +// Slow multiplication of signed bytes +// Perform a signed multiplication by repeated addition/subtraction muls8s: { .label m = $1f .label j = $1e @@ -6204,6 +6224,7 @@ muls8s: { jmp b4_from_b5 } //SEG411 mul8u_compare +// Perform all possible byte multiplications (slow and fast) and compare the results mul8u_compare: { .label ms = $74 .label mf = $7a @@ -6606,6 +6627,7 @@ mul8u_error: { str4: .text " / fast:@" } //SEG556 mulf8u +// Fast multiply two unsigned bytes to a word result mulf8u: { .label return = $8a .label a = $76 @@ -6650,6 +6672,8 @@ mulf8u: { rts } //SEG571 muls8u +// Slow multiplication of unsigned bytes +// Calculate an unsigned multiplication by repeated addition muls8u: { .label return = $26 .label m = $26 @@ -6714,6 +6738,8 @@ muls8u: { rts } //SEG590 mulf_tables_cmp +// Compare the ASM-based mul tables with the KC-based mul tables +// Red screen on failure - green on success mulf_tables_cmp: { .label asm_sqr = $2a .label kc_sqr = $28 @@ -6889,6 +6915,8 @@ mulf_tables_cmp: { str2: .text "multiply tables match!@" } //SEG648 mulf_init_asm +// Initialize the multiplication tables using ASM code from +// http://codebase64.org/doku.php?id=base:seriously_fast_multiplication mulf_init_asm: { .label mem = $ff //SEG649 asm { ldx#$00 txa .byte$c9 lb1: tya adc#$00 ml1: stamula_sqr1_hi,x tay cmp#$40 txa ror ml9: adc#$00 staml9+1 inx ml0: stamula_sqr1_lo,x bnelb1 incml0+2 incml1+2 clc iny bnelb1 ldx#$00 ldy#$ff !: ldamula_sqr1_hi+1,x stamula_sqr2_hi+$100,x ldamula_sqr1_hi,x stamula_sqr2_hi,y ldamula_sqr1_lo+1,x stamula_sqr2_lo+$100,x ldamula_sqr1_lo,x stamula_sqr2_lo,y dey inx bne!- } @@ -6949,6 +6977,7 @@ mulf_init_asm: { rts } //SEG656 mulf_init +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label _2 = $8c .label _5 = $8d @@ -7160,6 +7189,7 @@ mulf_init: { jmp b4 } //SEG718 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = $3a //SEG719 [341] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -7794,6 +7824,7 @@ main: { rts } //SEG33 mul8s_compare +// Perform all possible signed byte multiplications (slow and fast) and compare the results mul8s_compare: { .label ms = 8 .label mf = $e @@ -7825,18 +7856,15 @@ mul8s_compare: { //SEG43 mul8s_compare::@2 b2: //SEG44 [20] (signed byte) muls8s::a#0 ← (signed byte) mul8s_compare::a#7 - // (signed byte) muls8s::a#0 = (signed byte) mul8s_compare::a#7 // register copy zp ZP_BYTE:2 //SEG45 [21] (signed byte) muls8s::b#0 ← (signed byte) mul8s_compare::b#10 -- vbsxx=vbsz1 ldx b //SEG46 [22] call muls8s jsr muls8s //SEG47 [23] (signed word) muls8s::return#2 ← (signed word) muls8s::return#0 - // (signed word) muls8s::return#2 = (signed word) muls8s::return#0 // register copy zp ZP_WORD:8 jmp b12 //SEG48 mul8s_compare::@12 b12: //SEG49 [24] (signed word) mul8s_compare::ms#0 ← (signed word) muls8s::return#2 - // (signed word) mul8s_compare::ms#0 = (signed word) muls8s::return#2 // register copy zp ZP_WORD:8 //SEG50 [25] (signed byte) mulf8s::a#0 ← (signed byte) mul8s_compare::a#7 -- vbsaa=vbsz1 lda a //SEG51 [26] (signed byte) mulf8s::b#0 ← (signed byte) mul8s_compare::b#10 -- vbsxx=vbsz1 @@ -7846,25 +7874,20 @@ mul8s_compare: { mulf8s_from_b12: jsr mulf8s //SEG54 [28] (signed word) mulf8s::return#2 ← (signed word) mulf8s::return#0 - // (signed word) mulf8s::return#2 = (signed word) mulf8s::return#0 // register copy zp ZP_WORD:14 jmp b13 //SEG55 mul8s_compare::@13 b13: //SEG56 [29] (signed word) mul8s_compare::mf#0 ← (signed word) mulf8s::return#2 - // (signed word) mul8s_compare::mf#0 = (signed word) mulf8s::return#2 // register copy zp ZP_WORD:14 //SEG57 [30] (signed byte) mul8s::a#0 ← (signed byte) mul8s_compare::a#7 - // (signed byte) mul8s::a#0 = (signed byte) mul8s_compare::a#7 // register copy zp ZP_BYTE:2 //SEG58 [31] (signed byte) mul8s::b#0 ← (signed byte) mul8s_compare::b#10 -- vbsyy=vbsz1 ldy b //SEG59 [32] call mul8s jsr mul8s //SEG60 [33] (signed word) mul8s::return#2 ← (signed word)(word) mul8s::m#4 - // (signed word) mul8s::return#2 = (signed word)(word) mul8s::m#4 // register copy zp ZP_WORD:12 jmp b14 //SEG61 mul8s_compare::@14 b14: //SEG62 [34] (signed word) mul8s_compare::mn#0 ← (signed word) mul8s::return#2 - // (signed word) mul8s_compare::mn#0 = (signed word) mul8s::return#2 // register copy zp ZP_WORD:12 //SEG63 [35] if((signed word) mul8s_compare::ms#0==(signed word) mul8s_compare::mf#0) goto mul8s_compare::@3 -- vwsz1_eq_vwsz2_then_la1 lda ms cmp mf @@ -7917,13 +7940,9 @@ mul8s_compare: { //SEG78 [42] (signed byte) mul8s_error::a#0 ← (signed byte) mul8s_compare::a#7 -- vbsxx=vbsz1 ldx a //SEG79 [43] (signed byte) mul8s_error::b#0 ← (signed byte) mul8s_compare::b#10 - // (signed byte) mul8s_error::b#0 = (signed byte) mul8s_compare::b#10 // register copy zp ZP_BYTE:3 //SEG80 [44] (signed word) mul8s_error::ms#0 ← (signed word) mul8s_compare::ms#0 - // (signed word) mul8s_error::ms#0 = (signed word) mul8s_compare::ms#0 // register copy zp ZP_WORD:8 //SEG81 [45] (signed word) mul8s_error::mn#0 ← (signed word) mul8s_compare::mn#0 - // (signed word) mul8s_error::mn#0 = (signed word) mul8s_compare::mn#0 // register copy zp ZP_WORD:12 //SEG82 [46] (signed word) mul8s_error::mf#0 ← (signed word) mul8s_compare::mf#0 - // (signed word) mul8s_error::mf#0 = (signed word) mul8s_compare::mf#0 // register copy zp ZP_WORD:14 //SEG83 [47] call mul8s_error jsr mul8s_error jmp breturn @@ -7990,6 +8009,7 @@ mul8s_compare: { str: .text "signed multiply results match!@" } //SEG108 print_ln +// Print a newline print_ln: { //SEG109 [59] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] b1_from_print_ln: @@ -8022,6 +8042,7 @@ print_ln: { rts } //SEG116 print_str +// Print a zero-terminated string print_str: { .label str = 6 //SEG117 [64] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -8086,7 +8107,6 @@ mul8s_error: { //SEG134 mul8s_error::@1 b1: //SEG135 [72] (signed byte) print_sbyte::b#1 ← (signed byte) mul8s_error::a#0 - // (signed byte) print_sbyte::b#1 = (signed byte) mul8s_error::a#0 // register copy reg byte x //SEG136 [73] call print_sbyte //SEG137 [120] phi from mul8s_error::@1 to print_sbyte [phi:mul8s_error::@1->print_sbyte] print_sbyte_from_b1: @@ -8136,7 +8156,6 @@ mul8s_error: { //SEG156 mul8s_error::@5 b5: //SEG157 [80] (signed word) print_sword::w#1 ← (signed word) mul8s_error::ms#0 - // (signed word) print_sword::w#1 = (signed word) mul8s_error::ms#0 // register copy zp ZP_WORD:8 //SEG158 [81] call print_sword //SEG159 [93] phi from mul8s_error::@5 to print_sword [phi:mul8s_error::@5->print_sword] print_sword_from_b5: @@ -8221,6 +8240,7 @@ mul8s_error: { str4: .text " / fast:@" } //SEG191 print_sword +// Print a signed word as HEX print_sword: { .label w = 8 //SEG192 [94] if((signed word) print_sword::w#4>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -8260,7 +8280,6 @@ print_sword: { //SEG204 print_sword::@1 b1: //SEG205 [99] (word~) print_word::w#13 ← (word)(signed word) print_sword::w#5 - // (word~) print_word::w#13 = (word)(signed word) print_sword::w#5 // register copy zp ZP_WORD:8 //SEG206 [100] call print_word //SEG207 [102] phi from print_sword::@1 to print_word [phi:print_sword::@1->print_word] print_word_from_b1: @@ -8274,6 +8293,7 @@ print_sword: { rts } //SEG212 print_word +// Print a word as HEX print_word: { .label w = 8 //SEG213 [103] (byte) print_byte::b#1 ← > (word) print_word::w#6 -- vbuxx=_hi_vwuz1 @@ -8304,6 +8324,7 @@ print_word: { rts } //SEG226 print_byte +// Print a byte as HEX print_byte: { //SEG227 [109] (byte~) print_byte::$0 ← (byte) print_byte::b#5 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -8342,6 +8363,7 @@ print_byte: { rts } //SEG242 print_char +// Print a single char print_char: { //SEG243 [117] *((byte*) print_char_cursor#84) ← (byte) print_char::ch#5 -- _deref_pbuz1=vbuaa ldy #0 @@ -8358,6 +8380,7 @@ print_char: { rts } //SEG247 print_sbyte +// Print a signed byte as HEX print_sbyte: { //SEG248 [121] if((signed byte) print_sbyte::b#3<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsxx_lt_0_then_la1 cpx #0 @@ -8382,7 +8405,6 @@ print_sbyte: { //SEG257 print_sbyte::@2 b2: //SEG258 [125] (byte~) print_byte::b#9 ← (byte)(signed byte) print_sbyte::b#5 - // (byte~) print_byte::b#9 = (byte)(signed byte) print_sbyte::b#5 // register copy reg byte x //SEG259 [126] call print_byte //SEG260 [108] phi from print_sbyte::@2 to print_byte [phi:print_sbyte::@2->print_byte] print_byte_from_b2: @@ -8418,6 +8440,8 @@ print_sbyte: { jmp b2_from_b5 } //SEG273 mul8s +// Multiply of two signed bytes to a signed word +// Fixes offsets introduced by using unsigned multiplication mul8s: { .label m = $c .label a = 2 @@ -8433,12 +8457,10 @@ mul8s: { //SEG279 [149] phi (byte) mul8u::b#2 = (byte~) mul8u::b#3 [phi:mul8s->mul8u#1] -- register_copy jsr mul8u //SEG280 [134] (word) mul8u::return#2 ← (word) mul8u::res#2 - // (word) mul8u::return#2 = (word) mul8u::res#2 // register copy zp ZP_WORD:12 jmp b6 //SEG281 mul8s::@6 b6: //SEG282 [135] (word) mul8s::m#0 ← (word) mul8u::return#2 - // (word) mul8s::m#0 = (word) mul8u::return#2 // register copy zp ZP_WORD:12 //SEG283 [136] if((signed byte) mul8s::a#0>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mul8s::@1 -- vbsz1_ge_0_then_la1 lda a cmp #0 @@ -8492,6 +8514,8 @@ mul8s: { rts } //SEG303 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .label mb = 6 .label res = $c @@ -8561,13 +8585,13 @@ mul8u: { jmp b1 } //SEG327 mulf8s +// Fast multiply two signed bytes to a word result mulf8s: { .label return = $e jmp mulf8s_prepare1 //SEG328 mulf8s::mulf8s_prepare1 mulf8s_prepare1: //SEG329 [161] (byte~) mulf8u_prepare::a#3 ← (byte)(signed byte) mulf8s::a#0 - // (byte~) mulf8u_prepare::a#3 = (byte)(signed byte) mulf8s::a#0 // register copy reg byte a //SEG330 [162] call mulf8u_prepare //SEG331 [190] phi from mulf8s::mulf8s_prepare1 to mulf8u_prepare [phi:mulf8s::mulf8s_prepare1->mulf8u_prepare] mulf8u_prepare_from_mulf8s_prepare1: @@ -8581,12 +8605,10 @@ mulf8s: { //SEG335 [164] call mulf8s_prepared jsr mulf8s_prepared //SEG336 [165] (signed word) mulf8s_prepared::return#2 ← (signed word)(word) mulf8s_prepared::m#4 - // (signed word) mulf8s_prepared::return#2 = (signed word)(word) mulf8s_prepared::m#4 // register copy zp ZP_WORD:14 jmp b4 //SEG337 mulf8s::@4 b4: //SEG338 [166] (signed word) mulf8s::return#0 ← (signed word) mulf8s_prepared::return#2 - // (signed word) mulf8s::return#0 = (signed word) mulf8s_prepared::return#2 // register copy zp ZP_WORD:14 jmp breturn //SEG339 mulf8s::@return breturn: @@ -8594,6 +8616,8 @@ mulf8s: { rts } //SEG341 mulf8s_prepared +// 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: { .label memA = $fd .label m = $e @@ -8607,12 +8631,10 @@ mulf8s_prepared: { //SEG345 [185] phi (byte) mulf8u_prepared::b#2 = (byte~) mulf8u_prepared::b#3 [phi:mulf8s_prepared->mulf8u_prepared#0] -- register_copy jsr mulf8u_prepared //SEG346 [170] (word) mulf8u_prepared::return#3 ← (word) mulf8u_prepared::return#0 - // (word) mulf8u_prepared::return#3 = (word) mulf8u_prepared::return#0 // register copy zp ZP_WORD:14 jmp b6 //SEG347 mulf8s_prepared::@6 b6: //SEG348 [171] (word) mulf8s_prepared::m#0 ← (word) mulf8u_prepared::return#3 - // (word) mulf8s_prepared::m#0 = (word) mulf8u_prepared::return#3 // register copy zp ZP_WORD:14 //SEG349 [172] if(*((const signed byte*) mulf8s_prepared::memA#0)>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mulf8s_prepared::@1 -- _deref_pbsc1_ge_0_then_la1 lda memA cmp #0 @@ -8666,6 +8688,8 @@ mulf8s_prepared: { rts } //SEG369 mulf8u_prepared +// 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: { .label resL = $fe .label memB = $ff @@ -8697,6 +8721,7 @@ mulf8u_prepared: { rts } //SEG375 mulf8u_prepare +// Prepare for fast multiply with an unsigned byte to a word result mulf8u_prepare: { .label memA = $fd //SEG376 [191] *((const byte*) mulf8u_prepare::memA#0) ← (byte) mulf8u_prepare::a#2 -- _deref_pbuc1=vbuaa @@ -8715,6 +8740,8 @@ mulf8u_prepare: { rts } //SEG380 muls8s +// Slow multiplication of signed bytes +// Perform a signed multiplication by repeated addition/subtraction muls8s: { .label m = 8 .label return = 8 @@ -8828,6 +8855,7 @@ muls8s: { jmp b4_from_b5 } //SEG411 mul8u_compare +// Perform all possible byte multiplications (slow and fast) and compare the results mul8u_compare: { .label ms = 8 .label mf = $e @@ -8859,18 +8887,15 @@ mul8u_compare: { //SEG421 mul8u_compare::@2 b2: //SEG422 [209] (byte) muls8u::a#0 ← (byte) mul8u_compare::a#7 - // (byte) muls8u::a#0 = (byte) mul8u_compare::a#7 // register copy zp ZP_BYTE:2 //SEG423 [210] (byte) muls8u::b#0 ← (byte) mul8u_compare::b#10 -- vbuxx=vbuz1 ldx b //SEG424 [211] call muls8u jsr muls8u //SEG425 [212] (word) muls8u::return#2 ← (word) muls8u::return#0 - // (word) muls8u::return#2 = (word) muls8u::return#0 // register copy zp ZP_WORD:8 jmp b12 //SEG426 mul8u_compare::@12 b12: //SEG427 [213] (word) mul8u_compare::ms#0 ← (word) muls8u::return#2 - // (word) mul8u_compare::ms#0 = (word) muls8u::return#2 // register copy zp ZP_WORD:8 //SEG428 [214] (byte) mulf8u::a#0 ← (byte) mul8u_compare::a#7 -- vbuaa=vbuz1 lda a //SEG429 [215] (byte) mulf8u::b#0 ← (byte) mul8u_compare::b#10 -- vbuxx=vbuz1 @@ -8878,12 +8903,10 @@ mul8u_compare: { //SEG430 [216] call mulf8u jsr mulf8u //SEG431 [217] (word) mulf8u::return#2 ← (word) mulf8u::return#0 - // (word) mulf8u::return#2 = (word) mulf8u::return#0 // register copy zp ZP_WORD:14 jmp b13 //SEG432 mul8u_compare::@13 b13: //SEG433 [218] (word) mul8u_compare::mf#0 ← (word) mulf8u::return#2 - // (word) mul8u_compare::mf#0 = (word) mulf8u::return#2 // register copy zp ZP_WORD:14 //SEG434 [219] (byte) mul8u::a#2 ← (byte) mul8u_compare::a#7 -- vbuxx=vbuz1 ldx a //SEG435 [220] (byte) mul8u::b#1 ← (byte) mul8u_compare::b#10 -- vbuaa=vbuz1 @@ -8895,12 +8918,10 @@ mul8u_compare: { //SEG439 [149] phi (byte) mul8u::b#2 = (byte) mul8u::b#1 [phi:mul8u_compare::@13->mul8u#1] -- register_copy jsr mul8u //SEG440 [222] (word) mul8u::return#3 ← (word) mul8u::res#2 - // (word) mul8u::return#3 = (word) mul8u::res#2 // register copy zp ZP_WORD:12 jmp b14 //SEG441 mul8u_compare::@14 b14: //SEG442 [223] (word) mul8u_compare::mn#0 ← (word) mul8u::return#3 - // (word) mul8u_compare::mn#0 = (word) mul8u::return#3 // register copy zp ZP_WORD:12 //SEG443 [224] if((word) mul8u_compare::ms#0==(word) mul8u_compare::mf#0) goto mul8u_compare::@3 -- vwuz1_eq_vwuz2_then_la1 lda ms cmp mf @@ -8953,13 +8974,9 @@ mul8u_compare: { //SEG458 [231] (byte) mul8u_error::a#0 ← (byte) mul8u_compare::a#7 -- vbuxx=vbuz1 ldx a //SEG459 [232] (byte) mul8u_error::b#0 ← (byte) mul8u_compare::b#10 - // (byte) mul8u_error::b#0 = (byte) mul8u_compare::b#10 // register copy zp ZP_BYTE:3 //SEG460 [233] (word) mul8u_error::ms#0 ← (word) mul8u_compare::ms#0 - // (word) mul8u_error::ms#0 = (word) mul8u_compare::ms#0 // register copy zp ZP_WORD:8 //SEG461 [234] (word) mul8u_error::mn#0 ← (word) mul8u_compare::mn#0 - // (word) mul8u_error::mn#0 = (word) mul8u_compare::mn#0 // register copy zp ZP_WORD:12 //SEG462 [235] (word) mul8u_error::mf#0 ← (word) mul8u_compare::mf#0 - // (word) mul8u_error::mf#0 = (word) mul8u_compare::mf#0 // register copy zp ZP_WORD:14 //SEG463 [236] call mul8u_error //SEG464 [247] phi from mul8u_compare::@8 to mul8u_error [phi:mul8u_compare::@8->mul8u_error] mul8u_error_from_b8: @@ -9044,7 +9061,6 @@ mul8u_error: { //SEG494 mul8u_error::@1 b1: //SEG495 [249] (byte) print_byte::b#3 ← (byte) mul8u_error::a#0 - // (byte) print_byte::b#3 = (byte) mul8u_error::a#0 // register copy reg byte x //SEG496 [250] call print_byte //SEG497 [108] phi from mul8u_error::@1 to print_byte [phi:mul8u_error::@1->print_byte] print_byte_from_b1: @@ -9096,7 +9112,6 @@ mul8u_error: { //SEG518 mul8u_error::@5 b5: //SEG519 [257] (word) print_word::w#3 ← (word) mul8u_error::ms#0 - // (word) print_word::w#3 = (word) mul8u_error::ms#0 // register copy zp ZP_WORD:8 //SEG520 [258] call print_word //SEG521 [102] phi from mul8u_error::@5 to print_word [phi:mul8u_error::@5->print_word] print_word_from_b5: @@ -9184,10 +9199,10 @@ mul8u_error: { str4: .text " / fast:@" } //SEG556 mulf8u +// Fast multiply two unsigned bytes to a word result mulf8u: { .label return = $e //SEG557 [270] (byte) mulf8u_prepare::a#0 ← (byte) mulf8u::a#0 - // (byte) mulf8u_prepare::a#0 = (byte) mulf8u::a#0 // register copy reg byte a //SEG558 [271] call mulf8u_prepare //SEG559 [190] phi from mulf8u to mulf8u_prepare [phi:mulf8u->mulf8u_prepare] mulf8u_prepare_from_mulf8u: @@ -9197,19 +9212,16 @@ mulf8u: { //SEG561 mulf8u::@2 b2: //SEG562 [272] (byte) mulf8u_prepared::b#0 ← (byte) mulf8u::b#0 - // (byte) mulf8u_prepared::b#0 = (byte) mulf8u::b#0 // register copy reg byte x //SEG563 [273] call mulf8u_prepared //SEG564 [185] phi from mulf8u::@2 to mulf8u_prepared [phi:mulf8u::@2->mulf8u_prepared] mulf8u_prepared_from_b2: //SEG565 [185] phi (byte) mulf8u_prepared::b#2 = (byte) mulf8u_prepared::b#0 [phi:mulf8u::@2->mulf8u_prepared#0] -- register_copy jsr mulf8u_prepared //SEG566 [274] (word) mulf8u_prepared::return#2 ← (word) mulf8u_prepared::return#0 - // (word) mulf8u_prepared::return#2 = (word) mulf8u_prepared::return#0 // register copy zp ZP_WORD:14 jmp b3 //SEG567 mulf8u::@3 b3: //SEG568 [275] (word) mulf8u::return#0 ← (word) mulf8u_prepared::return#2 - // (word) mulf8u::return#0 = (word) mulf8u_prepared::return#2 // register copy zp ZP_WORD:14 jmp breturn //SEG569 mulf8u::@return breturn: @@ -9217,6 +9229,8 @@ mulf8u: { rts } //SEG571 muls8u +// Slow multiplication of unsigned bytes +// Calculate an unsigned multiplication by repeated addition muls8u: { .label return = 8 .label m = 8 @@ -9276,6 +9290,8 @@ muls8u: { rts } //SEG590 mulf_tables_cmp +// Compare the ASM-based mul tables with the KC-based mul tables +// Red screen on failure - green on success mulf_tables_cmp: { .label asm_sqr = 8 .label kc_sqr = 4 @@ -9329,7 +9345,6 @@ mulf_tables_cmp: { //SEG605 mulf_tables_cmp::@6 b6: //SEG606 [289] (word~) print_word::w#11 ← (word)(byte*) mulf_tables_cmp::asm_sqr#2 - // (word~) print_word::w#11 = (word)(byte*) mulf_tables_cmp::asm_sqr#2 // register copy zp ZP_WORD:8 //SEG607 [290] call print_word //SEG608 [102] phi from mulf_tables_cmp::@6 to print_word [phi:mulf_tables_cmp::@6->print_word] print_word_from_b6: @@ -9448,6 +9463,8 @@ mulf_tables_cmp: { str2: .text "multiply tables match!@" } //SEG648 mulf_init_asm +// Initialize the multiplication tables using ASM code from +// http://codebase64.org/doku.php?id=base:seriously_fast_multiplication mulf_init_asm: { .label mem = $ff //SEG649 asm { ldx#$00 txa .byte$c9 lb1: tya adc#$00 ml1: stamula_sqr1_hi,x tay cmp#$40 txa ror ml9: adc#$00 staml9+1 inx ml0: stamula_sqr1_lo,x bnelb1 incml0+2 incml1+2 clc iny bnelb1 ldx#$00 ldy#$ff !: ldamula_sqr1_hi+1,x stamula_sqr2_hi+$100,x ldamula_sqr1_hi,x stamula_sqr2_hi,y ldamula_sqr1_lo+1,x stamula_sqr2_lo+$100,x ldamula_sqr1_lo,x stamula_sqr2_lo,y dey inx bne!- } @@ -9508,6 +9525,7 @@ mulf_init_asm: { rts } //SEG656 mulf_init +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label sqr1_hi = 6 .label sqr = 8 @@ -9703,6 +9721,7 @@ mulf_init: { jmp b4 } //SEG718 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 4 //SEG719 [341] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] @@ -9966,10 +9985,12 @@ Removing instruction b1_from_print_ln: Removing instruction b1_from_b1: Removing instruction b1_from_print_str: Removing instruction b1_from_b2: +Removing instruction print_sbyte_from_b1: Removing instruction b2_from_b1: Removing instruction print_str_from_b2: Removing instruction b4_from_b3: Removing instruction print_str_from_b4: +Removing instruction print_sword_from_b5: Removing instruction b6_from_b5: Removing instruction print_str_from_b6: Removing instruction b8_from_b7: @@ -9980,10 +10001,12 @@ Removing instruction b2_from_print_sword: Removing instruction print_char_from_b2: Removing instruction b1_from_print_sword: Removing instruction b1_from_b4: +Removing instruction print_word_from_b1: Removing instruction b3_from_print_sbyte: Removing instruction print_char_from_b3: Removing instruction b2_from_b3: Removing instruction b2_from_b5: +Removing instruction print_byte_from_b2: Removing instruction b1_from_print_sbyte: Removing instruction print_char_from_b1: Removing instruction b1_from_b3: @@ -9993,6 +10016,8 @@ Removing instruction b2_from_b4: Removing instruction breturn: Removing instruction b4_from_b2: Removing instruction b4_from_b7: +Removing instruction mulf8u_prepare_from_mulf8s_prepare1: +Removing instruction breturn: Removing instruction b1_from_b3: Removing instruction b1_from_b6: Removing instruction b2_from_b1: @@ -10013,19 +10038,24 @@ Removing instruction b16_from_b11: Removing instruction print_ln_from_b16: Removing instruction b20_from_b3: Removing instruction b4_from_b20: +Removing instruction print_byte_from_b1: Removing instruction b2_from_b1: Removing instruction print_str_from_b2: Removing instruction b4_from_b3: Removing instruction print_str_from_b4: +Removing instruction print_word_from_b5: Removing instruction b6_from_b5: Removing instruction print_str_from_b6: Removing instruction b8_from_b7: Removing instruction print_str_from_b8: Removing instruction b10_from_b9: Removing instruction print_ln_from_b10: +Removing instruction mulf8u_prepared_from_b2: +Removing instruction breturn: Removing instruction b2_from_b2: Removing instruction breturn: Removing instruction b1_from_b2: +Removing instruction print_word_from_b6: Removing instruction b7_from_b6: Removing instruction print_str_from_b7: Removing instruction b5_from_b2: @@ -10064,13 +10094,11 @@ Removing instruction breturn: Removing instruction breturn: Removing instruction print_str_from_mul8s_error: Removing instruction b1: -Removing instruction print_sbyte_from_b1: Removing instruction b2: Removing instruction b3: Removing instruction print_sbyte_from_b3: Removing instruction b4: Removing instruction b5: -Removing instruction print_sword_from_b5: Removing instruction b6: Removing instruction b7: Removing instruction print_sword_from_b7: @@ -10081,7 +10109,6 @@ Removing instruction b10: Removing instruction breturn: Removing instruction b2: Removing instruction b4: -Removing instruction print_word_from_b1: Removing instruction breturn: Removing instruction print_byte_from_print_word: Removing instruction b1: @@ -10093,7 +10120,6 @@ Removing instruction print_char_from_b1: Removing instruction breturn: Removing instruction breturn: Removing instruction b3: -Removing instruction print_byte_from_b2: Removing instruction breturn: Removing instruction b5: Removing instruction mul8u_from_mul8s: @@ -10105,10 +10131,8 @@ Removing instruction breturn: Removing instruction b7: Removing instruction b1_from_b4: Removing instruction mulf8s_prepare1: -Removing instruction mulf8u_prepare_from_mulf8s_prepare1: Removing instruction b2: Removing instruction b4: -Removing instruction breturn: Removing instruction mulf8u_prepared_from_mulf8s_prepared: Removing instruction b6: Removing instruction b3: @@ -10131,13 +10155,11 @@ Removing instruction b11: Removing instruction b16: Removing instruction print_str_from_mul8u_error: Removing instruction b1: -Removing instruction print_byte_from_b1: Removing instruction b2: Removing instruction b3: Removing instruction print_byte_from_b3: Removing instruction b4: Removing instruction b5: -Removing instruction print_word_from_b5: Removing instruction b6: Removing instruction b7: Removing instruction print_word_from_b7: @@ -10148,16 +10170,13 @@ Removing instruction b10: Removing instruction breturn: Removing instruction mulf8u_prepare_from_mulf8u: Removing instruction b2: -Removing instruction mulf8u_prepared_from_b2: Removing instruction b3: -Removing instruction breturn: Removing instruction b2_from_muls8u: Removing instruction b1_from_b2: Removing instruction b1_from_mulf_tables_cmp: Removing instruction b3: Removing instruction print_str_from_b3: Removing instruction b6: -Removing instruction print_word_from_b6: Removing instruction b7: Removing instruction b8: Removing instruction print_word_from_b8: @@ -10792,6 +10811,7 @@ main: { rts } //SEG33 mul8s_compare +// Perform all possible signed byte multiplications (slow and fast) and compare the results mul8s_compare: { .label ms = 8 .label mf = $e @@ -10815,16 +10835,13 @@ mul8s_compare: { //SEG43 mul8s_compare::@2 b2: //SEG44 [20] (signed byte) muls8s::a#0 ← (signed byte) mul8s_compare::a#7 - // (signed byte) muls8s::a#0 = (signed byte) mul8s_compare::a#7 // register copy zp ZP_BYTE:2 //SEG45 [21] (signed byte) muls8s::b#0 ← (signed byte) mul8s_compare::b#10 -- vbsxx=vbsz1 ldx b //SEG46 [22] call muls8s jsr muls8s //SEG47 [23] (signed word) muls8s::return#2 ← (signed word) muls8s::return#0 - // (signed word) muls8s::return#2 = (signed word) muls8s::return#0 // register copy zp ZP_WORD:8 //SEG48 mul8s_compare::@12 //SEG49 [24] (signed word) mul8s_compare::ms#0 ← (signed word) muls8s::return#2 - // (signed word) mul8s_compare::ms#0 = (signed word) muls8s::return#2 // register copy zp ZP_WORD:8 //SEG50 [25] (signed byte) mulf8s::a#0 ← (signed byte) mul8s_compare::a#7 -- vbsaa=vbsz1 lda a //SEG51 [26] (signed byte) mulf8s::b#0 ← (signed byte) mul8s_compare::b#10 -- vbsxx=vbsz1 @@ -10833,21 +10850,16 @@ mul8s_compare: { //SEG53 [160] phi from mul8s_compare::@12 to mulf8s [phi:mul8s_compare::@12->mulf8s] jsr mulf8s //SEG54 [28] (signed word) mulf8s::return#2 ← (signed word) mulf8s::return#0 - // (signed word) mulf8s::return#2 = (signed word) mulf8s::return#0 // register copy zp ZP_WORD:14 //SEG55 mul8s_compare::@13 //SEG56 [29] (signed word) mul8s_compare::mf#0 ← (signed word) mulf8s::return#2 - // (signed word) mul8s_compare::mf#0 = (signed word) mulf8s::return#2 // register copy zp ZP_WORD:14 //SEG57 [30] (signed byte) mul8s::a#0 ← (signed byte) mul8s_compare::a#7 - // (signed byte) mul8s::a#0 = (signed byte) mul8s_compare::a#7 // register copy zp ZP_BYTE:2 //SEG58 [31] (signed byte) mul8s::b#0 ← (signed byte) mul8s_compare::b#10 -- vbsyy=vbsz1 ldy b //SEG59 [32] call mul8s jsr mul8s //SEG60 [33] (signed word) mul8s::return#2 ← (signed word)(word) mul8s::m#4 - // (signed word) mul8s::return#2 = (signed word)(word) mul8s::m#4 // register copy zp ZP_WORD:12 //SEG61 mul8s_compare::@14 //SEG62 [34] (signed word) mul8s_compare::mn#0 ← (signed word) mul8s::return#2 - // (signed word) mul8s_compare::mn#0 = (signed word) mul8s::return#2 // register copy zp ZP_WORD:12 //SEG63 [35] if((signed word) mul8s_compare::ms#0==(signed word) mul8s_compare::mf#0) goto mul8s_compare::@3 -- vwsz1_eq_vwsz2_then_la1 lda ms cmp mf @@ -10891,13 +10903,9 @@ mul8s_compare: { //SEG78 [42] (signed byte) mul8s_error::a#0 ← (signed byte) mul8s_compare::a#7 -- vbsxx=vbsz1 ldx a //SEG79 [43] (signed byte) mul8s_error::b#0 ← (signed byte) mul8s_compare::b#10 - // (signed byte) mul8s_error::b#0 = (signed byte) mul8s_compare::b#10 // register copy zp ZP_BYTE:3 //SEG80 [44] (signed word) mul8s_error::ms#0 ← (signed word) mul8s_compare::ms#0 - // (signed word) mul8s_error::ms#0 = (signed word) mul8s_compare::ms#0 // register copy zp ZP_WORD:8 //SEG81 [45] (signed word) mul8s_error::mn#0 ← (signed word) mul8s_compare::mn#0 - // (signed word) mul8s_error::mn#0 = (signed word) mul8s_compare::mn#0 // register copy zp ZP_WORD:12 //SEG82 [46] (signed word) mul8s_error::mf#0 ← (signed word) mul8s_compare::mf#0 - // (signed word) mul8s_error::mf#0 = (signed word) mul8s_compare::mf#0 // register copy zp ZP_WORD:14 //SEG83 [47] call mul8s_error jsr mul8s_error //SEG84 mul8s_compare::@return @@ -10949,6 +10957,7 @@ mul8s_compare: { str: .text "signed multiply results match!@" } //SEG108 print_ln +// Print a newline print_ln: { //SEG109 [59] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] //SEG110 [59] phi (byte*) print_line_cursor#23 = (byte*) print_line_cursor#45 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy @@ -10976,6 +10985,7 @@ print_ln: { rts } //SEG116 print_str +// Print a zero-terminated string print_str: { .label str = 6 //SEG117 [64] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] @@ -11031,7 +11041,6 @@ mul8s_error: { jsr print_str //SEG134 mul8s_error::@1 //SEG135 [72] (signed byte) print_sbyte::b#1 ← (signed byte) mul8s_error::a#0 - // (signed byte) print_sbyte::b#1 = (signed byte) mul8s_error::a#0 // register copy reg byte x //SEG136 [73] call print_sbyte //SEG137 [120] phi from mul8s_error::@1 to print_sbyte [phi:mul8s_error::@1->print_sbyte] //SEG138 [120] phi (signed byte) print_sbyte::b#3 = (signed byte) print_sbyte::b#1 [phi:mul8s_error::@1->print_sbyte#0] -- register_copy @@ -11067,7 +11076,6 @@ mul8s_error: { jsr print_str //SEG156 mul8s_error::@5 //SEG157 [80] (signed word) print_sword::w#1 ← (signed word) mul8s_error::ms#0 - // (signed word) print_sword::w#1 = (signed word) mul8s_error::ms#0 // register copy zp ZP_WORD:8 //SEG158 [81] call print_sword //SEG159 [93] phi from mul8s_error::@5 to print_sword [phi:mul8s_error::@5->print_sword] //SEG160 [93] phi (signed word) print_sword::w#4 = (signed word) print_sword::w#1 [phi:mul8s_error::@5->print_sword#0] -- register_copy @@ -11131,6 +11139,7 @@ mul8s_error: { str4: .text " / fast:@" } //SEG191 print_sword +// Print a signed word as HEX print_sword: { .label w = 8 //SEG192 [94] if((signed word) print_sword::w#4>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sword::@1 -- vwsz1_ge_0_then_la1 @@ -11161,7 +11170,6 @@ print_sword: { //SEG204 print_sword::@1 b1: //SEG205 [99] (word~) print_word::w#13 ← (word)(signed word) print_sword::w#5 - // (word~) print_word::w#13 = (word)(signed word) print_sword::w#5 // register copy zp ZP_WORD:8 //SEG206 [100] call print_word //SEG207 [102] phi from print_sword::@1 to print_word [phi:print_sword::@1->print_word] //SEG208 [102] phi (byte*) print_char_cursor#139 = (byte*) print_char_cursor#134 [phi:print_sword::@1->print_word#0] -- register_copy @@ -11172,6 +11180,7 @@ print_sword: { rts } //SEG212 print_word +// Print a word as HEX print_word: { .label w = 8 //SEG213 [103] (byte) print_byte::b#1 ← > (word) print_word::w#6 -- vbuxx=_hi_vwuz1 @@ -11196,6 +11205,7 @@ print_word: { rts } //SEG226 print_byte +// Print a byte as HEX print_byte: { //SEG227 [109] (byte~) print_byte::$0 ← (byte) print_byte::b#5 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4 txa @@ -11228,6 +11238,7 @@ print_byte: { rts } //SEG242 print_char +// Print a single char print_char: { //SEG243 [117] *((byte*) print_char_cursor#84) ← (byte) print_char::ch#5 -- _deref_pbuz1=vbuaa ldy #0 @@ -11242,6 +11253,7 @@ print_char: { rts } //SEG247 print_sbyte +// Print a signed byte as HEX print_sbyte: { //SEG248 [121] if((signed byte) print_sbyte::b#3<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsxx_lt_0_then_la1 cpx #0 @@ -11259,7 +11271,6 @@ print_sbyte: { //SEG257 print_sbyte::@2 b2: //SEG258 [125] (byte~) print_byte::b#9 ← (byte)(signed byte) print_sbyte::b#5 - // (byte~) print_byte::b#9 = (byte)(signed byte) print_sbyte::b#5 // register copy reg byte x //SEG259 [126] call print_byte //SEG260 [108] phi from print_sbyte::@2 to print_byte [phi:print_sbyte::@2->print_byte] //SEG261 [108] phi (byte*) print_char_cursor#140 = (byte*) print_char_cursor#18 [phi:print_sbyte::@2->print_byte#0] -- register_copy @@ -11287,6 +11298,8 @@ print_sbyte: { jmp b2 } //SEG273 mul8s +// Multiply of two signed bytes to a signed word +// Fixes offsets introduced by using unsigned multiplication mul8s: { .label m = $c .label a = 2 @@ -11301,10 +11314,8 @@ mul8s: { //SEG279 [149] phi (byte) mul8u::b#2 = (byte~) mul8u::b#3 [phi:mul8s->mul8u#1] -- register_copy jsr mul8u //SEG280 [134] (word) mul8u::return#2 ← (word) mul8u::res#2 - // (word) mul8u::return#2 = (word) mul8u::res#2 // register copy zp ZP_WORD:12 //SEG281 mul8s::@6 //SEG282 [135] (word) mul8s::m#0 ← (word) mul8u::return#2 - // (word) mul8s::m#0 = (word) mul8u::return#2 // register copy zp ZP_WORD:12 //SEG283 [136] if((signed byte) mul8s::a#0>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mul8s::@1 -- vbsz1_ge_0_then_la1 lda a cmp #0 @@ -11344,6 +11355,8 @@ mul8s: { rts } //SEG303 mul8u +// Simple binary multiplication implementation +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word mul8u: { .label mb = 6 .label res = $c @@ -11401,11 +11414,11 @@ mul8u: { jmp b1 } //SEG327 mulf8s +// Fast multiply two signed bytes to a word result mulf8s: { .label return = $e //SEG328 mulf8s::mulf8s_prepare1 //SEG329 [161] (byte~) mulf8u_prepare::a#3 ← (byte)(signed byte) mulf8s::a#0 - // (byte~) mulf8u_prepare::a#3 = (byte)(signed byte) mulf8s::a#0 // register copy reg byte a //SEG330 [162] call mulf8u_prepare //SEG331 [190] phi from mulf8s::mulf8s_prepare1 to mulf8u_prepare [phi:mulf8s::mulf8s_prepare1->mulf8u_prepare] //SEG332 [190] phi (byte) mulf8u_prepare::a#2 = (byte~) mulf8u_prepare::a#3 [phi:mulf8s::mulf8s_prepare1->mulf8u_prepare#0] -- register_copy @@ -11416,15 +11429,15 @@ mulf8s: { //SEG335 [164] call mulf8s_prepared jsr mulf8s_prepared //SEG336 [165] (signed word) mulf8s_prepared::return#2 ← (signed word)(word) mulf8s_prepared::m#4 - // (signed word) mulf8s_prepared::return#2 = (signed word)(word) mulf8s_prepared::m#4 // register copy zp ZP_WORD:14 //SEG337 mulf8s::@4 //SEG338 [166] (signed word) mulf8s::return#0 ← (signed word) mulf8s_prepared::return#2 - // (signed word) mulf8s::return#0 = (signed word) mulf8s_prepared::return#2 // register copy zp ZP_WORD:14 //SEG339 mulf8s::@return //SEG340 [167] return rts } //SEG341 mulf8s_prepared +// 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: { .label memA = $fd .label m = $e @@ -11437,10 +11450,8 @@ mulf8s_prepared: { //SEG345 [185] phi (byte) mulf8u_prepared::b#2 = (byte~) mulf8u_prepared::b#3 [phi:mulf8s_prepared->mulf8u_prepared#0] -- register_copy jsr mulf8u_prepared //SEG346 [170] (word) mulf8u_prepared::return#3 ← (word) mulf8u_prepared::return#0 - // (word) mulf8u_prepared::return#3 = (word) mulf8u_prepared::return#0 // register copy zp ZP_WORD:14 //SEG347 mulf8s_prepared::@6 //SEG348 [171] (word) mulf8s_prepared::m#0 ← (word) mulf8u_prepared::return#3 - // (word) mulf8s_prepared::m#0 = (word) mulf8u_prepared::return#3 // register copy zp ZP_WORD:14 //SEG349 [172] if(*((const signed byte*) mulf8s_prepared::memA#0)>=(byte/signed byte/word/signed word/dword/signed dword) 0) goto mulf8s_prepared::@1 -- _deref_pbsc1_ge_0_then_la1 lda memA cmp #0 @@ -11480,6 +11491,8 @@ mulf8s_prepared: { rts } //SEG369 mulf8u_prepared +// 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: { .label resL = $fe .label memB = $ff @@ -11508,6 +11521,7 @@ mulf8u_prepared: { rts } //SEG375 mulf8u_prepare +// Prepare for fast multiply with an unsigned byte to a word result mulf8u_prepare: { .label memA = $fd //SEG376 [191] *((const byte*) mulf8u_prepare::memA#0) ← (byte) mulf8u_prepare::a#2 -- _deref_pbuc1=vbuaa @@ -11523,6 +11537,8 @@ mulf8u_prepare: { rts } //SEG380 muls8s +// Slow multiplication of signed bytes +// Perform a signed multiplication by repeated addition/subtraction muls8s: { .label m = 8 .label return = 8 @@ -11616,6 +11632,7 @@ muls8s: { jmp b4 } //SEG411 mul8u_compare +// Perform all possible byte multiplications (slow and fast) and compare the results mul8u_compare: { .label ms = 8 .label mf = $e @@ -11639,16 +11656,13 @@ mul8u_compare: { //SEG421 mul8u_compare::@2 b2: //SEG422 [209] (byte) muls8u::a#0 ← (byte) mul8u_compare::a#7 - // (byte) muls8u::a#0 = (byte) mul8u_compare::a#7 // register copy zp ZP_BYTE:2 //SEG423 [210] (byte) muls8u::b#0 ← (byte) mul8u_compare::b#10 -- vbuxx=vbuz1 ldx b //SEG424 [211] call muls8u jsr muls8u //SEG425 [212] (word) muls8u::return#2 ← (word) muls8u::return#0 - // (word) muls8u::return#2 = (word) muls8u::return#0 // register copy zp ZP_WORD:8 //SEG426 mul8u_compare::@12 //SEG427 [213] (word) mul8u_compare::ms#0 ← (word) muls8u::return#2 - // (word) mul8u_compare::ms#0 = (word) muls8u::return#2 // register copy zp ZP_WORD:8 //SEG428 [214] (byte) mulf8u::a#0 ← (byte) mul8u_compare::a#7 -- vbuaa=vbuz1 lda a //SEG429 [215] (byte) mulf8u::b#0 ← (byte) mul8u_compare::b#10 -- vbuxx=vbuz1 @@ -11656,10 +11670,8 @@ mul8u_compare: { //SEG430 [216] call mulf8u jsr mulf8u //SEG431 [217] (word) mulf8u::return#2 ← (word) mulf8u::return#0 - // (word) mulf8u::return#2 = (word) mulf8u::return#0 // register copy zp ZP_WORD:14 //SEG432 mul8u_compare::@13 //SEG433 [218] (word) mul8u_compare::mf#0 ← (word) mulf8u::return#2 - // (word) mul8u_compare::mf#0 = (word) mulf8u::return#2 // register copy zp ZP_WORD:14 //SEG434 [219] (byte) mul8u::a#2 ← (byte) mul8u_compare::a#7 -- vbuxx=vbuz1 ldx a //SEG435 [220] (byte) mul8u::b#1 ← (byte) mul8u_compare::b#10 -- vbuaa=vbuz1 @@ -11670,10 +11682,8 @@ mul8u_compare: { //SEG439 [149] phi (byte) mul8u::b#2 = (byte) mul8u::b#1 [phi:mul8u_compare::@13->mul8u#1] -- register_copy jsr mul8u //SEG440 [222] (word) mul8u::return#3 ← (word) mul8u::res#2 - // (word) mul8u::return#3 = (word) mul8u::res#2 // register copy zp ZP_WORD:12 //SEG441 mul8u_compare::@14 //SEG442 [223] (word) mul8u_compare::mn#0 ← (word) mul8u::return#3 - // (word) mul8u_compare::mn#0 = (word) mul8u::return#3 // register copy zp ZP_WORD:12 //SEG443 [224] if((word) mul8u_compare::ms#0==(word) mul8u_compare::mf#0) goto mul8u_compare::@3 -- vwuz1_eq_vwuz2_then_la1 lda ms cmp mf @@ -11717,13 +11727,9 @@ mul8u_compare: { //SEG458 [231] (byte) mul8u_error::a#0 ← (byte) mul8u_compare::a#7 -- vbuxx=vbuz1 ldx a //SEG459 [232] (byte) mul8u_error::b#0 ← (byte) mul8u_compare::b#10 - // (byte) mul8u_error::b#0 = (byte) mul8u_compare::b#10 // register copy zp ZP_BYTE:3 //SEG460 [233] (word) mul8u_error::ms#0 ← (word) mul8u_compare::ms#0 - // (word) mul8u_error::ms#0 = (word) mul8u_compare::ms#0 // register copy zp ZP_WORD:8 //SEG461 [234] (word) mul8u_error::mn#0 ← (word) mul8u_compare::mn#0 - // (word) mul8u_error::mn#0 = (word) mul8u_compare::mn#0 // register copy zp ZP_WORD:12 //SEG462 [235] (word) mul8u_error::mf#0 ← (word) mul8u_compare::mf#0 - // (word) mul8u_error::mf#0 = (word) mul8u_compare::mf#0 // register copy zp ZP_WORD:14 //SEG463 [236] call mul8u_error //SEG464 [247] phi from mul8u_compare::@8 to mul8u_error [phi:mul8u_compare::@8->mul8u_error] jsr mul8u_error @@ -11788,7 +11794,6 @@ mul8u_error: { jsr print_str //SEG494 mul8u_error::@1 //SEG495 [249] (byte) print_byte::b#3 ← (byte) mul8u_error::a#0 - // (byte) print_byte::b#3 = (byte) mul8u_error::a#0 // register copy reg byte x //SEG496 [250] call print_byte //SEG497 [108] phi from mul8u_error::@1 to print_byte [phi:mul8u_error::@1->print_byte] //SEG498 [108] phi (byte*) print_char_cursor#140 = (byte*) print_char_cursor#132 [phi:mul8u_error::@1->print_byte#0] -- register_copy @@ -11826,7 +11831,6 @@ mul8u_error: { jsr print_str //SEG518 mul8u_error::@5 //SEG519 [257] (word) print_word::w#3 ← (word) mul8u_error::ms#0 - // (word) print_word::w#3 = (word) mul8u_error::ms#0 // register copy zp ZP_WORD:8 //SEG520 [258] call print_word //SEG521 [102] phi from mul8u_error::@5 to print_word [phi:mul8u_error::@5->print_word] //SEG522 [102] phi (byte*) print_char_cursor#139 = (byte*) print_char_cursor#132 [phi:mul8u_error::@5->print_word#0] -- register_copy @@ -11893,31 +11897,30 @@ mul8u_error: { str4: .text " / fast:@" } //SEG556 mulf8u +// Fast multiply two unsigned bytes to a word result mulf8u: { .label return = $e //SEG557 [270] (byte) mulf8u_prepare::a#0 ← (byte) mulf8u::a#0 - // (byte) mulf8u_prepare::a#0 = (byte) mulf8u::a#0 // register copy reg byte a //SEG558 [271] call mulf8u_prepare //SEG559 [190] phi from mulf8u to mulf8u_prepare [phi:mulf8u->mulf8u_prepare] //SEG560 [190] phi (byte) mulf8u_prepare::a#2 = (byte) mulf8u_prepare::a#0 [phi:mulf8u->mulf8u_prepare#0] -- register_copy jsr mulf8u_prepare //SEG561 mulf8u::@2 //SEG562 [272] (byte) mulf8u_prepared::b#0 ← (byte) mulf8u::b#0 - // (byte) mulf8u_prepared::b#0 = (byte) mulf8u::b#0 // register copy reg byte x //SEG563 [273] call mulf8u_prepared //SEG564 [185] phi from mulf8u::@2 to mulf8u_prepared [phi:mulf8u::@2->mulf8u_prepared] //SEG565 [185] phi (byte) mulf8u_prepared::b#2 = (byte) mulf8u_prepared::b#0 [phi:mulf8u::@2->mulf8u_prepared#0] -- register_copy jsr mulf8u_prepared //SEG566 [274] (word) mulf8u_prepared::return#2 ← (word) mulf8u_prepared::return#0 - // (word) mulf8u_prepared::return#2 = (word) mulf8u_prepared::return#0 // register copy zp ZP_WORD:14 //SEG567 mulf8u::@3 //SEG568 [275] (word) mulf8u::return#0 ← (word) mulf8u_prepared::return#2 - // (word) mulf8u::return#0 = (word) mulf8u_prepared::return#2 // register copy zp ZP_WORD:14 //SEG569 mulf8u::@return //SEG570 [276] return rts } //SEG571 muls8u +// Slow multiplication of unsigned bytes +// Calculate an unsigned multiplication by repeated addition muls8u: { .label return = 8 .label m = 8 @@ -11967,6 +11970,8 @@ muls8u: { rts } //SEG590 mulf_tables_cmp +// Compare the ASM-based mul tables with the KC-based mul tables +// Red screen on failure - green on success mulf_tables_cmp: { .label asm_sqr = 8 .label kc_sqr = 4 @@ -12010,7 +12015,6 @@ mulf_tables_cmp: { jsr print_str //SEG605 mulf_tables_cmp::@6 //SEG606 [289] (word~) print_word::w#11 ← (word)(byte*) mulf_tables_cmp::asm_sqr#2 - // (word~) print_word::w#11 = (word)(byte*) mulf_tables_cmp::asm_sqr#2 // register copy zp ZP_WORD:8 //SEG607 [290] call print_word //SEG608 [102] phi from mulf_tables_cmp::@6 to print_word [phi:mulf_tables_cmp::@6->print_word] //SEG609 [102] phi (byte*) print_char_cursor#139 = (byte*) print_char_cursor#132 [phi:mulf_tables_cmp::@6->print_word#0] -- register_copy @@ -12110,6 +12114,8 @@ mulf_tables_cmp: { str2: .text "multiply tables match!@" } //SEG648 mulf_init_asm +// Initialize the multiplication tables using ASM code from +// http://codebase64.org/doku.php?id=base:seriously_fast_multiplication mulf_init_asm: { .label mem = $ff //SEG649 asm { ldx#$00 txa .byte$c9 lb1: tya adc#$00 ml1: stamula_sqr1_hi,x tay cmp#$40 txa ror ml9: adc#$00 staml9+1 inx ml0: stamula_sqr1_lo,x bnelb1 incml0+2 incml1+2 clc iny bnelb1 ldx#$00 ldy#$ff !: ldamula_sqr1_hi+1,x stamula_sqr2_hi+$100,x ldamula_sqr1_hi,x stamula_sqr2_hi,y ldamula_sqr1_lo+1,x stamula_sqr2_lo+$100,x ldamula_sqr1_lo,x stamula_sqr2_lo,y dey inx bne!- } @@ -12168,6 +12174,7 @@ mulf_init_asm: { rts } //SEG656 mulf_init +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4) mulf_init: { .label sqr1_hi = 6 .label sqr = 8 @@ -12336,6 +12343,7 @@ mulf_init: { //SEG717 [333] phi (byte) mulf_init::dir#3 = (byte) mulf_init::dir#2 [phi:mulf_init::@12->mulf_init::@4#0] -- register_copy } //SEG718 print_cls +// Clear the screen. Also resets current line/char cursor. print_cls: { .label sc = 4 //SEG719 [341] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1] diff --git a/src/test/ref/typeinference-problem.asm b/src/test/ref/typeinference-problem.asm index cd52f4c1c..b0ce5cdeb 100644 --- a/src/test/ref/typeinference-problem.asm +++ b/src/test/ref/typeinference-problem.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/2) and g(x) = f(1-x) main: { ldx #0 b1: diff --git a/src/test/ref/typeinference-problem.log b/src/test/ref/typeinference-problem.log index b87ee4a03..4ac1bb284 100644 --- a/src/test/ref/typeinference-problem.log +++ b/src/test/ref/typeinference-problem.log @@ -135,6 +135,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/2) and g(x) = f(1-x) main: { .label _0 = 3 .label i = 2 @@ -212,6 +213,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/2) and g(x) = f(1-x) main: { //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] b1_from_main: @@ -305,6 +307,7 @@ Score: 261 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/2) and g(x) = f(1-x) main: { //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] //SEG11 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 diff --git a/src/test/ref/unroll-loop-modifyvar.asm b/src/test/ref/unroll-loop-modifyvar.asm index f0d9ddbae..94baac5de 100644 --- a/src/test/ref/unroll-loop-modifyvar.asm +++ b/src/test/ref/unroll-loop-modifyvar.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// An unrolled loop modifying a var used later main: { .label SCREEN = $400 lda #3 diff --git a/src/test/ref/unroll-loop-modifyvar.log b/src/test/ref/unroll-loop-modifyvar.log index f70a81d2e..cab087f67 100644 --- a/src/test/ref/unroll-loop-modifyvar.log +++ b/src/test/ref/unroll-loop-modifyvar.log @@ -382,6 +382,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// An unrolled loop modifying a var used later main: { .label SCREEN = $400 jmp b1 @@ -507,6 +508,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// An unrolled loop modifying a var used later main: { .label SCREEN = $400 jmp b1 @@ -671,6 +673,7 @@ Score: 78 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// An unrolled loop modifying a var used later main: { .label SCREEN = $400 //SEG10 main::@1 diff --git a/src/test/ref/unroll-screenfill-for-double.asm b/src/test/ref/unroll-screenfill-for-double.asm index 21a688bab..3e2f35b4e 100644 --- a/src/test/ref/unroll-screenfill-for-double.asm +++ b/src/test/ref/unroll-screenfill-for-double.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Fills the screen using two unrolled ranged for()-loops main: { .label SCREEN = $400 lda #0 diff --git a/src/test/ref/unroll-screenfill-for-double.log b/src/test/ref/unroll-screenfill-for-double.log index f6b4f6096..9b2094daa 100644 --- a/src/test/ref/unroll-screenfill-for-double.log +++ b/src/test/ref/unroll-screenfill-for-double.log @@ -1262,6 +1262,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Fills the screen using two unrolled ranged for()-loops main: { .label SCREEN = $400 jmp b2 @@ -2150,6 +2151,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Fills the screen using two unrolled ranged for()-loops main: { .label SCREEN = $400 jmp b2 @@ -3407,6 +3409,7 @@ Score: 512 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Fills the screen using two unrolled ranged for()-loops main: { .label SCREEN = $400 //SEG10 main::@2 diff --git a/src/test/ref/unroll-screenfill-for.asm b/src/test/ref/unroll-screenfill-for.asm index 99cb380d2..184cf280b 100644 --- a/src/test/ref/unroll-screenfill-for.asm +++ b/src/test/ref/unroll-screenfill-for.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Fills the screen using an unrolled inner ranged for()-loop main: { .label SCREEN = $400 ldx #0 diff --git a/src/test/ref/unroll-screenfill-for.log b/src/test/ref/unroll-screenfill-for.log index 1218fa4d4..024681b0f 100644 --- a/src/test/ref/unroll-screenfill-for.log +++ b/src/test/ref/unroll-screenfill-for.log @@ -686,6 +686,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Fills the screen using an unrolled inner ranged for()-loop main: { .label SCREEN = $400 .label x = 2 @@ -925,6 +926,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Fills the screen using an unrolled inner ranged for()-loop main: { .label SCREEN = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] @@ -1240,6 +1242,7 @@ Score: 1841 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Fills the screen using an unrolled inner ranged for()-loop main: { .label SCREEN = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] diff --git a/src/test/ref/unroll-screenfill-while.asm b/src/test/ref/unroll-screenfill-while.asm index a1e8bfef1..b1518f32e 100644 --- a/src/test/ref/unroll-screenfill-while.asm +++ b/src/test/ref/unroll-screenfill-while.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Fills the screen using an unrolled inner while()-loop main: { .label SCREEN = $400 ldx #0 diff --git a/src/test/ref/unroll-screenfill-while.log b/src/test/ref/unroll-screenfill-while.log index 193a660e4..759fb4457 100644 --- a/src/test/ref/unroll-screenfill-while.log +++ b/src/test/ref/unroll-screenfill-while.log @@ -761,6 +761,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Fills the screen using an unrolled inner while()-loop main: { .label SCREEN = $400 .label x = 2 @@ -1000,6 +1001,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Fills the screen using an unrolled inner while()-loop main: { .label SCREEN = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] @@ -1315,6 +1317,7 @@ Score: 1841 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Fills the screen using an unrolled inner while()-loop main: { .label SCREEN = $400 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] diff --git a/src/test/ref/unusedblockproblem.asm b/src/test/ref/unusedblockproblem.asm index fc0bdea06..2b3b3747e 100644 --- a/src/test/ref/unusedblockproblem.asm +++ b/src/test/ref/unusedblockproblem.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Problem with eliminating unused blocks/vars after the infinite loop (symbol line#2 not removed from symbol table) main: { .label SCREEN = $400 b2: diff --git a/src/test/ref/unusedblockproblem.log b/src/test/ref/unusedblockproblem.log index 7cc1a3e50..e879b1acc 100644 --- a/src/test/ref/unusedblockproblem.log +++ b/src/test/ref/unusedblockproblem.log @@ -148,6 +148,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Problem with eliminating unused blocks/vars after the infinite loop (symbol line#2 not removed from symbol table) main: { .label SCREEN = $400 jmp b2 @@ -190,6 +191,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Problem with eliminating unused blocks/vars after the infinite loop (symbol line#2 not removed from symbol table) main: { .label SCREEN = $400 jmp b2 @@ -246,6 +248,7 @@ Score: 90 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Problem with eliminating unused blocks/vars after the infinite loop (symbol line#2 not removed from symbol table) main: { .label SCREEN = $400 //SEG10 main::@2 diff --git a/src/test/ref/var-forward-problem.asm b/src/test/ref/var-forward-problem.asm index 74ab41c70..0b893497e 100644 --- a/src/test/ref/var-forward-problem.asm +++ b/src/test/ref/var-forward-problem.asm @@ -3,6 +3,7 @@ .pc = $80d "Program" .label screen = $400 .const b = 'a' +// Illustrates the problem with variable forward references not working main: { lda #b sta screen diff --git a/src/test/ref/var-forward-problem.log b/src/test/ref/var-forward-problem.log index 0a4ff17b4..75ced20de 100644 --- a/src/test/ref/var-forward-problem.log +++ b/src/test/ref/var-forward-problem.log @@ -97,6 +97,7 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Illustrates the problem with variable forward references not working main: { //SEG9 [4] *((const byte*) screen#0) ← (const byte) b#0 -- _deref_pbuc1=vbuc2 lda #b @@ -141,6 +142,7 @@ bend_from_b1: //SEG7 @end bend: //SEG8 main +// Illustrates the problem with variable forward references not working main: { //SEG9 [4] *((const byte*) screen#0) ← (const byte) b#0 -- _deref_pbuc1=vbuc2 lda #b @@ -200,6 +202,7 @@ Score: 12 //SEG6 [3] phi from @1 to @end [phi:@1->@end] //SEG7 @end //SEG8 main +// Illustrates the problem with variable forward references not working main: { //SEG9 [4] *((const byte*) screen#0) ← (const byte) b#0 -- _deref_pbuc1=vbuc2 lda #b diff --git a/src/test/ref/var-register.log b/src/test/ref/var-register.log index 88afc9566..1e1ffaf16 100644 --- a/src/test/ref/var-register.log +++ b/src/test/ref/var-register.log @@ -474,9 +474,7 @@ main: { clc adc a //SEG26 [9] (byte) print::idx#0 ← (byte) main::y#4 - // (byte) print::idx#0 = (byte) main::y#4 // register copy reg byte x //SEG27 [10] (byte) print::val#0 ← (byte) main::val1#0 - // (byte) print::val#0 = (byte) main::val1#0 // register copy reg byte a //SEG28 [11] call print jsr print jmp b7 @@ -650,9 +648,7 @@ main: { clc adc a //SEG26 [9] (byte) print::idx#0 ← (byte) main::y#4 - // (byte) print::idx#0 = (byte) main::y#4 // register copy reg byte x //SEG27 [10] (byte) print::val#0 ← (byte) main::val1#0 - // (byte) print::val#0 = (byte) main::val1#0 // register copy reg byte a //SEG28 [11] call print jsr print //SEG29 main::@7 diff --git a/src/test/ref/voronoi.log b/src/test/ref/voronoi.log index fb3a055d0..3e151f38e 100644 --- a/src/test/ref/voronoi.log +++ b/src/test/ref/voronoi.log @@ -2023,9 +2023,7 @@ render: { //SEG69 render::@2 b2: //SEG70 [39] (byte) findcol::x#0 ← (byte) render::x#2 - // (byte) findcol::x#0 = (byte) render::x#2 // register copy zp ZP_BYTE:5 //SEG71 [40] (byte) findcol::y#0 ← (byte) render::y#4 - // (byte) findcol::y#0 = (byte) render::y#4 // register copy zp ZP_BYTE:2 //SEG72 [41] call findcol //SEG73 [51] phi from render::@2 to findcol [phi:render::@2->findcol] findcol_from_b2: @@ -2036,7 +2034,6 @@ render: { //SEG75 render::@5 b5: //SEG76 [43] (byte) render::col#0 ← (byte) findcol::return#0 - // (byte) render::col#0 = (byte) findcol::return#0 // register copy reg byte a //SEG77 [44] *((byte*) render::colline#5 + (byte) render::x#2) ← (byte) render::col#0 -- pbuz1_derefidx_vbuz2=vbuaa ldy x sta (colline),y @@ -2332,6 +2329,7 @@ Removing instruction b4_from_b1: Removing instruction b1_from_b3: Removing instruction b2_from_b1: Removing instruction b2_from_b5: +Removing instruction findcol_from_b2: Removing instruction b5_from_b12: Removing instruction b5_from_b4: Removing instruction b7_from_b14: @@ -2350,7 +2348,6 @@ Removing instruction b10: Removing instruction b11: Removing instruction b12: Removing instruction b1_from_render: -Removing instruction findcol_from_b2: Removing instruction b5: Removing instruction b3: Removing instruction breturn: @@ -2672,9 +2669,7 @@ render: { //SEG69 render::@2 b2: //SEG70 [39] (byte) findcol::x#0 ← (byte) render::x#2 - // (byte) findcol::x#0 = (byte) render::x#2 // register copy zp ZP_BYTE:5 //SEG71 [40] (byte) findcol::y#0 ← (byte) render::y#4 - // (byte) findcol::y#0 = (byte) render::y#4 // register copy zp ZP_BYTE:2 //SEG72 [41] call findcol //SEG73 [51] phi from render::@2 to findcol [phi:render::@2->findcol] jsr findcol @@ -2682,7 +2677,6 @@ render: { txa //SEG75 render::@5 //SEG76 [43] (byte) render::col#0 ← (byte) findcol::return#0 - // (byte) render::col#0 = (byte) findcol::return#0 // register copy reg byte a //SEG77 [44] *((byte*) render::colline#5 + (byte) render::x#2) ← (byte) render::col#0 -- pbuz1_derefidx_vbuz2=vbuaa ldy x sta (colline),y diff --git a/src/test/ref/wordexpr.asm b/src/test/ref/wordexpr.asm index d1a2cadd8..a66e99dfa 100644 --- a/src/test/ref/wordexpr.asm +++ b/src/test/ref/wordexpr.asm @@ -1,6 +1,7 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" +// Expressions based on bytes but resulting in words are as words - eg. b = b + 40*8; main: { .label b = 2 ldx #0 diff --git a/src/test/ref/wordexpr.log b/src/test/ref/wordexpr.log index 394aaf19c..28a4405a9 100644 --- a/src/test/ref/wordexpr.log +++ b/src/test/ref/wordexpr.log @@ -148,6 +148,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Expressions based on bytes but resulting in words are as words - eg. b = b + 40*8; main: { .label b = 2 .label i = 4 @@ -227,6 +228,7 @@ bend_from_b1: //SEG8 @end bend: //SEG9 main +// Expressions based on bytes but resulting in words are as words - eg. b = b + 40*8; main: { .label b = 2 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] @@ -328,6 +330,7 @@ Score: 351 //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main +// Expressions based on bytes but resulting in words are as words - eg. b = b + 40*8; main: { .label b = 2 //SEG10 [5] phi from main to main::@1 [phi:main->main::@1] diff --git a/src/test/ref/zpparammin.log b/src/test/ref/zpparammin.log index f865acdde..1692e8bfe 100644 --- a/src/test/ref/zpparammin.log +++ b/src/test/ref/zpparammin.log @@ -619,12 +619,10 @@ main: { //SEG18 [9] call sum jsr sum //SEG19 [10] (byte) sum::return#0 ← (byte) sum::return#1 - // (byte) sum::return#0 = (byte) sum::return#1 // register copy reg byte a jmp b3 //SEG20 main::@3 b3: //SEG21 [11] (byte~) main::$2 ← (byte) sum::return#0 - // (byte~) main::$2 = (byte) sum::return#0 // register copy reg byte a //SEG22 [12] *((const byte*) SCREEN#0 + (byte) main::i#2) ← (byte~) main::$2 -- pbuc1_derefidx_vbuz1=vbuaa ldy i sta SCREEN,y @@ -641,12 +639,10 @@ main: { //SEG26 [16] call sum2 jsr sum2 //SEG27 [17] (byte) sum2::return#0 ← (byte) sum2::return#1 - // (byte) sum2::return#0 = (byte) sum2::return#1 // register copy reg byte a jmp b4 //SEG28 main::@4 b4: //SEG29 [18] (byte~) main::$5 ← (byte) sum2::return#0 - // (byte~) main::$5 = (byte) sum2::return#0 // register copy reg byte a //SEG30 [19] *((const byte*) SCREEN2#0 + (byte) main::i#2) ← (byte~) main::$5 -- pbuc1_derefidx_vbuz1=vbuaa ldy i sta SCREEN2,y @@ -832,10 +828,8 @@ main: { //SEG18 [9] call sum jsr sum //SEG19 [10] (byte) sum::return#0 ← (byte) sum::return#1 - // (byte) sum::return#0 = (byte) sum::return#1 // register copy reg byte a //SEG20 main::@3 //SEG21 [11] (byte~) main::$2 ← (byte) sum::return#0 - // (byte~) main::$2 = (byte) sum::return#0 // register copy reg byte a //SEG22 [12] *((const byte*) SCREEN#0 + (byte) main::i#2) ← (byte~) main::$2 -- pbuc1_derefidx_vbuz1=vbuaa ldy i sta SCREEN,y @@ -851,10 +845,8 @@ main: { //SEG26 [16] call sum2 jsr sum2 //SEG27 [17] (byte) sum2::return#0 ← (byte) sum2::return#1 - // (byte) sum2::return#0 = (byte) sum2::return#1 // register copy reg byte a //SEG28 main::@4 //SEG29 [18] (byte~) main::$5 ← (byte) sum2::return#0 - // (byte~) main::$5 = (byte) sum2::return#0 // register copy reg byte a //SEG30 [19] *((const byte*) SCREEN2#0 + (byte) main::i#2) ← (byte~) main::$5 -- pbuc1_derefidx_vbuz1=vbuaa ldy i sta SCREEN2,y