mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-04-08 14:37:40 +00:00
Now comments on global variables are no longer destroyed. However some comments appear twice!
This commit is contained in:
parent
e09a0718d0
commit
aee57979ef
6532
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
6532
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,7 @@ import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||
import dk.camelot64.kickc.model.values.SymbolRef;
|
||||
import dk.camelot64.kickc.passes.Pass2ConstantIdentification;
|
||||
import dk.camelot64.kickc.passes.utils.ProcedureUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
@ -45,7 +45,7 @@ public class ControlFlowGraph implements Serializable {
|
||||
}
|
||||
|
||||
public List<ControlFlowBlock> getAllBlocks() {
|
||||
return blocks;
|
||||
return blocks;
|
||||
}
|
||||
|
||||
public void setAllBlocks(List<ControlFlowBlock> blocks) {
|
||||
@ -109,8 +109,8 @@ public class ControlFlowGraph implements Serializable {
|
||||
}
|
||||
|
||||
public void setSequence(List<LabelRef> sequence) {
|
||||
if(sequence.size()!=blocks.size()) {
|
||||
throw new CompileError("ERROR! Sequence does not contain all blocks from the program. Sequence: "+sequence.size()+" Blocks: "+blocks.size());
|
||||
if(sequence.size() != blocks.size()) {
|
||||
throw new CompileError("ERROR! Sequence does not contain all blocks from the program. Sequence: " + sequence.size() + " Blocks: " + blocks.size());
|
||||
}
|
||||
this.sequence = sequence;
|
||||
ArrayList<ControlFlowBlock> seqBlocks = new ArrayList<>();
|
||||
@ -144,29 +144,26 @@ public class ControlFlowGraph implements Serializable {
|
||||
/**
|
||||
* Get all blocks that are program entry points.
|
||||
* This is the start-block and any blocks referenced by the address-off operator (&)
|
||||
*
|
||||
* @param program The program
|
||||
* @return All entry-point blocks
|
||||
*/
|
||||
public List<ControlFlowBlock> getEntryPointBlocks(Program program) {
|
||||
List<ControlFlowBlock> entryPointBlocks = new ArrayList<>();
|
||||
for(Procedure procedure : program.getScope().getAllProcedures(true)) {
|
||||
if(Pass2ConstantIdentification.isAddressOfUsed(procedure.getRef(), program) || Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
|
||||
if(ProcedureUtils.isEntrypoint(procedure.getRef(), program) || Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
|
||||
// Address-of is used on the procedure
|
||||
Label procedureLabel = procedure.getLabel();
|
||||
ControlFlowBlock procedureBlock = getBlock(procedureLabel.getRef());
|
||||
entryPointBlocks.add(procedureBlock);
|
||||
}
|
||||
}
|
||||
final ProcedureRef startProcedure = program.getStartProcedure();
|
||||
final ControlFlowBlock startBlock = getBlock(startProcedure.getLabelRef());
|
||||
if(startBlock != null && !entryPointBlocks.contains(startBlock)) {
|
||||
entryPointBlocks.add(startBlock);
|
||||
}
|
||||
return entryPointBlocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all called procedures in the graph
|
||||
*
|
||||
* @return All called procedures
|
||||
*/
|
||||
public Set<ProcedureRef> getAllCalledProcedures() {
|
||||
@ -219,7 +216,7 @@ public class ControlFlowGraph implements Serializable {
|
||||
public Statement getStatementByIndex(int statementIdx) {
|
||||
for(ControlFlowBlock block : getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
if(statement.getIndex()!=null && statementIdx == statement.getIndex()) {
|
||||
if(statement.getIndex() != null && statementIdx == statement.getIndex()) {
|
||||
return statement;
|
||||
}
|
||||
}
|
||||
@ -245,20 +242,22 @@ public class ControlFlowGraph implements Serializable {
|
||||
|
||||
/**
|
||||
* Get information about the size of the program
|
||||
*
|
||||
* @return Size information
|
||||
*/
|
||||
public String getSizeInfo() {
|
||||
StringBuilder sizeInfo = new StringBuilder();
|
||||
sizeInfo.append("SIZE blocks "+ getAllBlocks().size()).append("\n");
|
||||
sizeInfo.append("SIZE blocks " + getAllBlocks().size()).append("\n");
|
||||
int numStmt = getAllBlocks().stream().mapToInt(block -> block.getStatements().size()).sum();
|
||||
sizeInfo.append("SIZE statements "+ numStmt).append("\n");
|
||||
int numPhiVars = getAllBlocks().stream().mapToInt(value -> value.getStatements().stream().mapToInt(value1 -> (value1 instanceof StatementPhiBlock)?((StatementPhiBlock) value1).getPhiVariables().size():0).sum()).sum();
|
||||
sizeInfo.append("SIZE phi variables "+ numPhiVars).append("\n");
|
||||
sizeInfo.append("SIZE statements " + numStmt).append("\n");
|
||||
int numPhiVars = getAllBlocks().stream().mapToInt(value -> value.getStatements().stream().mapToInt(value1 -> (value1 instanceof StatementPhiBlock) ? ((StatementPhiBlock) value1).getPhiVariables().size() : 0).sum()).sum();
|
||||
sizeInfo.append("SIZE phi variables " + numPhiVars).append("\n");
|
||||
return sizeInfo.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all statements executed between two statements (none of these are included in the result)
|
||||
*
|
||||
* @param from The statement to start at
|
||||
* @param to The statement to end at
|
||||
* @return All statements executed between the two passed statements
|
||||
@ -272,6 +271,7 @@ public class ControlFlowGraph implements Serializable {
|
||||
|
||||
/**
|
||||
* Fill the between collection with all statements executed between two statements (none of these are included in the result)
|
||||
*
|
||||
* @param from The statement to start at
|
||||
* @param to The statement to end at
|
||||
* @param between The between collection
|
||||
|
@ -985,8 +985,11 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
// Add comments to constant
|
||||
variable.setComments(ensureUnusedComments(declComments));
|
||||
} else if(!variable.isKindConstant() && !isStructMember) {
|
||||
Statement initStmt = new StatementAssignment(variable.getVariableRef(), initValue, true, statementSource, ensureUnusedComments(declComments));
|
||||
final List<Comment> comments = ensureUnusedComments(declComments);
|
||||
Statement initStmt = new StatementAssignment(variable.getVariableRef(), initValue, true, statementSource, comments);
|
||||
addStatement(initStmt);
|
||||
// Add comments to variable
|
||||
variable.setComments(comments);
|
||||
}
|
||||
if(initializer != null)
|
||||
PrePostModifierHandler.addPostModifiers(this, initializer, statementSource);
|
||||
|
@ -4,6 +4,7 @@ import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||
import dk.camelot64.kickc.passes.utils.ProcedureUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
@ -20,17 +21,15 @@ public class Pass1EliminateUncalledProcedures extends Pass1Base {
|
||||
@Override
|
||||
public boolean step() {
|
||||
Set<ProcedureRef> calledProcedures = getGraph().getAllCalledProcedures();
|
||||
calledProcedures.add(getProgram().getStartProcedure());
|
||||
//calledProcedures.add(getProgram().getStartProcedure());
|
||||
|
||||
Set<ProcedureRef> unusedProcedures = new LinkedHashSet<>();
|
||||
Collection<Procedure> allProcedures = getProgram().getScope().getAllProcedures(true);
|
||||
for(Procedure procedure : allProcedures) {
|
||||
// TODO Also look at kickasm/asm uses! (Maybe also look at some directive like "export" )
|
||||
if(!calledProcedures.contains(procedure.getRef()) && !Pass2ConstantIdentification.isAddressOfUsed(procedure.getRef(), getProgram())) {
|
||||
// The procedure is not used - mark for removal!
|
||||
unusedProcedures.add(procedure.getRef());
|
||||
}
|
||||
}
|
||||
for(Procedure procedure : allProcedures)
|
||||
if(!ProcedureUtils.isEntrypoint(procedure.getRef(), getProgram()))
|
||||
if(!calledProcedures.contains(procedure.getRef()))
|
||||
// The procedure is not used - mark for removal!
|
||||
unusedProcedures.add(procedure.getRef());
|
||||
|
||||
for(ProcedureRef unusedProcedure : unusedProcedures) {
|
||||
removeProcedure(getProgram(), unusedProcedure);
|
||||
@ -41,6 +40,7 @@ public class Pass1EliminateUncalledProcedures extends Pass1Base {
|
||||
|
||||
/**
|
||||
* Removed a procedure from the program (the symbol in the symbol table and all blocks in the control flow graph)
|
||||
*
|
||||
* @param program The program
|
||||
* @param procedureRef The procedure to be removed
|
||||
*/
|
||||
|
@ -258,7 +258,6 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
|
||||
if(symbol instanceof Procedure) {
|
||||
Procedure procedure = (Procedure) symbol;
|
||||
if(procedure.getInterruptType() != null || Pass2ConstantIdentification.isAddressOfUsed(procedure.getRef(), program)) {
|
||||
final ControlFlowBlock startBlock = program.getGraph().getBlock(program.getStartProcedure().getLabelRef());
|
||||
// Find all root-level predecessors to the main block
|
||||
ControlFlowBlock mainBlock = program.getGraph().getBlock(new LabelRef(SymbolRef.MAIN_PROC_NAME));
|
||||
List<ControlFlowBlock> mainPredecessors = program.getGraph().getPredecessors(mainBlock);
|
||||
|
@ -87,7 +87,6 @@ public class Pass4CodeGeneration {
|
||||
linkScriptBody = linkScriptBody.replace("%_O", outputFileName.toLowerCase());
|
||||
linkScriptBody = linkScriptBody.replace("%^O", outputFileName.toUpperCase());
|
||||
String entryName = program.getStartProcedure().getFullName();
|
||||
;
|
||||
linkScriptBody = linkScriptBody.replace("%E", entryName);
|
||||
Number programPc = program.getProgramPc();
|
||||
if(programPc == null) programPc = 0x080d;
|
||||
|
@ -7,6 +7,7 @@ import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||
import dk.camelot64.kickc.model.values.SymbolRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.passes.utils.ProcedureUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@ -32,22 +33,9 @@ public abstract class Pass4MemoryCoalesce extends Pass2Base {
|
||||
public static Collection<ScopeRef> getThreadHeads(Program program) {
|
||||
ArrayList<ScopeRef> threadHeads = new ArrayList<>();
|
||||
Collection<Procedure> procedures = program.getScope().getAllProcedures(true);
|
||||
for(Procedure procedure : procedures) {
|
||||
if(procedure.getRef().equals(program.getStartProcedure())) {
|
||||
// TODO: Handles main() correctly?
|
||||
for(Procedure procedure : procedures)
|
||||
if(ProcedureUtils.isEntrypoint(procedure.getRef(), program))
|
||||
threadHeads.add(procedure.getRef());
|
||||
continue;
|
||||
}
|
||||
if(Pass2ConstantIdentification.isAddressOfUsed(procedure.getRef(), program)) {
|
||||
threadHeads.add(procedure.getRef());
|
||||
continue;
|
||||
}
|
||||
if(procedure.getInterruptType()!=null) {
|
||||
// TODO: Handles Interrupts correctly?
|
||||
threadHeads.add(procedure.getRef());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return threadHeads;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.Symbol;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||
import dk.camelot64.kickc.model.values.SymbolRef;
|
||||
import dk.camelot64.kickc.model.values.SymbolVariableRef;
|
||||
|
||||
import java.util.Collection;
|
||||
@ -30,7 +31,8 @@ public class PassNEliminateEmptyProcedure extends Pass2SsaOptimization {
|
||||
boolean optimized = false;
|
||||
for(Procedure procedure : allProcedures) {
|
||||
if(hasEmptyBody(procedure.getRef())) {
|
||||
if(!hasExternalUsages(procedure.getRef(), getProgram())) {
|
||||
if(!hasExternalUsages(procedure.getRef(), getProgram()) && !SymbolRef.MAIN_PROC_NAME.equals(procedure.getLabel().getLocalName())) {
|
||||
// TODO: Entry point procedures include isAddressOfUsed!
|
||||
// Remove all calls
|
||||
removeAllCalls(procedure.getRef());
|
||||
// Remove the procedure
|
||||
|
@ -11,6 +11,7 @@ import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.passes.Pass2AliasElimination;
|
||||
import dk.camelot64.kickc.passes.Pass2ConstantIdentification;
|
||||
import dk.camelot64.kickc.passes.utils.ProcedureUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -69,8 +70,7 @@ public class PassNCalcLiveRangesEffectiveCallPaths extends PassNCalcBase<LiveRan
|
||||
LiveRangeVariablesEffectiveCallPaths.CallPaths callPaths = procedureCallPaths.get(procedureRef);
|
||||
if(callPaths == null) {
|
||||
callPaths = new LiveRangeVariablesEffectiveCallPaths.CallPaths(procedureRef);
|
||||
|
||||
if(procedure.getInterruptType()!=null || Pass2ConstantIdentification.isAddressOfUsed(procedureRef, getProgram()) || procedureRef.equals(getProgram().getStartProcedure())) {
|
||||
if(ProcedureUtils.isEntrypoint(procedureRef, getProgram())) {
|
||||
// Interrupt is called outside procedure scope - create initial call-path.
|
||||
ArrayList<CallGraph.CallBlock.Call> rootPath = new ArrayList<>();
|
||||
ArrayList<VariableRef> rootAlive = new ArrayList<>();
|
||||
|
@ -0,0 +1,34 @@
|
||||
package dk.camelot64.kickc.passes.utils;
|
||||
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||
import dk.camelot64.kickc.passes.Pass2ConstantIdentification;
|
||||
|
||||
public class ProcedureUtils {
|
||||
|
||||
/**
|
||||
* Determines if a procedure is an entry point.
|
||||
* Entry points are:
|
||||
* - the starting procedure (typically main())
|
||||
* - interrupts
|
||||
* - any procedure where address-of is used in the code.
|
||||
* TODO: Should all stack call procedures be included (probably no!)
|
||||
* TODO: Also look at kickasm/asm uses! (Maybe also look at some directive like "export" )
|
||||
*
|
||||
* @param procedure The procedure to examine
|
||||
* @param program The program
|
||||
* @return true if the procedure is an entry point
|
||||
*/
|
||||
public static boolean isEntrypoint(ProcedureRef procedureRef, Program program) {
|
||||
if(procedureRef.equals(program.getStartProcedure()))
|
||||
return true;
|
||||
final Procedure procedure = program.getScope().getProcedure(procedureRef);
|
||||
if(procedure.getInterruptType()!=null)
|
||||
return true;
|
||||
if(Pass2ConstantIdentification.isAddressOfUsed(procedureRef, program))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -42,6 +42,21 @@ public class TestPrograms {
|
||||
public TestPrograms() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyFunction2() throws IOException, URISyntaxException {
|
||||
compileAndCompare("empty-function-2.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyFunction1() throws IOException, URISyntaxException {
|
||||
compileAndCompare("empty-function-1.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyFunction0() throws IOException, URISyntaxException {
|
||||
compileAndCompare("empty-function-0.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStaticInitCode2() throws IOException, URISyntaxException {
|
||||
compileAndCompare("static-init-code-2.c");
|
||||
@ -1240,7 +1255,7 @@ public class TestPrograms {
|
||||
|
||||
@Test
|
||||
public void testInnerIncrementProblem() throws IOException, URISyntaxException {
|
||||
compileAndCompare("inner-increment-problem.c");
|
||||
compileAndCompare("inner-increment-problem.c", log());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -3045,6 +3060,11 @@ public class TestPrograms {
|
||||
compileAndCompare("string-const-consolidation.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommentsGlobalInit() throws IOException, URISyntaxException {
|
||||
compileAndCompare("test-comments-global.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommentsBlock() throws IOException, URISyntaxException {
|
||||
compileAndCompare("test-comments-block.c");
|
||||
|
14
src/test/kc/empty-function-0.c
Normal file
14
src/test/kc/empty-function-0.c
Normal file
@ -0,0 +1,14 @@
|
||||
// Test removal of empty function
|
||||
|
||||
char v;
|
||||
|
||||
char * const SCREEN = 0x0400;
|
||||
|
||||
void main() {
|
||||
set();
|
||||
SCREEN[0] = v;
|
||||
}
|
||||
|
||||
void set() {
|
||||
v = 7;
|
||||
}
|
11
src/test/kc/empty-function-1.c
Normal file
11
src/test/kc/empty-function-1.c
Normal file
@ -0,0 +1,11 @@
|
||||
// Test removal of empty function
|
||||
|
||||
char * const SCREEN = 0x0400;
|
||||
|
||||
void main() {
|
||||
empty();
|
||||
SCREEN[0] = 'x';
|
||||
}
|
||||
|
||||
void empty() {
|
||||
}
|
9
src/test/kc/empty-function-2.c
Normal file
9
src/test/kc/empty-function-2.c
Normal file
@ -0,0 +1,9 @@
|
||||
// Test removal of empty function
|
||||
// main() should not be removed!
|
||||
|
||||
void main() {
|
||||
empty();
|
||||
}
|
||||
|
||||
void empty() {
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
char *fileCur;
|
||||
char *fileTop;
|
||||
char *filesEnd;
|
||||
char *file;
|
||||
char *fileCur = 0x1005;
|
||||
char *fileTop = 0x1010;
|
||||
char *filesEnd = 0x1010;
|
||||
char *file = 0x1000;
|
||||
|
||||
char * const SCREEN = 0x0400;
|
||||
|
||||
void main(void) {
|
||||
if (fileTop == filesEnd) --fileTop;
|
||||
if (file <= fileCur) --fileCur;
|
||||
if (fileCur < fileTop) fileCur = fileTop;
|
||||
|
||||
SCREEN[0] = *fileCur;
|
||||
}
|
||||
|
13
src/test/kc/test-comments-global.c
Normal file
13
src/test/kc/test-comments-global.c
Normal file
@ -0,0 +1,13 @@
|
||||
// Tests that global variables with initializer gets their comments
|
||||
|
||||
// The screen (should become a var-comment in ASM)
|
||||
__ma char * screen = 0x0400;
|
||||
|
||||
// The program entry point
|
||||
void main() {
|
||||
// Put 'a' in screen
|
||||
*screen = 'a';
|
||||
screen++;
|
||||
// Put another 'a' in screen
|
||||
*screen = 'a';
|
||||
}
|
@ -1,16 +1,17 @@
|
||||
// Test that address vars are turned into load/store and located at hardcoded addresses
|
||||
// Hard-coded mainmem-page address - global variable
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
.label i = $2000
|
||||
__bbegin:
|
||||
// i = 3
|
||||
lda #3
|
||||
sta i
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// i = 3
|
||||
lda #3
|
||||
sta i
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
__b1:
|
||||
// while(i<7)
|
||||
|
@ -1,16 +1,17 @@
|
||||
// Test declaring a variable as at a hard-coded address
|
||||
// zero-page hard-coded address parameter
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
.label idx = 3
|
||||
__bbegin:
|
||||
// idx
|
||||
lda #0
|
||||
sta.z idx
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// idx
|
||||
lda #0
|
||||
sta.z idx
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// print('c')
|
||||
lda #'c'
|
||||
|
@ -1,16 +1,17 @@
|
||||
// Test declaring a variable as at a hard-coded address
|
||||
// mainmem-page hard-coded address parameter
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
.label idx = $3000
|
||||
__bbegin:
|
||||
// idx
|
||||
lda #0
|
||||
sta idx
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// idx
|
||||
lda #0
|
||||
sta idx
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// print('c')
|
||||
lda #'c'
|
||||
|
@ -1,18 +1,20 @@
|
||||
// Test address-of by assigning the affected variable in multiple ways
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.label val = 2
|
||||
__bbegin:
|
||||
// val = 0
|
||||
lda #0
|
||||
sta.z val
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// val = 0
|
||||
lda #0
|
||||
sta.z val
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.label SCREEN1 = $400
|
||||
.label SCREEN2 = SCREEN1+$28
|
||||
// Use address-of - hereafter all versions of val must be in the same memory
|
||||
// Use address-of - hereafter all versions of val must be in the same memory
|
||||
.label ptr = val
|
||||
// SCREEN1[idx] = val
|
||||
lda.z val
|
||||
|
18
src/test/ref/arrays-init-kasm-1.asm
Normal file
18
src/test/ref/arrays-init-kasm-1.asm
Normal file
@ -0,0 +1,18 @@
|
||||
// Test initializing array using KickAssembler
|
||||
// Place array at hardcoded address
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
main: {
|
||||
// SCREEN[0] = SINTAB[0]
|
||||
lda SINTAB
|
||||
sta SCREEN
|
||||
// }
|
||||
rts
|
||||
}
|
||||
.pc = $1000 "SINTAB"
|
||||
// Sinus table at an absolute address in memory
|
||||
SINTAB:
|
||||
.fill 256, 128 + 128*sin(i*2*PI/256)
|
||||
|
@ -3,12 +3,6 @@
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.label BG_COLOR = $d020
|
||||
main: {
|
||||
// asm
|
||||
jsr init
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Function only used inside the inline asm
|
||||
init: {
|
||||
// *BG_COLOR = 0
|
||||
@ -17,3 +11,9 @@ init: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// asm
|
||||
jsr init
|
||||
// }
|
||||
rts
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Test atoi()
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.const LIGHT_BLUE = $e
|
||||
.const OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS = 1
|
||||
@ -9,33 +9,34 @@
|
||||
.label COLORRAM = $d800
|
||||
// Default address of screen character matrix
|
||||
.label DEFAULT_SCREEN = $400
|
||||
.label conio_cursor_x = 9
|
||||
.label conio_cursor_y = $a
|
||||
.label conio_line_text = $b
|
||||
.label conio_line_color = $d
|
||||
__bbegin:
|
||||
// conio_cursor_x = 0
|
||||
// The number of bytes on the screen
|
||||
// The current cursor x-position
|
||||
lda #0
|
||||
sta.z conio_cursor_x
|
||||
// conio_cursor_y = 0
|
||||
.label conio_cursor_x = 9
|
||||
// The current cursor y-position
|
||||
sta.z conio_cursor_y
|
||||
// conio_line_text = CONIO_SCREEN_TEXT
|
||||
.label conio_cursor_y = $a
|
||||
// The current text cursor line start
|
||||
lda #<DEFAULT_SCREEN
|
||||
sta.z conio_line_text
|
||||
lda #>DEFAULT_SCREEN
|
||||
sta.z conio_line_text+1
|
||||
// conio_line_color = CONIO_SCREEN_COLORS
|
||||
.label conio_line_text = $b
|
||||
// The current color cursor line start
|
||||
lda #<COLORRAM
|
||||
sta.z conio_line_color
|
||||
lda #>COLORRAM
|
||||
sta.z conio_line_color+1
|
||||
jsr main
|
||||
rts
|
||||
.label conio_line_color = $d
|
||||
_start: {
|
||||
// conio_cursor_x = 0
|
||||
lda #0
|
||||
sta.z conio_cursor_x
|
||||
// conio_cursor_y = 0
|
||||
sta.z conio_cursor_y
|
||||
// conio_line_text = CONIO_SCREEN_TEXT
|
||||
lda #<DEFAULT_SCREEN
|
||||
sta.z conio_line_text
|
||||
lda #>DEFAULT_SCREEN
|
||||
sta.z conio_line_text+1
|
||||
// conio_line_color = CONIO_SCREEN_COLORS
|
||||
lda #<COLORRAM
|
||||
sta.z conio_line_color
|
||||
lda #>COLORRAM
|
||||
sta.z conio_line_color+1
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// clrscr()
|
||||
jsr clrscr
|
||||
|
@ -12,7 +12,7 @@
|
||||
.label VIC_MEMORY = $d018
|
||||
.label SCREEN = $400
|
||||
.label BITMAP = $2000
|
||||
.label next = 2
|
||||
.label next = 5
|
||||
main: {
|
||||
// *BORDER_COLOR = 0
|
||||
lda #0
|
||||
@ -89,13 +89,13 @@ bitmap_line: {
|
||||
jsr bitmap_line_xdyi
|
||||
rts
|
||||
}
|
||||
// bitmap_line_xdyi(byte zp(3) x, byte zp(4) y, byte zp($b) x1, byte zp(6) xd)
|
||||
// bitmap_line_xdyi(byte zp(2) x, byte zp(3) y, byte zp(6) x1, byte zp($b) xd)
|
||||
bitmap_line_xdyi: {
|
||||
.label x1 = $b
|
||||
.label xd = 6
|
||||
.label x = 3
|
||||
.label e = 5
|
||||
.label y = 4
|
||||
.label x1 = 6
|
||||
.label xd = $b
|
||||
.label x = 2
|
||||
.label e = 4
|
||||
.label y = 3
|
||||
lda #bitmap_line.y1>>1
|
||||
sta.z e
|
||||
lda #bitmap_line.y0
|
||||
@ -136,6 +136,7 @@ bitmap_line_xdyi: {
|
||||
}
|
||||
// bitmap_plot(byte register(X) x, byte register(Y) y)
|
||||
bitmap_plot: {
|
||||
// Needs unsigned int arrays arranged as two underlying char arrays to allow char* plotter_x = plot_x[x]; - and eventually - char* plotter = plot_x[x] + plot_y[y];
|
||||
.label plotter_x = 7
|
||||
.label plotter_y = 9
|
||||
.label plotter = 7
|
||||
@ -166,12 +167,12 @@ bitmap_plot: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// bitmap_line_ydxi(byte zp(4) y, byte zp(3) x, byte zp(6) xd)
|
||||
// bitmap_line_ydxi(byte zp(3) y, byte zp(2) x, byte zp(6) xd)
|
||||
bitmap_line_ydxi: {
|
||||
.label xd = 6
|
||||
.label e = 5
|
||||
.label y = 4
|
||||
.label x = 3
|
||||
.label e = 4
|
||||
.label y = 3
|
||||
.label x = 2
|
||||
// e = xd>>1
|
||||
lda.z xd
|
||||
lsr
|
||||
@ -210,12 +211,12 @@ bitmap_line_ydxi: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// bitmap_line_xdyd(byte zp(3) x, byte zp(4) y, byte zp(6) xd)
|
||||
// bitmap_line_xdyd(byte zp(2) x, byte zp(3) y, byte zp(6) xd)
|
||||
bitmap_line_xdyd: {
|
||||
.label x = 3
|
||||
.label x = 2
|
||||
.label xd = 6
|
||||
.label e = 5
|
||||
.label y = 4
|
||||
.label e = 4
|
||||
.label y = 3
|
||||
lda #bitmap_line.y1>>1
|
||||
sta.z e
|
||||
lda #bitmap_line.y1
|
||||
@ -250,12 +251,12 @@ bitmap_line_xdyd: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// bitmap_line_ydxd(byte zp(4) y, byte zp(3) x, byte zp(6) xd)
|
||||
// bitmap_line_ydxd(byte zp(3) y, byte zp(2) x, byte zp(6) xd)
|
||||
bitmap_line_ydxd: {
|
||||
.label xd = 6
|
||||
.label e = 5
|
||||
.label y = 4
|
||||
.label x = 3
|
||||
.label e = 4
|
||||
.label y = 3
|
||||
.label x = 2
|
||||
// e = xd>>1
|
||||
lda.z xd
|
||||
lsr
|
||||
@ -325,7 +326,7 @@ init_screen: {
|
||||
// Clear all graphics on the bitmap
|
||||
bitmap_clear: {
|
||||
.label bitmap = 7
|
||||
.label y = 6
|
||||
.label y = 5
|
||||
// bitmap = (char*) { bitmap_plot_xhi[0], bitmap_plot_xlo[0] }
|
||||
lda bitmap_plot_xlo
|
||||
sta.z bitmap
|
||||
|
@ -14,7 +14,7 @@
|
||||
.label VIC_MEMORY = $d018
|
||||
.label SCREEN = $400
|
||||
.label BITMAP = $2000
|
||||
.label next = 2
|
||||
.label next = $a
|
||||
main: {
|
||||
// *BORDER_COLOR = 0
|
||||
lda #0
|
||||
@ -55,7 +55,7 @@ main: {
|
||||
jmp __b1
|
||||
}
|
||||
// Draw a line on the bitmap using bresenhams algorithm
|
||||
// bitmap_line(word zp(2) x2)
|
||||
// bitmap_line(word zp($a) x2)
|
||||
bitmap_line: {
|
||||
.const x1 = 0
|
||||
.const y1 = 0
|
||||
@ -64,11 +64,13 @@ bitmap_line: {
|
||||
.label dy = 8
|
||||
.label sx = $12
|
||||
.label sy = 6
|
||||
// X is the driver
|
||||
.label e1 = 4
|
||||
.label e = $a
|
||||
.label y = $e
|
||||
.label x = $c
|
||||
.label x2 = 2
|
||||
// Y is the driver
|
||||
.label e = $c
|
||||
.label y = 2
|
||||
.label x = $e
|
||||
.label x2 = $a
|
||||
// abs_u16(x2-x1)
|
||||
lda.z x2
|
||||
sta.z abs_u16.w
|
||||
@ -287,11 +289,11 @@ bitmap_line: {
|
||||
rts
|
||||
}
|
||||
// Plot a single dot in the bitmap
|
||||
// bitmap_plot(word zp($c) x, byte register(X) y)
|
||||
// bitmap_plot(word zp($e) x, byte register(X) y)
|
||||
bitmap_plot: {
|
||||
.label __0 = $16
|
||||
.label plotter = $14
|
||||
.label x = $c
|
||||
.label x = $e
|
||||
// plotter = (char*) { bitmap_plot_yhi[y], bitmap_plot_ylo[y] }
|
||||
lda bitmap_plot_yhi,x
|
||||
sta.z plotter+1
|
||||
|
@ -4,7 +4,7 @@
|
||||
// The MOS 6526 Complex Interface Adapter (CIA)
|
||||
// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
|
||||
.const CIA_INTERRUPT_CLEAR = $7f
|
||||
@ -40,14 +40,15 @@
|
||||
.label HARDWARE_IRQ = $fffe
|
||||
.label BITMAP = $2000
|
||||
.label SCREEN = $400
|
||||
.label frame_cnt = 8
|
||||
__bbegin:
|
||||
// frame_cnt = 1
|
||||
// Counts frames - updated by the IRQ
|
||||
lda #1
|
||||
sta.z frame_cnt
|
||||
jsr main
|
||||
rts
|
||||
.label frame_cnt = 8
|
||||
_start: {
|
||||
// frame_cnt = 1
|
||||
lda #1
|
||||
sta.z frame_cnt
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.const toD0181_return = (>(SCREEN&$3fff)*4)|(>BITMAP)/4&$f
|
||||
.label x = 2
|
||||
|
@ -4,7 +4,7 @@
|
||||
// The MOS 6526 Complex Interface Adapter (CIA)
|
||||
// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
|
||||
.const CIA_INTERRUPT_CLEAR = $7f
|
||||
@ -47,16 +47,17 @@
|
||||
.label HARDWARE_IRQ = $fffe
|
||||
.label BITMAP = $2000
|
||||
.label SCREEN = $400
|
||||
// Counts frames - updated by the IRQ
|
||||
.label frame_cnt = $16
|
||||
// Remainder after unsigned 16-bit division
|
||||
.label rem16u = $14
|
||||
__bbegin:
|
||||
// frame_cnt = 1
|
||||
// Counts frames - updated by the IRQ
|
||||
lda #1
|
||||
sta.z frame_cnt
|
||||
jsr main
|
||||
rts
|
||||
.label rem16u = $2e
|
||||
_start: {
|
||||
// frame_cnt = 1
|
||||
lda #1
|
||||
sta.z frame_cnt
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.const toD0181_return = (>(SCREEN&$3fff)*4)|(>BITMAP)/4&$f
|
||||
.label __6 = 8
|
||||
@ -596,10 +597,14 @@ sin16s_gen2: {
|
||||
.label wavelength = $200
|
||||
.label __6 = 8
|
||||
.label __8 = $24
|
||||
// ampl is always positive so shifting left does not alter the sign
|
||||
// u[4.28] step = PI*2/wavelength
|
||||
.label step = $20
|
||||
.label sintab = $19
|
||||
// u[4.28]
|
||||
// Iterate over the table
|
||||
// u[4.28]
|
||||
// Iterate over the table
|
||||
.label x = $c
|
||||
.label i = $17
|
||||
// div32u16u(PI2_u4f28, wavelength)
|
||||
@ -700,14 +705,23 @@ sin16s: {
|
||||
.label __4 = $26
|
||||
.label x = $10
|
||||
.label return = $1b
|
||||
// sinx = x - x^3/6 + x5/128;
|
||||
.label x1 = $2a
|
||||
// u[1.15]
|
||||
.label x2 = $14
|
||||
// u[2.14] x^2
|
||||
.label x3 = $14
|
||||
// u[2.14] x^3
|
||||
.label x3_6 = $2c
|
||||
// u[1.15] x^3/6;
|
||||
.label usinx = $1b
|
||||
// u[1.15] x - x^3/6
|
||||
.label x4 = $14
|
||||
// u[3.13] x^4
|
||||
.label x5 = $2c
|
||||
// u[4.12] x^5
|
||||
.label x5_128 = $2c
|
||||
// u[1.15] (first bit is always zero)
|
||||
.label sinx = $1b
|
||||
// if(x >= PI_u4f28 )
|
||||
lda.z x+3
|
||||
@ -962,6 +976,10 @@ div32u16u: {
|
||||
lda.z divr16u.return+1
|
||||
sta.z quotient_hi+1
|
||||
// divr16u(<dividend, divisor, rem16u)
|
||||
lda.z rem16u
|
||||
sta.z divr16u.rem
|
||||
lda.z rem16u+1
|
||||
sta.z divr16u.rem+1
|
||||
lda #<PI2_u4f28&$ffff
|
||||
sta.z divr16u.dividend
|
||||
lda #>PI2_u4f28&$ffff
|
||||
@ -1045,6 +1063,10 @@ divr16u: {
|
||||
cpx #$10
|
||||
bne __b1
|
||||
// rem16u = rem
|
||||
lda.z rem
|
||||
sta.z rem16u
|
||||
lda.z rem+1
|
||||
sta.z rem16u+1
|
||||
// }
|
||||
rts
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
// The MOS 6526 Complex Interface Adapter (CIA)
|
||||
// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
|
||||
.const CIA_INTERRUPT_CLEAR = $7f
|
||||
@ -48,30 +48,31 @@
|
||||
.label HARDWARE_IRQ = $fffe
|
||||
.label BITMAP = $2000
|
||||
.label SCREEN = $400
|
||||
.label frame_cnt = $1b
|
||||
// Remainder after unsigned 16-bit division
|
||||
.label rem16u = $19
|
||||
__bbegin:
|
||||
// frame_cnt = 1
|
||||
// Counts frames - updated by the IRQ
|
||||
lda #1
|
||||
sta.z frame_cnt
|
||||
jsr main
|
||||
rts
|
||||
.label frame_cnt = $19
|
||||
// Remainder after unsigned 16-bit division
|
||||
.label rem16u = $2f
|
||||
_start: {
|
||||
// frame_cnt = 1
|
||||
lda #1
|
||||
sta.z frame_cnt
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.const toD0181_return = (>(SCREEN&$3fff)*4)|(>BITMAP)/4&$f
|
||||
.label __7 = $1c
|
||||
.label __11 = $1e
|
||||
.label __7 = $1a
|
||||
.label __11 = $1c
|
||||
.label __26 = 9
|
||||
.label __27 = 9
|
||||
.label __28 = $1c
|
||||
.label __29 = $1e
|
||||
.label __28 = $1a
|
||||
.label __29 = $1c
|
||||
.label cos_x = 9
|
||||
.label xpos = $b
|
||||
.label x = $1c
|
||||
.label x = $1a
|
||||
.label sin_y = 9
|
||||
.label ypos = $b
|
||||
.label y = $1e
|
||||
.label y = $1c
|
||||
.label idx_x = 2
|
||||
.label idx_y = 6
|
||||
.label r = 4
|
||||
@ -283,11 +284,11 @@ main: {
|
||||
jmp __b7
|
||||
}
|
||||
// Plot a single dot in the bitmap
|
||||
// bitmap_plot(word zp($1c) x, byte register(A) y)
|
||||
// bitmap_plot(word zp($1a) x, byte register(A) y)
|
||||
bitmap_plot: {
|
||||
.label __0 = $2b
|
||||
.label __0 = $1e
|
||||
.label plotter = $25
|
||||
.label x = $1c
|
||||
.label x = $1a
|
||||
// plotter = (char*) { bitmap_plot_yhi[y], bitmap_plot_ylo[y] }
|
||||
tay
|
||||
lda bitmap_plot_yhi,y
|
||||
@ -323,9 +324,9 @@ bitmap_plot: {
|
||||
// Fixes offsets introduced by using unsigned multiplication
|
||||
// mul16s(signed word zp(4) a, signed word zp(9) b)
|
||||
mul16s: {
|
||||
.label __6 = $2b
|
||||
.label __6 = $1e
|
||||
.label __9 = $25
|
||||
.label __11 = $2b
|
||||
.label __11 = $1e
|
||||
.label __12 = $25
|
||||
.label m = $b
|
||||
.label return = $b
|
||||
@ -390,12 +391,12 @@ mul16s: {
|
||||
rts
|
||||
}
|
||||
// Perform binary multiplication of two unsigned 16-bit unsigned ints into a 32-bit unsigned long
|
||||
// mul16u(word zp($25) a, word zp($1e) b)
|
||||
// mul16u(word zp($25) a, word zp($1c) b)
|
||||
mul16u: {
|
||||
.label mb = $15
|
||||
.label a = $25
|
||||
.label res = $b
|
||||
.label b = $1e
|
||||
.label b = $1c
|
||||
.label return = $b
|
||||
// mb = b
|
||||
lda.z b
|
||||
@ -520,11 +521,11 @@ bitmap_clear: {
|
||||
rts
|
||||
}
|
||||
// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str.
|
||||
// memset(void* zp($25) str, byte register(X) c, word zp($1e) num)
|
||||
// memset(void* zp($25) str, byte register(X) c, word zp($1c) num)
|
||||
memset: {
|
||||
.label end = $1e
|
||||
.label end = $1c
|
||||
.label dst = $25
|
||||
.label num = $1e
|
||||
.label num = $1c
|
||||
.label str = $25
|
||||
// if(num>0)
|
||||
lda.z num
|
||||
@ -625,7 +626,7 @@ bitmap_init: {
|
||||
// Generate signed int 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(signed word* zp($1c) sintab)
|
||||
// sin16s_gen2(signed word* zp($1a) sintab)
|
||||
sin16s_gen2: {
|
||||
.const min = -$1001
|
||||
.const max = $1001
|
||||
@ -633,8 +634,12 @@ sin16s_gen2: {
|
||||
.label wavelength = $200
|
||||
.label __6 = $b
|
||||
.label __8 = $25
|
||||
// ampl is always positive so shifting left does not alter the sign
|
||||
// u[4.28] step = PI*2/wavelength
|
||||
.label step = $21
|
||||
.label sintab = $1c
|
||||
.label sintab = $1a
|
||||
// u[4.28]
|
||||
// Iterate over the table
|
||||
// u[4.28]
|
||||
// Iterate over the table
|
||||
.label x = $11
|
||||
@ -737,14 +742,23 @@ sin16s: {
|
||||
.label __4 = $27
|
||||
.label x = $15
|
||||
.label return = 4
|
||||
// sinx = x - x^3/6 + x5/128;
|
||||
.label x1 = $2d
|
||||
.label x2 = $19
|
||||
.label x3 = $19
|
||||
// u[1.15]
|
||||
.label x2 = $1e
|
||||
// u[2.14] x^2
|
||||
.label x3 = $1e
|
||||
// u[2.14] x^3
|
||||
.label x3_6 = $2b
|
||||
// u[1.15] x^3/6;
|
||||
.label usinx = 4
|
||||
.label x4 = $19
|
||||
// u[1.15] x - x^3/6
|
||||
.label x4 = $1e
|
||||
// u[3.13] x^4
|
||||
.label x5 = $2b
|
||||
// u[4.12] x^5
|
||||
.label x5_128 = $2b
|
||||
// u[1.15] (first bit is always zero)
|
||||
.label sinx = 4
|
||||
// if(x >= PI_u4f28 )
|
||||
lda.z x+3
|
||||
@ -943,14 +957,14 @@ sin16s: {
|
||||
}
|
||||
// Calculate val*val for two unsigned int values - the result is 16 selected bits of the 32-bit result.
|
||||
// The select parameter indicates how many of the highest bits of the 32-bit result to skip
|
||||
// mulu16_sel(word zp($19) v1, word zp($1e) v2, byte register(X) select)
|
||||
// mulu16_sel(word zp($1e) v1, word zp($1c) v2, byte register(X) select)
|
||||
mulu16_sel: {
|
||||
.label __0 = $b
|
||||
.label __1 = $b
|
||||
.label v1 = $19
|
||||
.label v2 = $1e
|
||||
.label v1 = $1e
|
||||
.label v2 = $1c
|
||||
.label return = $2b
|
||||
.label return_1 = $19
|
||||
.label return_1 = $1e
|
||||
// mul16u(v1, v2)
|
||||
lda.z v1
|
||||
sta.z mul16u.a
|
||||
@ -999,6 +1013,10 @@ div32u16u: {
|
||||
lda.z divr16u.return+1
|
||||
sta.z quotient_hi+1
|
||||
// divr16u(<dividend, divisor, rem16u)
|
||||
lda.z rem16u
|
||||
sta.z divr16u.rem
|
||||
lda.z rem16u+1
|
||||
sta.z divr16u.rem+1
|
||||
lda #<PI2_u4f28&$ffff
|
||||
sta.z divr16u.dividend
|
||||
lda #>PI2_u4f28&$ffff
|
||||
@ -1022,10 +1040,10 @@ div32u16u: {
|
||||
// Returns the quotient dividend/divisor.
|
||||
// The final remainder will be set into the global variable rem16u
|
||||
// Implemented using simple binary division
|
||||
// divr16u(word zp($1e) dividend, word zp($19) rem)
|
||||
// divr16u(word zp($1c) dividend, word zp($1e) rem)
|
||||
divr16u: {
|
||||
.label rem = $19
|
||||
.label dividend = $1e
|
||||
.label rem = $1e
|
||||
.label dividend = $1c
|
||||
.label quotient = $25
|
||||
.label return = $25
|
||||
ldx #0
|
||||
@ -1082,6 +1100,10 @@ divr16u: {
|
||||
cpx #$10
|
||||
bne __b1
|
||||
// rem16u = rem
|
||||
lda.z rem
|
||||
sta.z rem16u
|
||||
lda.z rem+1
|
||||
sta.z rem16u+1
|
||||
// }
|
||||
rts
|
||||
}
|
||||
|
@ -97,7 +97,9 @@ bitmap_line: {
|
||||
.label dy = 8
|
||||
.label sx = $16
|
||||
.label sy = 6
|
||||
// X is the driver
|
||||
.label e1 = $e
|
||||
// Y is the driver
|
||||
.label e = $a
|
||||
.label y = $c
|
||||
.label x = 4
|
||||
|
@ -2,8 +2,9 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.label print_line_cursor = 2
|
||||
.label print_char_cursor = 8
|
||||
.label print_screen = $400
|
||||
.label print_char_cursor = 6
|
||||
.label print_line_cursor = $a
|
||||
main: {
|
||||
// print_cls()
|
||||
jsr print_cls
|
||||
@ -99,9 +100,9 @@ print_ln: {
|
||||
rts
|
||||
}
|
||||
// Print a signed long as HEX
|
||||
// print_slong(signed dword zp(4) dw)
|
||||
// print_slong(signed dword zp(2) dw)
|
||||
print_slong: {
|
||||
.label dw = 4
|
||||
.label dw = 2
|
||||
// if(dw<0)
|
||||
lda.z dw+3
|
||||
bmi __b1
|
||||
@ -152,9 +153,9 @@ print_char: {
|
||||
rts
|
||||
}
|
||||
// Print a unsigned long as HEX
|
||||
// print_ulong(dword zp(4) dw)
|
||||
// print_ulong(dword zp(2) dw)
|
||||
print_ulong: {
|
||||
.label dw = 4
|
||||
.label dw = 2
|
||||
// print_uint(>dw)
|
||||
lda.z dw+2
|
||||
sta.z print_uint.w
|
||||
@ -171,9 +172,9 @@ print_ulong: {
|
||||
rts
|
||||
}
|
||||
// Print a unsigned int as HEX
|
||||
// print_uint(word zp($a) w)
|
||||
// print_uint(word zp(8) w)
|
||||
print_uint: {
|
||||
.label w = $a
|
||||
.label w = 8
|
||||
// print_uchar(>w)
|
||||
ldx.z w+1
|
||||
jsr print_uchar
|
||||
@ -207,9 +208,9 @@ print_uchar: {
|
||||
rts
|
||||
}
|
||||
// Print a zero-terminated string
|
||||
// print_str(byte* zp($a) str)
|
||||
// print_str(byte* zp(8) str)
|
||||
print_str: {
|
||||
.label str = $a
|
||||
.label str = 8
|
||||
__b1:
|
||||
// while(*str)
|
||||
ldy #0
|
||||
@ -276,9 +277,9 @@ testInt: {
|
||||
.byte 0
|
||||
}
|
||||
// Print a signed int as HEX
|
||||
// print_sint(signed word zp($a) w)
|
||||
// print_sint(signed word zp(8) w)
|
||||
print_sint: {
|
||||
.label w = $a
|
||||
.label w = 8
|
||||
// if(w<0)
|
||||
lda.z w+1
|
||||
bmi __b1
|
||||
@ -354,9 +355,9 @@ testChar: {
|
||||
.const n = $e
|
||||
.label s = -$e
|
||||
// print_str("char: ")
|
||||
lda #<$400
|
||||
lda #<print_screen
|
||||
sta.z print_char_cursor
|
||||
lda #>$400
|
||||
lda #>print_screen
|
||||
sta.z print_char_cursor+1
|
||||
lda #<str
|
||||
sta.z print_str.str
|
||||
@ -378,9 +379,9 @@ testChar: {
|
||||
// print_schar(s)
|
||||
jsr print_schar
|
||||
// print_ln()
|
||||
lda #<$400
|
||||
lda #<print_screen
|
||||
sta.z print_line_cursor
|
||||
lda #>$400
|
||||
lda #>print_screen
|
||||
sta.z print_line_cursor+1
|
||||
jsr print_ln
|
||||
// }
|
||||
@ -411,7 +412,7 @@ print_cls: {
|
||||
memset: {
|
||||
.const c = ' '
|
||||
.const num = $3e8
|
||||
.label str = $400
|
||||
.label str = print_screen
|
||||
.label end = str+num
|
||||
.label dst = $a
|
||||
lda #<str
|
||||
|
@ -263,6 +263,7 @@ gfx_init: {
|
||||
}
|
||||
// Initialize Plane with 8bpp charset
|
||||
gfx_init_plane_charset8: {
|
||||
// 8bpp cells for Plane B (charset) - ROM charset with 256 colors
|
||||
// 8bpp cells for Plane B (charset) - ROM charset with 256 colors
|
||||
.const gfxbCpuBank = $ff&CHARSET8/$4000
|
||||
.label bits = 2
|
||||
@ -354,6 +355,7 @@ gfx_init_plane_charset8: {
|
||||
// The actual memory addressed will be $4000*cpuSegmentIdx
|
||||
// dtvSetCpuBankSegment1(byte register(A) cpuBankIdx)
|
||||
dtvSetCpuBankSegment1: {
|
||||
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
|
||||
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
|
||||
.label cpuBank = $ff
|
||||
// *cpuBank = cpuBankIdx
|
||||
|
@ -309,6 +309,7 @@ gfx_init_chunky: {
|
||||
// The actual memory addressed will be $4000*cpuSegmentIdx
|
||||
// dtvSetCpuBankSegment1(byte register(A) cpuBankIdx)
|
||||
dtvSetCpuBankSegment1: {
|
||||
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
|
||||
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
|
||||
.label cpuBank = $ff
|
||||
// *cpuBank = cpuBankIdx
|
||||
|
@ -70,6 +70,7 @@
|
||||
.label DTV_BLITTER_CONTROL2 = $d33f
|
||||
.label SCREEN = $400
|
||||
// Controls the ALU operation
|
||||
// Controls the ALU operation
|
||||
.label DTV_BLITTER_ALU = $d33e
|
||||
main: {
|
||||
// *DTV_FEATURE = DTV_FEATURE_ENABLE
|
||||
|
@ -75,6 +75,7 @@
|
||||
.label DTV_BLITTER_CONTROL2 = $d33f
|
||||
.label SCREEN = $400
|
||||
// Controls the ALU operation
|
||||
// Controls the ALU operation
|
||||
.label DTV_BLITTER_ALU = $d33e
|
||||
main: {
|
||||
// *DTV_FEATURE = DTV_FEATURE_ENABLE
|
||||
|
@ -75,6 +75,7 @@
|
||||
.const OFFSET_STRUCT_MOS6569_VICII_CONTROL2 = $16
|
||||
.const OFFSET_STRUCT_MOS6569_VICII_MEMORY = $18
|
||||
// Number of form fields
|
||||
// Number of form fields
|
||||
.const form_fields_cnt = $24
|
||||
.label VIC_CONTROL = $d011
|
||||
.label VIC_CONTROL2 = $d016
|
||||
@ -169,15 +170,15 @@
|
||||
.label form_vic_bg2_lo = form_fields_val+$21
|
||||
.label form_vic_bg3_hi = form_fields_val+$22
|
||||
.label form_vic_bg3_lo = form_fields_val+$23
|
||||
.label print_line_cursor = 7
|
||||
.label print_char_cursor = $d
|
||||
.label print_line_cursor = $10
|
||||
// Keyboard event buffer size. The number of events currently in the event buffer
|
||||
.label keyboard_events_size = 2
|
||||
.label keyboard_events_size = 9
|
||||
// Counts down to blink for form cursor (it is inversed in the lower half)
|
||||
// Always blink cursor in new field
|
||||
.label form_cursor_count = 3
|
||||
.label form_cursor_count = $b
|
||||
// Current selected field in the form
|
||||
.label form_field_idx = 4
|
||||
.label print_char_cursor = 5
|
||||
.label form_field_idx = $c
|
||||
main: {
|
||||
// asm
|
||||
sei
|
||||
@ -213,23 +214,24 @@ main: {
|
||||
}
|
||||
// Change graphics mode to show the selected graphics mode
|
||||
gfx_mode: {
|
||||
.label __20 = 9
|
||||
.label __24 = $14
|
||||
.label __26 = $1d
|
||||
.label __34 = 9
|
||||
.label __38 = $1f
|
||||
.label __40 = $1b
|
||||
.label __47 = $10
|
||||
.label __48 = $10
|
||||
.label __50 = 7
|
||||
.label __20 = 2
|
||||
.label __24 = $1c
|
||||
.label __26 = $1e
|
||||
.label __34 = 2
|
||||
.label __38 = $14
|
||||
.label __40 = $1a
|
||||
.label __47 = 6
|
||||
.label __48 = 6
|
||||
.label __50 = $10
|
||||
.label __52 = $13
|
||||
.label __82 = $10
|
||||
.label __83 = 7
|
||||
.label plane_a = 9
|
||||
.label plane_b = 9
|
||||
.label vic_colors = $10
|
||||
.label col = 5
|
||||
.label cy = $d
|
||||
.label __82 = 6
|
||||
.label __83 = $10
|
||||
.label plane_a = 2
|
||||
.label plane_b = 2
|
||||
// VIC Colors
|
||||
.label vic_colors = 6
|
||||
.label col = $d
|
||||
.label cy = $f
|
||||
// if(*form_ctrl_line!=0)
|
||||
lda form_ctrl_line
|
||||
cmp #0
|
||||
@ -663,9 +665,9 @@ 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 = $16
|
||||
.label keycode = $22
|
||||
.label row = $e
|
||||
.label row_scan = $20
|
||||
.label keycode = 8
|
||||
.label row = $22
|
||||
lda #0
|
||||
sta.z keycode
|
||||
sta.z row
|
||||
@ -800,10 +802,10 @@ keyboard_event_scan: {
|
||||
}
|
||||
// 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(byte zp($f) keycode)
|
||||
// keyboard_event_pressed(byte zp($a) keycode)
|
||||
keyboard_event_pressed: {
|
||||
.label row_bits = $21
|
||||
.label keycode = $f
|
||||
.label keycode = $a
|
||||
// keycode>>3
|
||||
lda.z keycode
|
||||
lsr
|
||||
@ -842,7 +844,7 @@ keyboard_matrix_read: {
|
||||
// Get the VIC screen address from the screen index
|
||||
// get_vic_screen(byte register(A) idx)
|
||||
get_vic_screen: {
|
||||
.label return = $10
|
||||
.label return = 6
|
||||
// if(idx==0)
|
||||
cmp #0
|
||||
beq __b1
|
||||
@ -892,7 +894,7 @@ get_vic_screen: {
|
||||
// Get the VIC charset/bitmap address from the index
|
||||
// get_vic_charset(byte register(A) idx)
|
||||
get_vic_charset: {
|
||||
.label return = 7
|
||||
.label return = $10
|
||||
// if(idx==0)
|
||||
cmp #0
|
||||
beq __b1
|
||||
@ -915,7 +917,7 @@ get_vic_charset: {
|
||||
// Get plane address from a plane index (from the form)
|
||||
// get_plane(byte register(A) idx)
|
||||
get_plane: {
|
||||
.label return = 9
|
||||
.label return = 2
|
||||
// if(idx==0)
|
||||
cmp #0
|
||||
beq __b1
|
||||
@ -1117,7 +1119,7 @@ get_plane: {
|
||||
}
|
||||
// Show the form - and let the user change values
|
||||
form_mode: {
|
||||
.label preset_current = $d
|
||||
.label preset_current = $f
|
||||
// print_set_screen(COLS)
|
||||
// Form Colors
|
||||
lda #<COLS
|
||||
@ -1256,7 +1258,7 @@ form_mode: {
|
||||
// idx is the ID of the preset
|
||||
// render_preset_name(byte register(A) idx)
|
||||
render_preset_name: {
|
||||
.label name = $10
|
||||
.label name = 6
|
||||
// if(idx==0)
|
||||
cmp #0
|
||||
beq __b3
|
||||
@ -1385,10 +1387,10 @@ render_preset_name: {
|
||||
.byte 0
|
||||
}
|
||||
// Print a string at a specific screen position
|
||||
// print_str_at(byte* zp($10) str, byte* zp(5) at)
|
||||
// print_str_at(byte* zp(6) str, byte* zp($d) at)
|
||||
print_str_at: {
|
||||
.label at = 5
|
||||
.label str = $10
|
||||
.label at = $d
|
||||
.label str = 6
|
||||
lda #<FORM_SCREEN+$28*2+$a
|
||||
sta.z at
|
||||
lda #>FORM_SCREEN+$28*2+$a
|
||||
@ -1442,9 +1444,9 @@ form_render_values: {
|
||||
// field_idx is the index of the field to get the screen address for
|
||||
// form_field_ptr(byte register(X) field_idx)
|
||||
form_field_ptr: {
|
||||
.label line = $14
|
||||
.label x = $16
|
||||
.label return = $1d
|
||||
.label line = $1c
|
||||
.label x = $13
|
||||
.label return = $1e
|
||||
// y = form_fields_y[field_idx]
|
||||
ldy form_fields_y,x
|
||||
// line = (byte*) { form_line_hi[y], form_line_lo[y] }
|
||||
@ -1469,7 +1471,7 @@ form_field_ptr: {
|
||||
// idx is the ID of the preset
|
||||
// apply_preset(byte register(A) idx)
|
||||
apply_preset: {
|
||||
.label preset = 7
|
||||
.label preset = $10
|
||||
// if(idx==0)
|
||||
cmp #0
|
||||
beq __b3
|
||||
@ -1588,7 +1590,7 @@ apply_preset: {
|
||||
// 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 = $1d
|
||||
.label field = $1e
|
||||
// form_field_ptr(form_field_idx)
|
||||
ldx.z form_field_idx
|
||||
jsr form_field_ptr
|
||||
@ -1724,7 +1726,8 @@ form_control: {
|
||||
// Set the screen to use for the form.
|
||||
// screen is the start address of the screen to use
|
||||
form_set_screen: {
|
||||
.label line = $10
|
||||
// Calculate the field line table
|
||||
.label line = 6
|
||||
ldx #0
|
||||
lda #<FORM_SCREEN
|
||||
sta.z line
|
||||
@ -1756,9 +1759,9 @@ form_set_screen: {
|
||||
}
|
||||
// Print a number of zero-terminated strings, each followed by a newline.
|
||||
// The sequence of lines is terminated by another zero.
|
||||
// print_str_lines(byte* zp($10) str)
|
||||
// print_str_lines(byte* zp(6) str)
|
||||
print_str_lines: {
|
||||
.label str = $10
|
||||
.label str = 6
|
||||
lda.z print_set_screen.screen
|
||||
sta.z print_char_cursor
|
||||
lda.z print_set_screen.screen+1
|
||||
@ -1845,13 +1848,13 @@ print_cls: {
|
||||
rts
|
||||
}
|
||||
// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str.
|
||||
// memset(void* zp($10) str)
|
||||
// memset(void* zp($d) str)
|
||||
memset: {
|
||||
.const c = ' '
|
||||
.const num = $3e8
|
||||
.label end = $1f
|
||||
.label dst = $10
|
||||
.label str = $10
|
||||
.label end = $14
|
||||
.label dst = $d
|
||||
.label str = $d
|
||||
// end = (char*)str + num
|
||||
lda.z str
|
||||
clc
|
||||
@ -1883,9 +1886,9 @@ memset: {
|
||||
jmp __b2
|
||||
}
|
||||
// Set the screen to print on. Also resets current line/char cursor.
|
||||
// print_set_screen(byte* zp(7) screen)
|
||||
// print_set_screen(byte* zp($10) screen)
|
||||
print_set_screen: {
|
||||
.label screen = 7
|
||||
.label screen = $10
|
||||
// }
|
||||
rts
|
||||
}
|
||||
@ -1942,16 +1945,16 @@ gfx_init_plane_full: {
|
||||
rts
|
||||
}
|
||||
// Initialize 320*200 1bpp pixel ($2000) plane with identical bytes
|
||||
// gfx_init_plane_fill(dword zp(9) plane_addr, byte zp($e) fill)
|
||||
// gfx_init_plane_fill(dword zp(2) plane_addr, byte zp($22) fill)
|
||||
gfx_init_plane_fill: {
|
||||
.label __0 = $17
|
||||
.label __1 = $1b
|
||||
.label __0 = $16
|
||||
.label __1 = $1a
|
||||
.label __4 = $10
|
||||
.label __5 = $10
|
||||
.label gfxb = $10
|
||||
.label by = $22
|
||||
.label plane_addr = 9
|
||||
.label fill = $e
|
||||
.label by = 8
|
||||
.label plane_addr = 2
|
||||
.label fill = $22
|
||||
// plane_addr*4
|
||||
lda.z plane_addr
|
||||
asl
|
||||
@ -2033,6 +2036,7 @@ gfx_init_plane_fill: {
|
||||
// The actual memory addressed will be $4000*cpuSegmentIdx
|
||||
// dtvSetCpuBankSegment1(byte register(A) cpuBankIdx)
|
||||
dtvSetCpuBankSegment1: {
|
||||
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
|
||||
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
|
||||
.label cpuBank = $ff
|
||||
// *cpuBank = cpuBankIdx
|
||||
@ -2081,8 +2085,8 @@ gfx_init_plane_vertical2: {
|
||||
// Initialize Plane with Horizontal Stripes every 2 pixels
|
||||
gfx_init_plane_horisontal2: {
|
||||
.const gfxbCpuBank = PLANE_HORISONTAL2/$4000
|
||||
.label gfxa = $10
|
||||
.label ay = $f
|
||||
.label gfxa = 6
|
||||
.label ay = 9
|
||||
// dtvSetCpuBankSegment1(gfxbCpuBank++)
|
||||
lda #gfxbCpuBank
|
||||
jsr dtvSetCpuBankSegment1
|
||||
@ -2130,8 +2134,8 @@ gfx_init_plane_horisontal2: {
|
||||
// Initialize Plane with Vertical Stripes
|
||||
gfx_init_plane_vertical: {
|
||||
.const gfxbCpuBank = PLANE_VERTICAL/$4000
|
||||
.label gfxb = $10
|
||||
.label by = $d
|
||||
.label gfxb = 6
|
||||
.label by = $a
|
||||
// dtvSetCpuBankSegment1(gfxbCpuBank++)
|
||||
lda #gfxbCpuBank
|
||||
jsr dtvSetCpuBankSegment1
|
||||
@ -2172,8 +2176,8 @@ gfx_init_plane_vertical: {
|
||||
// Initialize Plane with Horizontal Stripes
|
||||
gfx_init_plane_horisontal: {
|
||||
.const gfxbCpuBank = PLANE_HORISONTAL/$4000
|
||||
.label gfxa = $10
|
||||
.label ay = $d
|
||||
.label gfxa = 6
|
||||
.label ay = $b
|
||||
// dtvSetCpuBankSegment1(gfxbCpuBank++)
|
||||
lda #gfxbCpuBank
|
||||
jsr dtvSetCpuBankSegment1
|
||||
@ -2231,14 +2235,15 @@ gfx_init_plane_horisontal: {
|
||||
}
|
||||
// Initialize Plane with 8bpp charset
|
||||
gfx_init_plane_charset8: {
|
||||
// 8bpp cells for Plane B (charset) - ROM charset with 256 colors
|
||||
// 8bpp cells for Plane B (charset) - ROM charset with 256 colors
|
||||
.const gfxbCpuBank = PLANE_CHARSET8/$4000
|
||||
.label bits = $f
|
||||
.label chargen = $10
|
||||
.label gfxa = $14
|
||||
.label col = $12
|
||||
.label cr = $22
|
||||
.label ch = $e
|
||||
.label bits = $22
|
||||
.label chargen = 6
|
||||
.label gfxa = $d
|
||||
.label col = 8
|
||||
.label cr = $f
|
||||
.label ch = $c
|
||||
// dtvSetCpuBankSegment1(gfxbCpuBank++)
|
||||
lda #gfxbCpuBank
|
||||
jsr dtvSetCpuBankSegment1
|
||||
@ -2319,10 +2324,10 @@ gfx_init_plane_charset8: {
|
||||
}
|
||||
// Initialize 8BPP Chunky Bitmap (contains 8bpp pixels)
|
||||
gfx_init_plane_8bppchunky: {
|
||||
.label __5 = $1d
|
||||
.label __5 = $1c
|
||||
.label gfxb = $10
|
||||
.label x = $14
|
||||
.label y = $e
|
||||
.label x = $d
|
||||
.label y = $f
|
||||
// dtvSetCpuBankSegment1(gfxbCpuBank++)
|
||||
lda #PLANE_8BPP_CHUNKY/$4000
|
||||
jsr dtvSetCpuBankSegment1
|
||||
@ -2432,12 +2437,12 @@ gfx_init_vic_bitmap: {
|
||||
lines_y: .byte 0, 0, $c7, $c7, 0, 0, $64, $c7, $64, 0
|
||||
}
|
||||
// Draw a line on the bitmap
|
||||
// bitmap_line(byte zp($16) x0, byte zp($21) x1, byte register(X) y0, byte zp($13) y1)
|
||||
// bitmap_line(byte zp($13) x0, byte zp($f) x1, byte register(X) y0, byte zp($a) y1)
|
||||
bitmap_line: {
|
||||
.label xd = $12
|
||||
.label x0 = $16
|
||||
.label x1 = $21
|
||||
.label y1 = $13
|
||||
.label x0 = $13
|
||||
.label x1 = $f
|
||||
.label y1 = $a
|
||||
// if(x0<x1)
|
||||
lda.z x0
|
||||
cmp.z x1
|
||||
@ -2558,13 +2563,13 @@ bitmap_line: {
|
||||
jsr bitmap_line_xdyi
|
||||
rts
|
||||
}
|
||||
// bitmap_line_xdyi(byte zp($d) x, byte register(X) y, byte zp($16) x1, byte zp($12) xd, byte zp($f) yd)
|
||||
// bitmap_line_xdyi(byte zp(9) x, byte register(X) y, byte zp($13) x1, byte zp($12) xd, byte zp(8) yd)
|
||||
bitmap_line_xdyi: {
|
||||
.label x = $d
|
||||
.label x1 = $16
|
||||
.label x = 9
|
||||
.label x1 = $13
|
||||
.label xd = $12
|
||||
.label yd = $f
|
||||
.label e = $13
|
||||
.label yd = 8
|
||||
.label e = $a
|
||||
// e = yd>>1
|
||||
lda.z yd
|
||||
lsr
|
||||
@ -2604,9 +2609,10 @@ bitmap_line_xdyi: {
|
||||
}
|
||||
// bitmap_plot(byte register(Y) x, byte register(X) y)
|
||||
bitmap_plot: {
|
||||
.label plotter_x = $1d
|
||||
.label plotter_y = $1f
|
||||
.label plotter = $1d
|
||||
// Needs unsigned int arrays arranged as two underlying char arrays to allow char* plotter_x = plot_x[x]; - and eventually - char* plotter = plot_x[x] + plot_y[y];
|
||||
.label plotter_x = $1c
|
||||
.label plotter_y = $1e
|
||||
.label plotter = $1c
|
||||
// plotter_x = { bitmap_plot_xhi[x], bitmap_plot_xlo[x] }
|
||||
lda bitmap_plot_xhi,y
|
||||
sta.z plotter_x+1
|
||||
@ -2634,14 +2640,14 @@ bitmap_plot: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// bitmap_line_ydxi(byte zp($e) y, byte zp($21) x, byte zp($13) y1, byte zp($d) yd, byte zp($12) xd)
|
||||
// bitmap_line_ydxi(byte zp($b) y, byte zp($f) x, byte zp($a) y1, byte zp(9) yd, byte zp($12) xd)
|
||||
bitmap_line_ydxi: {
|
||||
.label y = $e
|
||||
.label x = $21
|
||||
.label y1 = $13
|
||||
.label yd = $d
|
||||
.label y = $b
|
||||
.label x = $f
|
||||
.label y1 = $a
|
||||
.label yd = 9
|
||||
.label xd = $12
|
||||
.label e = $f
|
||||
.label e = $c
|
||||
// e = xd>>1
|
||||
lda.z xd
|
||||
lsr
|
||||
@ -2679,13 +2685,13 @@ bitmap_line_ydxi: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// bitmap_line_xdyd(byte zp($f) x, byte register(X) y, byte zp($16) x1, byte zp($12) xd, byte zp($e) yd)
|
||||
// bitmap_line_xdyd(byte zp($c) x, byte register(X) y, byte zp($13) x1, byte zp($12) xd, byte zp($b) yd)
|
||||
bitmap_line_xdyd: {
|
||||
.label x = $f
|
||||
.label x1 = $16
|
||||
.label x = $c
|
||||
.label x1 = $13
|
||||
.label xd = $12
|
||||
.label yd = $e
|
||||
.label e = $d
|
||||
.label yd = $b
|
||||
.label e = $f
|
||||
// e = yd>>1
|
||||
lda.z yd
|
||||
lsr
|
||||
@ -2723,14 +2729,14 @@ bitmap_line_xdyd: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// bitmap_line_ydxd(byte zp($e) y, byte zp($16) x, byte zp($13) y1, byte zp($d) yd, byte zp($12) xd)
|
||||
// bitmap_line_ydxd(byte zp($20) y, byte zp($13) x, byte zp($a) y1, byte zp($f) yd, byte zp($12) xd)
|
||||
bitmap_line_ydxd: {
|
||||
.label y = $e
|
||||
.label x = $16
|
||||
.label y1 = $13
|
||||
.label yd = $d
|
||||
.label y = $20
|
||||
.label x = $13
|
||||
.label y1 = $a
|
||||
.label yd = $f
|
||||
.label xd = $12
|
||||
.label e = $f
|
||||
.label e = $21
|
||||
// e = xd>>1
|
||||
lda.z xd
|
||||
lsr
|
||||
@ -2771,7 +2777,7 @@ bitmap_line_ydxd: {
|
||||
// Clear all graphics on the bitmap
|
||||
bitmap_clear: {
|
||||
.label bitmap = $10
|
||||
.label y = $16
|
||||
.label y = $12
|
||||
// bitmap = (char*) { bitmap_plot_xhi[0], bitmap_plot_xlo[0] }
|
||||
lda bitmap_plot_xlo
|
||||
sta.z bitmap
|
||||
@ -2805,8 +2811,8 @@ bitmap_clear: {
|
||||
}
|
||||
// Initialize the bitmap plotter tables for a specific bitmap
|
||||
bitmap_init: {
|
||||
.label __10 = $21
|
||||
.label yoffs = $14
|
||||
.label __10 = $20
|
||||
.label yoffs = $d
|
||||
ldy #$80
|
||||
ldx #0
|
||||
__b1:
|
||||
@ -2874,8 +2880,8 @@ bitmap_init: {
|
||||
}
|
||||
gfx_init_charset: {
|
||||
.label charset = $10
|
||||
.label chargen = $14
|
||||
.label c = $21
|
||||
.label chargen = $d
|
||||
.label c = $13
|
||||
// *PROCPORT = $32
|
||||
lda #$32
|
||||
sta PROCPORT
|
||||
@ -2923,7 +2929,7 @@ gfx_init_charset: {
|
||||
// Initialize VIC screen 4 - all chars are 00
|
||||
gfx_init_screen4: {
|
||||
.label ch = $10
|
||||
.label cy = $e
|
||||
.label cy = $f
|
||||
lda #0
|
||||
sta.z cy
|
||||
lda #<VIC_SCREEN4
|
||||
@ -2956,9 +2962,9 @@ gfx_init_screen4: {
|
||||
}
|
||||
// Initialize VIC screen 3 ( value is %00xx00yy where xx is xpos and yy is ypos
|
||||
gfx_init_screen3: {
|
||||
.label __1 = $22
|
||||
.label ch = $10
|
||||
.label cy = $f
|
||||
.label __1 = $21
|
||||
.label ch = $14
|
||||
.label cy = $20
|
||||
lda #<VIC_SCREEN3
|
||||
sta.z ch
|
||||
lda #>VIC_SCREEN3
|
||||
@ -3005,8 +3011,8 @@ gfx_init_screen3: {
|
||||
// Initialize VIC screen 2 ( value is %ccccrrrr where cccc is (x+y mod $f) and rrrr is %1111-%cccc)
|
||||
gfx_init_screen2: {
|
||||
.label col2 = $22
|
||||
.label ch = $10
|
||||
.label cy = $12
|
||||
.label ch = $14
|
||||
.label cy = $21
|
||||
lda #<VIC_SCREEN2
|
||||
sta.z ch
|
||||
lda #>VIC_SCREEN2
|
||||
@ -3100,7 +3106,7 @@ gfx_init_screen1: {
|
||||
gfx_init_screen0: {
|
||||
.label __1 = $22
|
||||
.label ch = $14
|
||||
.label cy = $13
|
||||
.label cy = $12
|
||||
lda #<VIC_SCREEN0
|
||||
sta.z ch
|
||||
lda #>VIC_SCREEN0
|
||||
|
@ -99,7 +99,7 @@
|
||||
// Memory address of VIC Graphics is GraphicsBank*$10000
|
||||
.label DTV_GRAPHICS_VIC_BANK = $d03d
|
||||
.label print_char_cursor = 6
|
||||
.label print_line_cursor = 8
|
||||
.label print_line_cursor = $b
|
||||
main: {
|
||||
// asm
|
||||
sei
|
||||
@ -192,9 +192,6 @@ menu: {
|
||||
sta BG_COLOR
|
||||
// *BORDER_COLOR = 0
|
||||
sta BORDER_COLOR
|
||||
// print_set_screen(SCREEN)
|
||||
// Display menu Text
|
||||
jsr print_set_screen
|
||||
// print_cls()
|
||||
jsr print_cls
|
||||
// print_str_lines(MENU_TEXT)
|
||||
@ -355,8 +352,8 @@ menu: {
|
||||
mode_8bppchunkybmm: {
|
||||
// 8BPP Chunky Bitmap (contains 8bpp pixels)
|
||||
.const PLANEB = $20000
|
||||
.label __7 = $d
|
||||
.label gfxb = 8
|
||||
.label __7 = $b
|
||||
.label gfxb = $d
|
||||
.label x = 6
|
||||
.label y = 2
|
||||
// *DTV_CONTROL = DTV_HIGHCOLOR | DTV_LINEAR | DTV_CHUNKY | DTV_COLORRAM_OFF
|
||||
@ -478,6 +475,7 @@ mode_8bppchunkybmm: {
|
||||
}
|
||||
// Allow the user to control the DTV graphics using different keys
|
||||
mode_ctrl: {
|
||||
// Read the current control byte
|
||||
// DTV Graphics Mode - Reset
|
||||
.label ctrl = 3
|
||||
__b1:
|
||||
@ -499,6 +497,7 @@ mode_ctrl: {
|
||||
__b4:
|
||||
// ctrl = dtv_control
|
||||
// Read the current control byte
|
||||
// DTV Graphics Mode - Reset
|
||||
stx.z ctrl
|
||||
// keyboard_key_pressed(KEY_L)
|
||||
ldy #KEY_L
|
||||
@ -601,7 +600,7 @@ mode_ctrl: {
|
||||
// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed
|
||||
// keyboard_key_pressed(byte register(Y) key)
|
||||
keyboard_key_pressed: {
|
||||
.label colidx = $13
|
||||
.label colidx = $11
|
||||
// colidx = key&7
|
||||
tya
|
||||
and #7
|
||||
@ -641,6 +640,7 @@ keyboard_matrix_read: {
|
||||
// The actual memory addressed will be $4000*cpuSegmentIdx
|
||||
// dtvSetCpuBankSegment1(byte register(A) cpuBankIdx)
|
||||
dtvSetCpuBankSegment1: {
|
||||
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
|
||||
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
|
||||
.label cpuBank = $ff
|
||||
// *cpuBank = cpuBankIdx
|
||||
@ -667,15 +667,16 @@ mode_8bpppixelcell: {
|
||||
// 8BPP Pixel Cell Charset (contains 256 64 byte chars)
|
||||
.label PLANEB = $4000
|
||||
.label CHARGEN = $d000
|
||||
.label __3 = $a
|
||||
.label __3 = 8
|
||||
// Screen Chars for Plane A (screen) - 16x16 repeating
|
||||
// Screen Chars for Plane A (screen) - 16x16 repeating
|
||||
.label gfxa = 6
|
||||
.label ay = 2
|
||||
.label bits = $11
|
||||
.label chargen = 8
|
||||
.label bits = $f
|
||||
.label chargen = $d
|
||||
.label gfxb = 4
|
||||
.label col = $13
|
||||
.label cr = $c
|
||||
.label col = $11
|
||||
.label cr = $a
|
||||
.label ch = 3
|
||||
// *DTV_CONTROL = DTV_HIGHCOLOR | DTV_LINEAR | DTV_CHUNKY
|
||||
lda #DTV_HIGHCOLOR|DTV_LINEAR|DTV_CHUNKY
|
||||
@ -860,14 +861,17 @@ mode_sixsfred: {
|
||||
.label PLANEB = $6000
|
||||
.label COLORS = $8000
|
||||
// Colors for high 4 bits of 8bpp
|
||||
// Colors for high 4 bits of 8bpp
|
||||
.label col = 4
|
||||
.label cy = $c
|
||||
.label cy = $a
|
||||
// Graphics for Plane A () - horizontal stripes every 2 pixels
|
||||
// Graphics for Plane A () - horizontal stripes every 2 pixels
|
||||
.label gfxa = 6
|
||||
.label ay = $11
|
||||
.label ay = $f
|
||||
// Graphics for Plane B - vertical stripes every 2 pixels
|
||||
.label gfxb = 8
|
||||
.label by = $13
|
||||
// Graphics for Plane B - vertical stripes every 2 pixels
|
||||
.label gfxb = $d
|
||||
.label by = $11
|
||||
// *DTV_CONTROL = DTV_HIGHCOLOR | DTV_LINEAR
|
||||
lda #DTV_HIGHCOLOR|DTV_LINEAR
|
||||
sta DTV_CONTROL
|
||||
@ -1047,17 +1051,21 @@ mode_twoplanebitmap: {
|
||||
.label PLANEA = $4000
|
||||
.label PLANEB = $6000
|
||||
.label COLORS = $8000
|
||||
.label __3 = $a
|
||||
.label __3 = 8
|
||||
// Color for bits 11
|
||||
// Colors for bits 01 / 10
|
||||
// Color for bits 11
|
||||
// Colors for bits 01 / 10
|
||||
.label col = 6
|
||||
.label cy = 2
|
||||
// Graphics for Plane A - horizontal stripes
|
||||
.label gfxa = 8
|
||||
// Graphics for Plane A - horizontal stripes
|
||||
.label gfxa = $d
|
||||
.label ay = 3
|
||||
// Graphics for Plane B - vertical stripes
|
||||
// Graphics for Plane B - vertical stripes
|
||||
.label gfxb = 4
|
||||
.label by = $c
|
||||
.label by = $a
|
||||
// *DTV_CONTROL = DTV_HIGHCOLOR | DTV_LINEAR
|
||||
lda #DTV_HIGHCOLOR|DTV_LINEAR
|
||||
sta DTV_CONTROL
|
||||
@ -1260,16 +1268,19 @@ mode_sixsfred2: {
|
||||
.label PLANEA = $4000
|
||||
.label PLANEB = $6000
|
||||
.label COLORS = $8000
|
||||
.label __3 = $b
|
||||
.label __3 = 9
|
||||
// Colors for high 4 bits of 8bpp
|
||||
// Colors for high 4 bits of 8bpp
|
||||
.label col = 4
|
||||
.label cy = 2
|
||||
// Graphics for Plane A () - horizontal stripes every 2 pixels
|
||||
// Graphics for Plane A () - horizontal stripes every 2 pixels
|
||||
.label gfxa = 6
|
||||
.label ay = 3
|
||||
// Graphics for Plane B - vertical stripes every 2 pixels
|
||||
.label gfxb = 8
|
||||
.label by = $c
|
||||
// Graphics for Plane B - vertical stripes every 2 pixels
|
||||
.label gfxb = $d
|
||||
.label by = $a
|
||||
// *DTV_CONTROL = DTV_LINEAR
|
||||
lda #DTV_LINEAR
|
||||
sta DTV_CONTROL
|
||||
@ -1461,11 +1472,12 @@ mode_hicolmcchar: {
|
||||
.label CHARSET = $9000
|
||||
// Charset ROM
|
||||
.label COLORS = $8400
|
||||
.label __3 = $b
|
||||
.label __3 = 9
|
||||
// Char Colors and screen chars
|
||||
// Char Colors and screen chars
|
||||
.label col = 6
|
||||
.label ch = 8
|
||||
.label cy = $11
|
||||
.label ch = $d
|
||||
.label cy = $f
|
||||
// *DTV_GRAPHICS_VIC_BANK = (byte)((dword)CHARSET/$10000)
|
||||
// DTV Graphics Bank
|
||||
lda #0
|
||||
@ -1598,11 +1610,12 @@ mode_hicolecmchar: {
|
||||
.label CHARSET = $9000
|
||||
// Charset ROM
|
||||
.label COLORS = $8400
|
||||
.label __3 = $c
|
||||
.label __3 = $a
|
||||
// Char Colors and screen chars
|
||||
// Char Colors and screen chars
|
||||
.label col = 6
|
||||
.label ch = 8
|
||||
.label cy = $11
|
||||
.label ch = $d
|
||||
.label cy = $f
|
||||
// *DTV_GRAPHICS_VIC_BANK = (byte)((dword)CHARSET/$10000)
|
||||
// DTV Graphics Bank
|
||||
lda #0
|
||||
@ -1734,11 +1747,12 @@ mode_hicolstdchar: {
|
||||
.label CHARSET = $9000
|
||||
// Charset ROM
|
||||
.label COLORS = $8400
|
||||
.label __3 = $c
|
||||
.label __3 = $a
|
||||
// Char Colors and screen chars
|
||||
// Char Colors and screen chars
|
||||
.label col = 6
|
||||
.label ch = 8
|
||||
.label cy = $13
|
||||
.label ch = $d
|
||||
.label cy = $11
|
||||
// *DTV_GRAPHICS_VIC_BANK = (byte)((dword)CHARSET/$10000)
|
||||
// DTV Graphics Bank
|
||||
lda #0
|
||||
@ -1859,11 +1873,12 @@ mode_stdbitmap: {
|
||||
.const lines_cnt = 9
|
||||
.label SCREEN = $4000
|
||||
.label BITMAP = $6000
|
||||
.label col2 = $11
|
||||
.label col2 = $f
|
||||
// Bitmap Colors
|
||||
// Bitmap Colors
|
||||
.label ch = 4
|
||||
.label cy = $13
|
||||
.label l = $c
|
||||
.label cy = $11
|
||||
.label l = $a
|
||||
// *DTV_GRAPHICS_VIC_BANK = (byte)((dword)BITMAP/$10000)
|
||||
// DTV Graphics Bank
|
||||
lda #0
|
||||
@ -1989,12 +2004,12 @@ mode_stdbitmap: {
|
||||
lines_y: .byte 0, 0, $c7, $c7, 0, 0, $64, $c7, $64, 0
|
||||
}
|
||||
// Draw a line on the bitmap
|
||||
// bitmap_line(byte zp($11) x0, byte zp($12) x1, byte register(X) y0, byte zp($a) y1)
|
||||
// bitmap_line(byte zp($f) x0, byte zp($10) x1, byte register(X) y0, byte zp(8) y1)
|
||||
bitmap_line: {
|
||||
.label xd = $b
|
||||
.label x0 = $11
|
||||
.label x1 = $12
|
||||
.label y1 = $a
|
||||
.label xd = 9
|
||||
.label x0 = $f
|
||||
.label x1 = $10
|
||||
.label y1 = 8
|
||||
// if(x0<x1)
|
||||
lda.z x0
|
||||
cmp.z x1
|
||||
@ -2115,13 +2130,13 @@ bitmap_line: {
|
||||
jsr bitmap_line_xdyi
|
||||
rts
|
||||
}
|
||||
// bitmap_line_xdyi(byte zp(3) x, byte register(X) y, byte zp($11) x1, byte zp($b) xd, byte zp(2) yd)
|
||||
// bitmap_line_xdyi(byte zp(3) x, byte register(X) y, byte zp($f) x1, byte zp(9) xd, byte zp(2) yd)
|
||||
bitmap_line_xdyi: {
|
||||
.label x = 3
|
||||
.label x1 = $11
|
||||
.label xd = $b
|
||||
.label x1 = $f
|
||||
.label xd = 9
|
||||
.label yd = 2
|
||||
.label e = $a
|
||||
.label e = 8
|
||||
// e = yd>>1
|
||||
lda.z yd
|
||||
lsr
|
||||
@ -2161,9 +2176,10 @@ bitmap_line_xdyi: {
|
||||
}
|
||||
// bitmap_plot(byte register(Y) x, byte register(X) y)
|
||||
bitmap_plot: {
|
||||
.label plotter_x = $d
|
||||
.label plotter_y = $f
|
||||
.label plotter = $d
|
||||
// Needs unsigned int arrays arranged as two underlying char arrays to allow char* plotter_x = plot_x[x]; - and eventually - char* plotter = plot_x[x] + plot_y[y];
|
||||
.label plotter_x = $b
|
||||
.label plotter_y = $d
|
||||
.label plotter = $b
|
||||
// plotter_x = { bitmap_plot_xhi[x], bitmap_plot_xlo[x] }
|
||||
lda bitmap_plot_xhi,y
|
||||
sta.z plotter_x+1
|
||||
@ -2191,14 +2207,14 @@ bitmap_plot: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// bitmap_line_ydxi(byte zp(3) y, byte zp($12) x, byte zp($a) y1, byte zp(2) yd, byte zp($b) xd)
|
||||
// bitmap_line_ydxi(byte zp(3) y, byte zp($10) x, byte zp(8) y1, byte zp(2) yd, byte zp(9) xd)
|
||||
bitmap_line_ydxi: {
|
||||
.label y = 3
|
||||
.label x = $12
|
||||
.label y1 = $a
|
||||
.label x = $10
|
||||
.label y1 = 8
|
||||
.label yd = 2
|
||||
.label xd = $b
|
||||
.label e = $13
|
||||
.label xd = 9
|
||||
.label e = $11
|
||||
// e = xd>>1
|
||||
lda.z xd
|
||||
lsr
|
||||
@ -2236,12 +2252,12 @@ bitmap_line_ydxi: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// bitmap_line_xdyd(byte zp(2) x, byte register(X) y, byte zp($11) x1, byte zp($b) xd, byte zp($13) yd)
|
||||
// bitmap_line_xdyd(byte zp(2) x, byte register(X) y, byte zp($f) x1, byte zp(9) xd, byte zp($11) yd)
|
||||
bitmap_line_xdyd: {
|
||||
.label x = 2
|
||||
.label x1 = $11
|
||||
.label xd = $b
|
||||
.label yd = $13
|
||||
.label x1 = $f
|
||||
.label xd = 9
|
||||
.label yd = $11
|
||||
.label e = 3
|
||||
// e = yd>>1
|
||||
lda.z yd
|
||||
@ -2280,14 +2296,14 @@ bitmap_line_xdyd: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// bitmap_line_ydxd(byte zp(3) y, byte zp($11) x, byte zp($a) y1, byte zp(2) yd, byte zp($b) xd)
|
||||
// bitmap_line_ydxd(byte zp(3) y, byte zp($f) x, byte zp(8) y1, byte zp(2) yd, byte zp(9) xd)
|
||||
bitmap_line_ydxd: {
|
||||
.label y = 3
|
||||
.label x = $11
|
||||
.label y1 = $a
|
||||
.label x = $f
|
||||
.label y1 = 8
|
||||
.label yd = 2
|
||||
.label xd = $b
|
||||
.label e = $13
|
||||
.label xd = 9
|
||||
.label e = $11
|
||||
// e = xd>>1
|
||||
lda.z xd
|
||||
lsr
|
||||
@ -2328,7 +2344,7 @@ bitmap_line_ydxd: {
|
||||
// Clear all graphics on the bitmap
|
||||
bitmap_clear: {
|
||||
.label bitmap = 4
|
||||
.label y = $b
|
||||
.label y = 9
|
||||
// bitmap = (char*) { bitmap_plot_xhi[0], bitmap_plot_xlo[0] }
|
||||
lda bitmap_plot_xlo
|
||||
sta.z bitmap
|
||||
@ -2362,7 +2378,7 @@ bitmap_clear: {
|
||||
}
|
||||
// Initialize the bitmap plotter tables for a specific bitmap
|
||||
bitmap_init: {
|
||||
.label __10 = $12
|
||||
.label __10 = $10
|
||||
.label yoffs = 4
|
||||
ldy #$80
|
||||
ldx #0
|
||||
@ -2446,11 +2462,12 @@ mode_mcchar: {
|
||||
.label CHARSET = $9000
|
||||
// Charset ROM
|
||||
.label COLORS = $d800
|
||||
.label __5 = $11
|
||||
.label __5 = $f
|
||||
// Char Colors and screen chars
|
||||
// Char Colors and screen chars
|
||||
.label col = 4
|
||||
.label ch = $d
|
||||
.label cy = $c
|
||||
.label cy = $a
|
||||
// *DTV_GRAPHICS_VIC_BANK = (byte)((dword)CHARSET/$10000)
|
||||
// DTV Graphics Bank
|
||||
lda #0
|
||||
@ -2588,11 +2605,12 @@ mode_ecmchar: {
|
||||
.label CHARSET = $9000
|
||||
// Charset ROM
|
||||
.label COLORS = $d800
|
||||
.label __5 = $12
|
||||
.label __5 = $10
|
||||
// Char Colors and screen chars
|
||||
// Char Colors and screen chars
|
||||
.label col = $d
|
||||
.label ch = 6
|
||||
.label cy = $11
|
||||
.label cy = $f
|
||||
// *DTV_GRAPHICS_VIC_BANK = (byte)((dword)CHARSET/$10000)
|
||||
// DTV Graphics Bank
|
||||
lda #0
|
||||
@ -2728,11 +2746,12 @@ mode_stdchar: {
|
||||
.label CHARSET = $9000
|
||||
// Charset ROM
|
||||
.label COLORS = $d800
|
||||
.label __5 = $13
|
||||
.label __5 = $11
|
||||
// Char Colors and screen chars
|
||||
// Char Colors and screen chars
|
||||
.label col = 6
|
||||
.label ch = $d
|
||||
.label cy = $12
|
||||
.label cy = $10
|
||||
// *DTV_GRAPHICS_VIC_BANK = (byte)((dword)CHARSET/$10000)
|
||||
// DTV Graphics Bank
|
||||
lda #0
|
||||
@ -2947,7 +2966,7 @@ memset: {
|
||||
.const num = $3e8
|
||||
.label str = menu.SCREEN
|
||||
.label end = str+num
|
||||
.label dst = $d
|
||||
.label dst = $b
|
||||
lda #<str
|
||||
sta.z dst
|
||||
lda #>str
|
||||
@ -2973,11 +2992,6 @@ memset: {
|
||||
inc.z dst+1
|
||||
!:
|
||||
jmp __b1
|
||||
}
|
||||
// Set the screen to print on. Also resets current line/char cursor.
|
||||
print_set_screen: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Default vallues for the palette
|
||||
DTV_PALETTE_DEFAULT: .byte 0, $f, $36, $be, $58, $db, $86, $ff, $29, $26, $3b, 5, 7, $df, $9a, $a
|
||||
|
@ -18,6 +18,7 @@
|
||||
.label SCREEN = $400
|
||||
main: {
|
||||
.label __1 = 9
|
||||
// Calculate the cycle count - 0x12 is the base usage of start/read
|
||||
.label cyclecount = 9
|
||||
__b1:
|
||||
// clock_start()
|
||||
|
@ -2,7 +2,7 @@
|
||||
// C standard library string.h
|
||||
// Functions to manipulate C strings and arrays.
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.const LIGHT_BLUE = $e
|
||||
.const OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS = 1
|
||||
@ -12,37 +12,40 @@
|
||||
// Default address of screen character matrix
|
||||
.label DEFAULT_SCREEN = $400
|
||||
.label SCREEN = $400
|
||||
.label conio_cursor_x = 9
|
||||
.label conio_cursor_y = $a
|
||||
.label conio_line_text = $b
|
||||
.label conio_line_color = $d
|
||||
__bbegin:
|
||||
// conio_cursor_x = 0
|
||||
// The number of bytes on the screen
|
||||
// The current cursor x-position
|
||||
lda #0
|
||||
sta.z conio_cursor_x
|
||||
// conio_cursor_y = 0
|
||||
.label conio_cursor_x = 9
|
||||
// The current cursor y-position
|
||||
sta.z conio_cursor_y
|
||||
// conio_line_text = CONIO_SCREEN_TEXT
|
||||
.label conio_cursor_y = $a
|
||||
// The current text cursor line start
|
||||
lda #<DEFAULT_SCREEN
|
||||
sta.z conio_line_text
|
||||
lda #>DEFAULT_SCREEN
|
||||
sta.z conio_line_text+1
|
||||
// conio_line_color = CONIO_SCREEN_COLORS
|
||||
.label conio_line_text = $b
|
||||
// The current color cursor line start
|
||||
lda #<COLORRAM
|
||||
sta.z conio_line_color
|
||||
lda #>COLORRAM
|
||||
sta.z conio_line_color+1
|
||||
jsr main
|
||||
rts
|
||||
.label conio_line_color = $d
|
||||
_start: {
|
||||
// conio_cursor_x = 0
|
||||
lda #0
|
||||
sta.z conio_cursor_x
|
||||
// conio_cursor_y = 0
|
||||
sta.z conio_cursor_y
|
||||
// conio_line_text = CONIO_SCREEN_TEXT
|
||||
lda #<DEFAULT_SCREEN
|
||||
sta.z conio_line_text
|
||||
lda #>DEFAULT_SCREEN
|
||||
sta.z conio_line_text+1
|
||||
// conio_line_color = CONIO_SCREEN_COLORS
|
||||
lda #<COLORRAM
|
||||
sta.z conio_line_color
|
||||
lda #>COLORRAM
|
||||
sta.z conio_line_color+1
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.label __9 = $10
|
||||
.label __10 = $d
|
||||
// yd = y-12
|
||||
.label yd = $f
|
||||
// dist_sq = xd*xd + yd*yd
|
||||
.label dist_sq = $10
|
||||
.label y = 9
|
||||
.label sc = $b
|
||||
|
@ -1,5 +1,5 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.const DARK_GREY = $b
|
||||
.const BLACK = 0
|
||||
@ -7,12 +7,13 @@
|
||||
.label BORDER_COLOR = $d020
|
||||
.label RASTER = $d012
|
||||
.label irq_raster_next = 2
|
||||
__bbegin:
|
||||
// irq_raster_next = 0
|
||||
lda #0
|
||||
sta.z irq_raster_next
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// irq_raster_next = 0
|
||||
lda #0
|
||||
sta.z irq_raster_next
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// *KERNEL_IRQ = &irq
|
||||
lda #<irq
|
||||
|
@ -4,7 +4,7 @@
|
||||
// C standard library string.h
|
||||
// Functions to manipulate C strings and arrays.
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
// The number of iterations performed during 16-bit CORDIC atan2 calculation
|
||||
.const CORDIC_ITERATIONS_16 = $f
|
||||
@ -80,30 +80,38 @@
|
||||
// Sprite data for the animating sprites
|
||||
.label SPRITE_DATA = $2000
|
||||
// Top of the heap used by malloc()
|
||||
// Top of the heap used by malloc()
|
||||
.label HEAP_TOP = $a000
|
||||
// Head of the heap. Moved backward each malloc()
|
||||
.label heap_head = 8
|
||||
// Copy of the screen used for finding chars to process
|
||||
.label SCREEN_COPY = $c
|
||||
// Screen containing bytes representing the distance to the center
|
||||
.label SCREEN_DIST = $e
|
||||
__bbegin:
|
||||
// malloc(1000)
|
||||
lda #<HEAP_TOP
|
||||
sta.z heap_head
|
||||
lda #>HEAP_TOP
|
||||
sta.z heap_head+1
|
||||
jsr malloc
|
||||
// malloc(1000)
|
||||
lda.z malloc.mem
|
||||
sta.z SCREEN_COPY
|
||||
lda.z malloc.mem+1
|
||||
sta.z SCREEN_COPY+1
|
||||
jsr malloc
|
||||
// malloc(1000)
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// malloc(1000)
|
||||
lda #<HEAP_TOP
|
||||
sta.z heap_head
|
||||
lda #>HEAP_TOP
|
||||
sta.z heap_head+1
|
||||
jsr malloc
|
||||
// malloc(1000)
|
||||
lda.z malloc.mem
|
||||
sta.z SCREEN_COPY
|
||||
lda.z malloc.mem+1
|
||||
sta.z SCREEN_COPY+1
|
||||
jsr malloc
|
||||
// malloc(1000)
|
||||
lda.z malloc.mem
|
||||
sta.z SCREEN_DIST
|
||||
lda.z malloc.mem+1
|
||||
sta.z SCREEN_DIST+1
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.label dst = 2
|
||||
.label src = 8
|
||||
.label src = $22
|
||||
.label i = 4
|
||||
.label center_y = $10
|
||||
// init_angle_screen(SCREEN_DIST)
|
||||
@ -147,7 +155,7 @@ main: {
|
||||
tax
|
||||
ldy #0
|
||||
!:
|
||||
lda __2,y
|
||||
lda __0,y
|
||||
sta PROCESSING,x
|
||||
inx
|
||||
iny
|
||||
@ -205,36 +213,38 @@ main: {
|
||||
jmp __b1
|
||||
}
|
||||
// Start processing a char - by inserting it into the PROCESSING array
|
||||
// startProcessing(byte zp($23) center_x, byte zp($10) center_y)
|
||||
// startProcessing(byte zp($21) center_x, byte zp($10) center_y)
|
||||
startProcessing: {
|
||||
.label __0 = $11
|
||||
.label __4 = 8
|
||||
.label __0 = $22
|
||||
.label __4 = $1f
|
||||
.label __6 = 6
|
||||
.label __8 = $18
|
||||
.label __9 = $18
|
||||
.label __11 = $1a
|
||||
.label __12 = $1a
|
||||
.label __23 = $11
|
||||
.label __24 = 8
|
||||
.label __8 = $16
|
||||
.label __9 = $16
|
||||
.label __11 = $18
|
||||
.label __12 = $18
|
||||
.label __23 = $22
|
||||
.label __24 = $1f
|
||||
.label __25 = 6
|
||||
.label __26 = $18
|
||||
.label __27 = $1a
|
||||
.label center_x = $23
|
||||
.label __26 = $16
|
||||
.label __27 = $18
|
||||
.label center_x = $21
|
||||
.label center_y = $10
|
||||
.label i = 5
|
||||
.label offset = $11
|
||||
.label colPtr = $15
|
||||
.label spriteCol = $17
|
||||
.label screenPtr = $11
|
||||
.label spriteData = 8
|
||||
// Copy char into sprite
|
||||
.label offset = $22
|
||||
.label colPtr = $13
|
||||
.label spriteCol = $15
|
||||
.label screenPtr = $22
|
||||
.label spriteData = $1f
|
||||
.label chargenData = 6
|
||||
.label spriteX = $18
|
||||
.label spriteY = $1a
|
||||
.label spritePtr = $1c
|
||||
.label spriteX = $16
|
||||
.label spriteY = $18
|
||||
.label spritePtr = $1a
|
||||
// Busy-wait while finding an empty slot in the PROCESSING array
|
||||
// Busy-wait while finding an empty slot in the PROCESSING array
|
||||
.label freeIdx = 5
|
||||
.label __33 = $13
|
||||
.label __34 = $11
|
||||
.label __33 = $11
|
||||
.label __34 = $22
|
||||
ldx #$ff
|
||||
__b1:
|
||||
lda #0
|
||||
@ -518,19 +528,19 @@ startProcessing: {
|
||||
// Find the non-space char closest to the center of the screen
|
||||
// If no non-space char is found the distance will be 0xffff
|
||||
getCharToProcess: {
|
||||
.label __8 = $1d
|
||||
.label __9 = $1d
|
||||
.label __11 = $1d
|
||||
.label __8 = $1b
|
||||
.label __9 = $1b
|
||||
.label __11 = $1b
|
||||
.label screen_line = 6
|
||||
.label dist_line = 8
|
||||
.label dist_line = $1f
|
||||
.label y = 5
|
||||
.label return_x = $17
|
||||
.label return_y = $1c
|
||||
.label return_x = $15
|
||||
.label return_y = $1a
|
||||
.label closest_dist = $10
|
||||
.label closest_x = $17
|
||||
.label closest_y = $1c
|
||||
.label __12 = $1f
|
||||
.label __13 = $1d
|
||||
.label closest_x = $15
|
||||
.label closest_y = $1a
|
||||
.label __12 = $1d
|
||||
.label __13 = $1b
|
||||
// screen_line = SCREEN_COPY
|
||||
lda.z SCREEN_COPY
|
||||
sta.z screen_line
|
||||
@ -738,18 +748,18 @@ initSprites: {
|
||||
}
|
||||
// Populates 1000 chars (a screen) with values representing the angle to the center.
|
||||
// Utilizes symmetry around the center
|
||||
// init_angle_screen(byte* zp($11) screen)
|
||||
// init_angle_screen(byte* zp($22) screen)
|
||||
init_angle_screen: {
|
||||
.label __7 = $18
|
||||
.label screen = $11
|
||||
.label __7 = $16
|
||||
.label screen = $22
|
||||
.label screen_topline = 6
|
||||
.label screen_bottomline = $11
|
||||
.label xw = $1f
|
||||
.label yw = $21
|
||||
.label angle_w = $18
|
||||
.label ang_w = $23
|
||||
.label x = $17
|
||||
.label xb = $1c
|
||||
.label screen_bottomline = $22
|
||||
.label xw = $1d
|
||||
.label yw = $1f
|
||||
.label angle_w = $16
|
||||
.label ang_w = $21
|
||||
.label x = $15
|
||||
.label xb = $1a
|
||||
.label y = $10
|
||||
// screen_topline = screen+40*12
|
||||
lda.z screen
|
||||
@ -864,18 +874,19 @@ init_angle_screen: {
|
||||
// Find the atan2(x, y) - which is the angle of the line from (0,0) to (x,y)
|
||||
// Finding the angle requires a binary search using CORDIC_ITERATIONS_16
|
||||
// Returns the angle in hex-degrees (0=0, 0x8000=PI, 0x10000=2*PI)
|
||||
// atan2_16(signed word zp($1f) x, signed word zp($21) y)
|
||||
// atan2_16(signed word zp($1d) x, signed word zp($1f) y)
|
||||
atan2_16: {
|
||||
.label __2 = $13
|
||||
.label __7 = $15
|
||||
.label yi = $13
|
||||
.label xi = $15
|
||||
.label angle = $18
|
||||
.label xd = $1d
|
||||
.label yd = $1a
|
||||
.label return = $18
|
||||
.label x = $1f
|
||||
.label y = $21
|
||||
.label __2 = $11
|
||||
.label __7 = $13
|
||||
.label yi = $11
|
||||
.label xi = $13
|
||||
.label angle = $16
|
||||
// Optimized shift of 2 values: xd=xi>>i; yd=yi>>i
|
||||
.label xd = $1b
|
||||
.label yd = $18
|
||||
.label return = $16
|
||||
.label x = $1d
|
||||
.label y = $1f
|
||||
// (y>=0)?y:-y
|
||||
lda.z y+1
|
||||
bmi !__b1+
|
||||
@ -1079,7 +1090,7 @@ atan2_16: {
|
||||
// Allocates a block of size chars of memory, returning a pointer to the beginning of the block.
|
||||
// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.
|
||||
malloc: {
|
||||
.label mem = $e
|
||||
.label mem = $22
|
||||
// mem = heap_head-size
|
||||
lda.z heap_head
|
||||
sec
|
||||
@ -1486,6 +1497,6 @@ VYSIN:
|
||||
|
||||
// Sprites currently being processed in the interrupt
|
||||
PROCESSING: .fill $e*NUM_PROCESSING, 0
|
||||
__2: .word 0, 0, 0, 0
|
||||
__0: .word 0, 0, 0, 0
|
||||
.byte 0, 0, 0, STATUS_FREE
|
||||
.word 0
|
||||
|
@ -5,7 +5,7 @@
|
||||
// - Up-to-down EOR filling
|
||||
// - Double buffering
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
|
||||
.const CIA_INTERRUPT_CLEAR = $7f
|
||||
@ -31,7 +31,6 @@
|
||||
.const OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE = $1a
|
||||
.const OFFSET_STRUCT_MOS6569_VICII_MEMORY = $18
|
||||
.const OFFSET_STRUCT_MOS6569_VICII_IRQ_STATUS = $19
|
||||
.const toD0181_return = (>(SCREEN&$3fff)*4)|(>CANVAS2)/4&$f
|
||||
// The VIC-II MOS 6567/6569
|
||||
.label VICII = $d000
|
||||
// Color Ram
|
||||
@ -56,27 +55,31 @@
|
||||
// The default charset address
|
||||
.label PETSCII = $1000
|
||||
.label COSTAB = SINTAB+$40
|
||||
.label canvas_show_memory = $11
|
||||
.label canvas_show_flag = $12
|
||||
__bbegin:
|
||||
// canvas_show_memory = toD018(SCREEN, CANVAS2)
|
||||
// The current canvas being rendered to the screen - in D018 format.
|
||||
lda #toD0181_return
|
||||
sta.z canvas_show_memory
|
||||
// canvas_show_flag = 0
|
||||
.label canvas_show_memory = $11
|
||||
// Flag signalling that the canvas on screen needs to be updated.
|
||||
// Set to 1 by the renderer when a new canvas is ready for showing, and to 0 by the raster when the canvas is shown on screen.
|
||||
lda #0
|
||||
sta.z canvas_show_flag
|
||||
jsr main
|
||||
rts
|
||||
.label canvas_show_flag = $12
|
||||
_start: {
|
||||
.const _init1_toD0181_return = (>(SCREEN&$3fff)*4)|(>CANVAS2)/4&$f
|
||||
// canvas_show_memory = toD018(SCREEN, CANVAS2)
|
||||
lda #_init1_toD0181_return
|
||||
sta.z canvas_show_memory
|
||||
// canvas_show_flag = 0
|
||||
lda #0
|
||||
sta.z canvas_show_flag
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.const toD0181_return = (>(SCREEN&$3fff)*4)|(>CANVAS1)/4&$f
|
||||
.const toD0182_return = (>(SCREEN&$3fff)*4)|(>CANVAS2)/4&$f
|
||||
.label cols = 3
|
||||
// Setup 16x16 canvas for rendering
|
||||
// Setup 16x16 canvas for rendering
|
||||
.label screen = 5
|
||||
.label y = 2
|
||||
// Plot in line buffer
|
||||
.label x0 = $13
|
||||
.label y0 = $14
|
||||
.label x1 = $c
|
||||
@ -87,6 +90,7 @@ main: {
|
||||
.label p1_idx = 8
|
||||
.label p2_idx = 9
|
||||
// The current canvas being rendered to
|
||||
// The current canvas being rendered to
|
||||
.label canvas = $a
|
||||
// memset(CONSOLE, ' ', 40*25)
|
||||
// Clear the console
|
||||
@ -148,9 +152,6 @@ main: {
|
||||
// setup_irq()
|
||||
// Set-up the raster IRQ
|
||||
jsr setup_irq
|
||||
// textcolor(WHITE)
|
||||
// Set text color
|
||||
jsr textcolor
|
||||
lda #<CANVAS1
|
||||
sta.z canvas
|
||||
lda #>CANVAS1
|
||||
@ -266,8 +267,6 @@ main: {
|
||||
// Set flag used to signal when the canvas has been shown
|
||||
lda #1
|
||||
sta.z canvas_show_flag
|
||||
// clock()
|
||||
jsr clock
|
||||
jmp __b8
|
||||
__b2:
|
||||
ldx.z y
|
||||
@ -309,12 +308,6 @@ main: {
|
||||
iny
|
||||
jmp __b4
|
||||
}
|
||||
// Returns the processor clock time used since the beginning of an implementation defined era (normally the beginning of the program).
|
||||
// This uses CIA #2 Timer A+B on the C64, and must be initialized using clock_start()
|
||||
clock: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// EOR fill from the line buffer onto the canvas
|
||||
// eorfill(byte* zp($1f) canvas)
|
||||
eorfill: {
|
||||
@ -387,13 +380,19 @@ line: {
|
||||
.label dy = $18
|
||||
.label sx = $19
|
||||
.label sy = $1a
|
||||
// Find the canvas column
|
||||
.label plot1_column = $21
|
||||
.label plot2_y = $1b
|
||||
// Find the canvas column
|
||||
.label plot2_column = $1c
|
||||
// Find the canvas column
|
||||
.label plot3_column = $1f
|
||||
.label e1 = $e
|
||||
// Find the canvas column
|
||||
.label plot4_column = $23
|
||||
// Find the canvas column
|
||||
.label plot5_column = $25
|
||||
// Find the canvas column
|
||||
.label plot6_column = $28
|
||||
// abs_u8(x2-x1)
|
||||
lda.z x2
|
||||
@ -803,10 +802,6 @@ clock_start: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Set the color for text output. The old color setting is returned.
|
||||
textcolor: {
|
||||
rts
|
||||
}
|
||||
// Setup raster IRQ to change charset at different lines
|
||||
setup_irq: {
|
||||
// asm
|
||||
|
@ -33,17 +33,18 @@
|
||||
// The BOB charset
|
||||
.label BOB_CHARSET = $2000
|
||||
// BOB charset ID of the next glyph to be added
|
||||
.label bob_charset_next_id = $11
|
||||
.label bob_charset_next_id = $15
|
||||
// Current index within the progress cursor (0-7)
|
||||
.label progress_idx = $10
|
||||
.label progress_idx = $e
|
||||
// Current position of the progress cursor
|
||||
.label progress_cursor = $e
|
||||
.label progress_cursor = $c
|
||||
// Pointer to the next clean-up to add
|
||||
// Prepare for next clean-up
|
||||
.label renderBobCleanupNext = $c
|
||||
.label renderBobCleanupNext = $f
|
||||
main: {
|
||||
.const origY = $a00
|
||||
// Row and column offset vectors
|
||||
// Row and column offset vectors
|
||||
.const rowOffsetX = $c00
|
||||
.const colOffsetX = $100
|
||||
.const colOffsetY = $1800
|
||||
@ -57,9 +58,10 @@ main: {
|
||||
.label y_1 = $a
|
||||
.label rowX = 4
|
||||
.label rowY = 6
|
||||
.label col = $10
|
||||
.label col = $e
|
||||
// Origin point
|
||||
.label origX = $e
|
||||
// Origin point
|
||||
.label origX = $c
|
||||
.label rowOffsetY = 2
|
||||
// mulf_init()
|
||||
jsr mulf_init
|
||||
@ -255,16 +257,16 @@ keyboard_matrix_read: {
|
||||
// Render a single BOB at a given x/y-position
|
||||
// X-position is 0-151. Each x-position is 2 pixels wide.
|
||||
// Y-position is 0-183. Each y-position is 1 pixel high.
|
||||
// renderBob(byte zp($16) xpos, byte zp($17) ypos)
|
||||
// renderBob(byte zp($13) xpos, byte zp($14) ypos)
|
||||
renderBob: {
|
||||
.label __2 = $19
|
||||
.label __5 = $1b
|
||||
.label xpos = $16
|
||||
.label ypos = $17
|
||||
.label x_char_offset = $18
|
||||
.label y_offset = $19
|
||||
.label screen = $19
|
||||
.label bob_table_idx = $1b
|
||||
.label __2 = $16
|
||||
.label __5 = $18
|
||||
.label xpos = $13
|
||||
.label ypos = $14
|
||||
.label x_char_offset = $15
|
||||
.label y_offset = $16
|
||||
.label screen = $16
|
||||
.label bob_table_idx = $18
|
||||
// x_char_offset = xpos/BOB_SHIFTS_X
|
||||
lda.z xpos
|
||||
lsr
|
||||
@ -377,7 +379,7 @@ renderBob: {
|
||||
}
|
||||
// Clean Up the rendered BOB's
|
||||
renderBobCleanup: {
|
||||
.label screen = $1c
|
||||
.label screen = $19
|
||||
ldx #0
|
||||
__b1:
|
||||
// screen = RENDERBOB_CLEANUP[i]
|
||||
@ -429,7 +431,7 @@ memset: {
|
||||
.const num = $3e8
|
||||
.label str = BOB_SCREEN
|
||||
.label end = str+num
|
||||
.label dst = $19
|
||||
.label dst = $f
|
||||
lda #<str
|
||||
sta.z dst
|
||||
lda #>str
|
||||
@ -458,10 +460,10 @@ memset: {
|
||||
}
|
||||
// Initialize the tables used by renderBob()
|
||||
renderBobInit: {
|
||||
.label __0 = $1e
|
||||
.label __5 = $1e
|
||||
.label __6 = $20
|
||||
.label __7 = $1e
|
||||
.label __0 = $1b
|
||||
.label __5 = $1b
|
||||
.label __6 = $1d
|
||||
.label __7 = $1b
|
||||
ldx #0
|
||||
__b1:
|
||||
// ((unsigned int)y)*40
|
||||
@ -522,15 +524,14 @@ renderBobInit: {
|
||||
// Creates the pre-shifted bobs into BOB_CHARSET and populates the BOB_TABLES
|
||||
// Modifies PROTO_BOB by shifting it around
|
||||
prepareBobs: {
|
||||
.label bob_table = $20
|
||||
.label shift_y = $12
|
||||
.label bob_table = $1b
|
||||
.label shift_y = $11
|
||||
// Populate charset and tables
|
||||
.label bob_glyph = $19
|
||||
.label cell = $17
|
||||
.label bob_table_idx = $15
|
||||
.label shift_x = $16
|
||||
// progress_init(BASIC_SCREEN)
|
||||
jsr progress_init
|
||||
// Populate charset and tables
|
||||
.label bob_glyph = $f
|
||||
.label cell = $14
|
||||
.label bob_table_idx = $12
|
||||
.label shift_x = $13
|
||||
// charsetFindOrAddGlyph(PROTO_BOB+48, BOB_CHARSET)
|
||||
// Ensure that glyph #0 is empty
|
||||
lda #<PROTO_BOB+$30
|
||||
@ -665,10 +666,10 @@ progress_inc: {
|
||||
}
|
||||
// Looks through a charset to find a glyph if present. If not present it is added.
|
||||
// Returns the glyph ID
|
||||
// charsetFindOrAddGlyph(byte* zp($19) glyph)
|
||||
// charsetFindOrAddGlyph(byte* zp($f) glyph)
|
||||
charsetFindOrAddGlyph: {
|
||||
.label glyph = $19
|
||||
.label glyph_cursor = $13
|
||||
.label glyph = $f
|
||||
.label glyph_cursor = $1d
|
||||
lda #<BOB_CHARSET
|
||||
sta.z glyph_cursor
|
||||
lda #>BOB_CHARSET
|
||||
@ -733,7 +734,7 @@ charsetFindOrAddGlyph: {
|
||||
}
|
||||
// Shift PROTO_BOB right one X pixel
|
||||
protoBobShiftRight: {
|
||||
.label carry = $1b
|
||||
.label carry = $14
|
||||
.label i = $18
|
||||
ldy #0
|
||||
ldx #0
|
||||
@ -819,25 +820,25 @@ protoBobShiftDown: {
|
||||
dex
|
||||
jmp __b1
|
||||
}
|
||||
// Initialize the PETSCII progress bar
|
||||
progress_init: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
|
||||
mulf_init: {
|
||||
// x/2
|
||||
.label c = $12
|
||||
// x/2
|
||||
.label c = $11
|
||||
// Counter used for determining x%2==0
|
||||
.label sqr1_hi = $13
|
||||
// Counter used for determining x%2==0
|
||||
.label sqr1_hi = $1b
|
||||
// Fill mulf_sqr1 = f(x) = int(x*x/4): If f(x) = x*x/4 then f(x+1) = f(x) + x/2 + 1/4
|
||||
.label sqr = $1e
|
||||
.label sqr1_lo = $20
|
||||
// Fill mulf_sqr1 = f(x) = int(x*x/4): If f(x) = x*x/4 then f(x+1) = f(x) + x/2 + 1/4
|
||||
.label sqr = $19
|
||||
.label sqr1_lo = $f
|
||||
// Decrease or increase x_255 - initially we decrease
|
||||
.label sqr2_hi = $1c
|
||||
.label sqr2_lo = $19
|
||||
// Decrease or increase x_255 - initially we decrease
|
||||
.label sqr2_hi = $16
|
||||
.label sqr2_lo = $1d
|
||||
//Start with g(0)=f(255)
|
||||
.label dir = $15
|
||||
//Start with g(0)=f(255)
|
||||
.label dir = $12
|
||||
ldx #0
|
||||
lda #<mulf_sqr1_hi+1
|
||||
sta.z sqr1_hi
|
||||
|
@ -34,29 +34,30 @@
|
||||
.label BOB_CHARSET = $2000
|
||||
.label COS = SIN+$40
|
||||
// BOB charset ID of the next glyph to be added
|
||||
.label bob_charset_next_id = 9
|
||||
.label bob_charset_next_id = 7
|
||||
// Current index within the progress cursor (0-7)
|
||||
.label progress_idx = 8
|
||||
.label progress_idx = 6
|
||||
// Current position of the progress cursor
|
||||
.label progress_cursor = 6
|
||||
.label progress_cursor = 4
|
||||
// Pointer to the next clean-up to add
|
||||
// Prepare for next clean-up
|
||||
.label renderBobCleanupNext = 3
|
||||
.label renderBobCleanupNext = 8
|
||||
main: {
|
||||
.const vicSelectGfxBank1_toDd001_return = 3
|
||||
.const vicSelectGfxBank2_toDd001_return = 3
|
||||
.const toD0181_return = (>(BOB_SCREEN&$3fff)*4)|(>BOB_CHARSET)/4&$f
|
||||
.const toD0182_return = (>(SCREEN_BASIC&$3fff)*4)|(>CHARSET_BASIC)/4&$f
|
||||
.label __10 = 6
|
||||
.label __12 = 6
|
||||
.label __13 = 6
|
||||
.label __10 = 4
|
||||
.label __12 = 4
|
||||
.label __13 = 4
|
||||
.label x = $c
|
||||
.label y = 6
|
||||
.label y = 4
|
||||
.label a = 2
|
||||
.label r = 9
|
||||
.label i = 5
|
||||
.label r = 7
|
||||
.label i = 3
|
||||
// Render Rotated BOBs
|
||||
.label angle = 8
|
||||
// Render Rotated BOBs
|
||||
.label angle = 6
|
||||
// mulf_init()
|
||||
jsr mulf_init
|
||||
// prepareBobs()
|
||||
@ -344,7 +345,7 @@ renderBob: {
|
||||
// Fast multiply two signed chars to a unsigned int result
|
||||
// mulf8s(signed byte register(A) a, signed byte register(X) b)
|
||||
mulf8s: {
|
||||
.label return = 6
|
||||
.label return = 4
|
||||
// mulf8u_prepare((char)a)
|
||||
jsr mulf8u_prepare
|
||||
// mulf8s_prepared(b)
|
||||
@ -358,7 +359,7 @@ mulf8s: {
|
||||
// mulf8s_prepared(signed byte zp($13) b)
|
||||
mulf8s_prepared: {
|
||||
.label memA = $fd
|
||||
.label m = 6
|
||||
.label m = 4
|
||||
.label b = $13
|
||||
// mulf8u_prepared((char) b)
|
||||
lda.z b
|
||||
@ -395,7 +396,7 @@ mulf8s_prepared: {
|
||||
mulf8u_prepared: {
|
||||
.label resL = $fe
|
||||
.label memB = $ff
|
||||
.label return = 6
|
||||
.label return = 4
|
||||
// *memB = b
|
||||
sta memB
|
||||
// asm
|
||||
@ -488,7 +489,7 @@ memset: {
|
||||
.const num = $3e8
|
||||
.label str = BOB_SCREEN
|
||||
.label end = str+num
|
||||
.label dst = $c
|
||||
.label dst = 8
|
||||
lda #<str
|
||||
sta.z dst
|
||||
lda #>str
|
||||
@ -517,10 +518,10 @@ memset: {
|
||||
}
|
||||
// Initialize the tables used by renderBob()
|
||||
renderBobInit: {
|
||||
.label __0 = $16
|
||||
.label __5 = $16
|
||||
.label __6 = $18
|
||||
.label __7 = $16
|
||||
.label __0 = $14
|
||||
.label __5 = $14
|
||||
.label __6 = $16
|
||||
.label __7 = $14
|
||||
ldx #0
|
||||
__b1:
|
||||
// ((unsigned int)y)*40
|
||||
@ -581,15 +582,14 @@ renderBobInit: {
|
||||
// Creates the pre-shifted bobs into BOB_CHARSET and populates the BOB_TABLES
|
||||
// Modifies PROTO_BOB by shifting it around
|
||||
prepareBobs: {
|
||||
.label bob_table = $16
|
||||
.label bob_table = $14
|
||||
.label shift_y = $a
|
||||
// Populate charset and tables
|
||||
.label bob_glyph = $c
|
||||
// Populate charset and tables
|
||||
.label bob_glyph = 8
|
||||
.label cell = $f
|
||||
.label bob_table_idx = $b
|
||||
.label shift_x = $e
|
||||
// progress_init(SCREEN_BASIC)
|
||||
jsr progress_init
|
||||
// bobCharsetFindOrAddGlyph(PROTO_BOB+48)
|
||||
// Ensure that glyph #0 is empty
|
||||
lda #<PROTO_BOB+$30
|
||||
@ -725,10 +725,10 @@ progress_inc: {
|
||||
// Looks through BOB_CHARSET to find the passed bob glyph if present.
|
||||
// If not present it is added
|
||||
// Returns the glyph ID
|
||||
// bobCharsetFindOrAddGlyph(byte* zp($c) bob_glyph)
|
||||
// bobCharsetFindOrAddGlyph(byte* zp(8) bob_glyph)
|
||||
bobCharsetFindOrAddGlyph: {
|
||||
.label bob_glyph = $c
|
||||
.label glyph_cursor = $18
|
||||
.label bob_glyph = 8
|
||||
.label glyph_cursor = $16
|
||||
lda #<BOB_CHARSET
|
||||
sta.z glyph_cursor
|
||||
lda #>BOB_CHARSET
|
||||
@ -879,23 +879,23 @@ shiftProtoBobDown: {
|
||||
dex
|
||||
jmp __b1
|
||||
}
|
||||
// Initialize the PETSCII progress bar
|
||||
progress_init: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
|
||||
mulf_init: {
|
||||
// x/2
|
||||
// x/2
|
||||
.label c = $a
|
||||
// Counter used for determining x%2==0
|
||||
.label sqr1_hi = $18
|
||||
// Counter used for determining x%2==0
|
||||
.label sqr1_hi = $14
|
||||
// Fill mulf_sqr1 = f(x) = int(x*x/4): If f(x) = x*x/4 then f(x+1) = f(x) + x/2 + 1/4
|
||||
.label sqr = $14
|
||||
.label sqr1_lo = $16
|
||||
// Fill mulf_sqr1 = f(x) = int(x*x/4): If f(x) = x*x/4 then f(x+1) = f(x) + x/2 + 1/4
|
||||
.label sqr = $10
|
||||
.label sqr1_lo = 8
|
||||
// Decrease or increase x_255 - initially we decrease
|
||||
.label sqr2_hi = $10
|
||||
.label sqr2_lo = $c
|
||||
// Decrease or increase x_255 - initially we decrease
|
||||
.label sqr2_hi = $c
|
||||
.label sqr2_lo = $16
|
||||
//Start with g(0)=f(255)
|
||||
//Start with g(0)=f(255)
|
||||
.label dir = $b
|
||||
ldx #0
|
||||
|
@ -3,7 +3,7 @@
|
||||
// The MOS 6526 Complex Interface Adapter (CIA)
|
||||
// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.const VIC_RST8 = $80
|
||||
.const VIC_DEN = $10
|
||||
@ -32,28 +32,29 @@
|
||||
.label COS = SIN+$40
|
||||
// The address of the sprite pointers on the current screen (screen+0x3f8).
|
||||
.label PLEX_SCREEN_PTR = SCREEN+$3f8
|
||||
.label plex_show_idx = $11
|
||||
.label plex_sprite_idx = $12
|
||||
.label plex_sprite_msb = $13
|
||||
.label plex_free_next = $14
|
||||
__bbegin:
|
||||
// plex_show_idx=0
|
||||
// The index in the PLEX tables of the next sprite to show
|
||||
lda #0
|
||||
sta.z plex_show_idx
|
||||
// plex_sprite_idx=0
|
||||
.label plex_show_idx = $11
|
||||
// The index the next sprite to use for showing (sprites are used round-robin)
|
||||
sta.z plex_sprite_idx
|
||||
// plex_sprite_msb=1
|
||||
.label plex_sprite_idx = $12
|
||||
// The MSB bit of the next sprite to use for showing
|
||||
lda #1
|
||||
sta.z plex_sprite_msb
|
||||
// plex_free_next = 0
|
||||
.label plex_sprite_msb = $13
|
||||
// The index of the sprite that is free next. Since sprites are used round-robin this moves forward each time a sprite is shown.
|
||||
lda #0
|
||||
sta.z plex_free_next
|
||||
jsr main
|
||||
rts
|
||||
.label plex_free_next = $14
|
||||
_start: {
|
||||
// plex_show_idx=0
|
||||
lda #0
|
||||
sta.z plex_show_idx
|
||||
// plex_sprite_idx=0
|
||||
sta.z plex_sprite_idx
|
||||
// plex_sprite_msb=1
|
||||
lda #1
|
||||
sta.z plex_sprite_msb
|
||||
// plex_free_next = 0
|
||||
lda #0
|
||||
sta.z plex_free_next
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// asm
|
||||
sei
|
||||
@ -122,6 +123,7 @@ loop: {
|
||||
.label r = 7
|
||||
.label i = 2
|
||||
// Render Rotated BOBs
|
||||
// Render Rotated BOBs
|
||||
.label angle = 4
|
||||
.label plexFreeNextYpos1_return = $15
|
||||
.label i1 = 3
|
||||
@ -623,17 +625,22 @@ memset: {
|
||||
}
|
||||
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
|
||||
mulf_init: {
|
||||
// x/2
|
||||
// x/2
|
||||
.label c = 7
|
||||
// Counter used for determining x%2==0
|
||||
// Counter used for determining x%2==0
|
||||
.label sqr1_hi = 8
|
||||
// Fill mulf_sqr1 = f(x) = int(x*x/4): If f(x) = x*x/4 then f(x+1) = f(x) + x/2 + 1/4
|
||||
// Fill mulf_sqr1 = f(x) = int(x*x/4): If f(x) = x*x/4 then f(x+1) = f(x) + x/2 + 1/4
|
||||
.label sqr = $f
|
||||
.label sqr1_lo = 5
|
||||
// Decrease or increase x_255 - initially we decrease
|
||||
// Decrease or increase x_255 - initially we decrease
|
||||
.label sqr2_hi = $c
|
||||
.label sqr2_lo = $a
|
||||
//Start with g(0)=f(255)
|
||||
//Start with g(0)=f(255)
|
||||
.label dir = $e
|
||||
ldx #0
|
||||
lda #<mulf_sqr1_hi+1
|
||||
|
@ -311,7 +311,9 @@ bitmap_line: {
|
||||
.label dy = $1a
|
||||
.label sx = $20
|
||||
.label sy = $1e
|
||||
// X is the driver
|
||||
.label e1 = 9
|
||||
// Y is the driver
|
||||
.label e = 7
|
||||
.label x1 = $f
|
||||
.label y1 = $11
|
||||
@ -958,8 +960,11 @@ rotate: {
|
||||
.label return_x = 3
|
||||
.label return_y = 5
|
||||
.label cos_a = $18
|
||||
// signed fixed[0.7]
|
||||
.label xr = $1a
|
||||
// signed fixed[8.8]
|
||||
.label yr = $1c
|
||||
// signed fixed[8.8]
|
||||
.label sin_a = $18
|
||||
// cos_a = (signed int) COS[angle]
|
||||
lda COS,y
|
||||
@ -1404,17 +1409,22 @@ bitmap_init: {
|
||||
}
|
||||
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
|
||||
mulf_init: {
|
||||
// x/2
|
||||
// x/2
|
||||
.label c = $26
|
||||
// Counter used for determining x%2==0
|
||||
// Counter used for determining x%2==0
|
||||
.label sqr1_hi = $16
|
||||
// Fill mulf_sqr1 = f(x) = int(x*x/4): If f(x) = x*x/4 then f(x+1) = f(x) + x/2 + 1/4
|
||||
// Fill mulf_sqr1 = f(x) = int(x*x/4): If f(x) = x*x/4 then f(x+1) = f(x) + x/2 + 1/4
|
||||
.label sqr = $18
|
||||
.label sqr1_lo = $14
|
||||
// Decrease or increase x_255 - initially we decrease
|
||||
// Decrease or increase x_255 - initially we decrease
|
||||
.label sqr2_hi = $20
|
||||
.label sqr2_lo = $1c
|
||||
//Start with g(0)=f(255)
|
||||
//Start with g(0)=f(255)
|
||||
.label dir = $13
|
||||
ldx #0
|
||||
lda #<mulf_sqr1_hi+1
|
||||
|
@ -3,7 +3,7 @@
|
||||
// The MOS 6526 Complex Interface Adapter (CIA)
|
||||
// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
|
||||
.const CIA_INTERRUPT_CLEAR = $7f
|
||||
@ -17,7 +17,8 @@
|
||||
// The number of sprites in the multiplexer
|
||||
.const PLEX_COUNT = $20
|
||||
.const OFFSET_STRUCT_MOS6526_CIA_INTERRUPT = $d
|
||||
.const toSpritePtr1_return = SPRITES/$40
|
||||
// Sprite pointer for sprite 0
|
||||
.const SPRITE_0 = SPRITES/$40
|
||||
.label SPRITES_XPOS = $d000
|
||||
.label SPRITES_YPOS = $d001
|
||||
.label SPRITES_XMSB = $d010
|
||||
@ -43,44 +44,45 @@
|
||||
.label SCREEN = $400
|
||||
// The high-value table
|
||||
.label XMOVEMENT_HI = XMOVEMENT+$100
|
||||
// The address of the sprite pointers on the current screen (screen+0x3f8).
|
||||
.label PLEX_SCREEN_PTR = $400+$3f8
|
||||
.label plex_show_idx = $d
|
||||
.label plex_sprite_idx = $e
|
||||
.label plex_sprite_msb = $f
|
||||
.label plex_free_next = $10
|
||||
.label frame_done = $11
|
||||
// The next char to use from the scroll text
|
||||
.label scroll_text_next = 4
|
||||
// Y-sine index
|
||||
.label y_sin_idx = 2
|
||||
// X-movement index
|
||||
.label x_movement_idx = 3
|
||||
__bbegin:
|
||||
// plex_show_idx=0
|
||||
// The index in the PLEX tables of the next sprite to show
|
||||
lda #0
|
||||
sta.z plex_show_idx
|
||||
// plex_sprite_idx=0
|
||||
.label plex_show_idx = $10
|
||||
// The index the next sprite to use for showing (sprites are used round-robin)
|
||||
sta.z plex_sprite_idx
|
||||
// plex_sprite_msb=1
|
||||
.label plex_sprite_idx = $11
|
||||
// The MSB bit of the next sprite to use for showing
|
||||
lda #1
|
||||
sta.z plex_sprite_msb
|
||||
// plex_free_next = 0
|
||||
.label plex_sprite_msb = $12
|
||||
// The index of the sprite that is free next. Since sprites are used round-robin this moves forward each time a sprite is shown.
|
||||
lda #0
|
||||
sta.z plex_free_next
|
||||
// frame_done = false
|
||||
.label plex_free_next = $13
|
||||
// Signal used between IRQ and main loop. Set to true when the IRQ is done showing the sprites.
|
||||
sta.z frame_done
|
||||
jsr main
|
||||
rts
|
||||
.label frame_done = $14
|
||||
// The next char to use from the scroll text
|
||||
.label scroll_text_next = 5
|
||||
// Y-sine index
|
||||
.label y_sin_idx = 3
|
||||
// X-movement index
|
||||
.label x_movement_idx = 4
|
||||
// The address of the sprite pointers on the current screen (screen+0x3f8).
|
||||
.label PLEX_SCREEN_PTR = $e
|
||||
_start: {
|
||||
// plex_show_idx=0
|
||||
lda #0
|
||||
sta.z plex_show_idx
|
||||
// plex_sprite_idx=0
|
||||
sta.z plex_sprite_idx
|
||||
// plex_sprite_msb=1
|
||||
lda #1
|
||||
sta.z plex_sprite_msb
|
||||
// plex_free_next = 0
|
||||
lda #0
|
||||
sta.z plex_free_next
|
||||
// frame_done = false
|
||||
sta.z frame_done
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.const toD0181_return = (>(SCREEN&$3fff)*4)|(>CHARSET_DEFAULT)/4&$f
|
||||
.label s = 2
|
||||
.label __13 = $12
|
||||
.label __13 = $15
|
||||
// asm
|
||||
// Create 2x2 font from CHARGEN
|
||||
sei
|
||||
@ -189,7 +191,7 @@ main: {
|
||||
jmp __b6
|
||||
__b2:
|
||||
// PLEX_PTR[s] = SPRITE_0+' '
|
||||
lda #toSpritePtr1_return+' '
|
||||
lda #SPRITE_0+' '
|
||||
ldy.z s
|
||||
sta PLEX_PTR,y
|
||||
// PLEX_XPOS[s] = { XMOVEMENT_HI[x], XMOVEMENT[x] }
|
||||
@ -220,9 +222,9 @@ main: {
|
||||
// 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 = $14
|
||||
.label nxt_y = $15
|
||||
.label m = $c
|
||||
.label nxt_idx = $17
|
||||
.label nxt_y = $18
|
||||
.label m = $d
|
||||
lda #0
|
||||
sta.z m
|
||||
__b1:
|
||||
@ -289,10 +291,10 @@ plexSort: {
|
||||
}
|
||||
// Move the plex sprites in an Y-sine and scroll them to the left.
|
||||
plex_move: {
|
||||
.label y_idx = $c
|
||||
.label x_idx = $15
|
||||
.label s = $14
|
||||
.label __7 = $16
|
||||
.label y_idx = $d
|
||||
.label x_idx = $18
|
||||
.label s = $17
|
||||
.label __7 = $19
|
||||
// y_idx = y_sin_idx
|
||||
lda.z y_sin_idx
|
||||
sta.z y_idx
|
||||
@ -339,7 +341,7 @@ plex_move: {
|
||||
sta.z scroll_text_next+1
|
||||
__b3:
|
||||
// SPRITE_0+*scroll_text_next++
|
||||
lda #toSpritePtr1_return
|
||||
lda #SPRITE_0
|
||||
clc
|
||||
ldy #0
|
||||
adc (scroll_text_next),y
|
||||
@ -391,13 +393,14 @@ plexInit: {
|
||||
// - num_chars The number of chars to convert
|
||||
font_2x2_to_sprites: {
|
||||
.const num_chars = $40
|
||||
.label __3 = $18
|
||||
.label char_right = $a
|
||||
.label sprite_idx = $15
|
||||
.label char_left = 8
|
||||
.label char_current = $16
|
||||
.label sprite = 6
|
||||
.label c = $14
|
||||
.label __3 = $1b
|
||||
.label char_right = $b
|
||||
.label sprite_idx = $18
|
||||
// Upper char
|
||||
.label char_left = 9
|
||||
.label char_current = $19
|
||||
.label sprite = 7
|
||||
.label c = $17
|
||||
lda #<SPRITES
|
||||
sta.z sprite
|
||||
lda #>SPRITES
|
||||
@ -519,18 +522,18 @@ font_2x2_to_sprites: {
|
||||
// - 0x80 - 0xbf Lower left glyphs
|
||||
// - 0xc0 - 0xff Lower right glyphs
|
||||
font_2x2: {
|
||||
.label __5 = $12
|
||||
.label __7 = $12
|
||||
.label next_2x2_left = $16
|
||||
.label next_2x2_right = $a
|
||||
.label glyph_bits = $c
|
||||
.label glyph_bits_2x2 = $12
|
||||
.label l2 = $18
|
||||
.label l = $15
|
||||
.label next_2x2_left_1 = 8
|
||||
.label next_2x2 = $16
|
||||
.label next_original = 6
|
||||
.label c = $14
|
||||
.label __5 = $15
|
||||
.label __7 = $15
|
||||
.label next_2x2_left = $19
|
||||
.label next_2x2_right = $b
|
||||
.label glyph_bits = $d
|
||||
.label glyph_bits_2x2 = $15
|
||||
.label l2 = $1b
|
||||
.label l = $18
|
||||
.label next_2x2_left_1 = 9
|
||||
.label next_2x2 = $19
|
||||
.label next_original = 7
|
||||
.label c = $17
|
||||
lda #0
|
||||
sta.z c
|
||||
lda #<CHARGEN
|
||||
@ -679,7 +682,7 @@ font_2x2: {
|
||||
}
|
||||
// Show sprites from the multiplexer, rescheduling the IRQ as many times as needed
|
||||
plex_irq: {
|
||||
.label __4 = $19
|
||||
.label __4 = $1c
|
||||
// asm
|
||||
sei
|
||||
__b3:
|
||||
@ -731,7 +734,7 @@ plex_irq: {
|
||||
// Show the next sprite.
|
||||
// plexSort() prepares showing the sprites
|
||||
plexShowSprite: {
|
||||
.label plex_sprite_idx2 = $1a
|
||||
.label plex_sprite_idx2 = $1d
|
||||
// plex_sprite_idx2 = plex_sprite_idx*2
|
||||
lda.z plex_sprite_idx
|
||||
asl
|
||||
@ -760,8 +763,8 @@ plexShowSprite: {
|
||||
// PLEX_SCREEN_PTR[plex_sprite_idx] = PLEX_PTR[PLEX_SORTED_IDX[plex_show_idx]]
|
||||
ldy PLEX_SORTED_IDX,x
|
||||
lda PLEX_PTR,y
|
||||
ldx.z plex_sprite_idx
|
||||
sta PLEX_SCREEN_PTR,x
|
||||
ldy.z plex_sprite_idx
|
||||
sta (PLEX_SCREEN_PTR),y
|
||||
// xpos_idx = PLEX_SORTED_IDX[plex_show_idx]
|
||||
ldy.z plex_show_idx
|
||||
lda PLEX_SORTED_IDX,y
|
||||
|
@ -4,7 +4,7 @@
|
||||
// The MOS 6526 Complex Interface Adapter (CIA)
|
||||
// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
|
||||
.const CIA_INTERRUPT_CLEAR = $7f
|
||||
@ -24,7 +24,6 @@
|
||||
.const IRQ_RASTER_FIRST = SPRITES_FIRST_YPOS+$13
|
||||
.const OFFSET_STRUCT_MOS6526_CIA_PORT_A_DDR = 2
|
||||
.const OFFSET_STRUCT_MOS6526_CIA_INTERRUPT = $d
|
||||
.const toSpritePtr1_return = PLAYFIELD_SPRITES/$40
|
||||
.label SPRITES_XPOS = $d000
|
||||
.label SPRITES_YPOS = $d001
|
||||
.label SPRITES_COLOR = $d027
|
||||
@ -59,48 +58,43 @@
|
||||
.label PLAYFIELD_SPRITE_PTRS_1 = PLAYFIELD_SCREEN_1+SPRITE_PTRS
|
||||
// Screen Sprite pointers on screen 2
|
||||
.label PLAYFIELD_SPRITE_PTRS_2 = PLAYFIELD_SCREEN_2+SPRITE_PTRS
|
||||
// Address of the sprites covering the playfield
|
||||
.label PLAYFIELD_SPRITES = $3000
|
||||
// Address of the charset
|
||||
.label PLAYFIELD_CHARSET = $2800
|
||||
.label SIN_SPRITE = $2800
|
||||
.label render_screen_showing = 5
|
||||
.label irq_raster_next = 6
|
||||
.label irq_sprite_ypos = 7
|
||||
.label irq_sprite_ptr = 8
|
||||
.label irq_cnt = 9
|
||||
.label sin_idx = 3
|
||||
__bbegin:
|
||||
// render_screen_showing = 0
|
||||
// The screen currently being showed to the user. 0x00 for screen 1 / 0x20 for screen 2.
|
||||
lda #0
|
||||
sta.z render_screen_showing
|
||||
// kickasm
|
||||
// irq_raster_next = IRQ_RASTER_FIRST
|
||||
.label render_screen_showing = 6
|
||||
// The raster line of the next IRQ
|
||||
lda #IRQ_RASTER_FIRST
|
||||
sta.z irq_raster_next
|
||||
// irq_sprite_ypos = SPRITES_FIRST_YPOS + 21
|
||||
.label irq_raster_next = 7
|
||||
// Y-pos of the sprites on the next IRQ
|
||||
lda #SPRITES_FIRST_YPOS+$15
|
||||
sta.z irq_sprite_ypos
|
||||
// irq_sprite_ptr = toSpritePtr(PLAYFIELD_SPRITES) + 3
|
||||
.label irq_sprite_ypos = 8
|
||||
// Index of the sprites to show on the next IRQ
|
||||
lda #toSpritePtr1_return+3
|
||||
sta.z irq_sprite_ptr
|
||||
// irq_cnt = 0
|
||||
.label irq_sprite_ptr = 9
|
||||
// Counting the 10 IRQs
|
||||
lda #0
|
||||
sta.z irq_cnt
|
||||
// kickasm
|
||||
jsr main
|
||||
rts
|
||||
.label irq_cnt = $a
|
||||
.label sin_idx = 4
|
||||
_start: {
|
||||
.const _init1_toSpritePtr1_return = $ff&PLAYFIELD_SPRITES/$40
|
||||
// render_screen_showing = 0
|
||||
lda #0
|
||||
sta.z render_screen_showing
|
||||
// irq_raster_next = IRQ_RASTER_FIRST
|
||||
lda #IRQ_RASTER_FIRST
|
||||
sta.z irq_raster_next
|
||||
// irq_sprite_ypos = SPRITES_FIRST_YPOS + 21
|
||||
lda #SPRITES_FIRST_YPOS+$15
|
||||
sta.z irq_sprite_ypos
|
||||
// irq_sprite_ptr = toSpritePtr(PLAYFIELD_SPRITES) + 3
|
||||
lda #_init1_toSpritePtr1_return+3
|
||||
sta.z irq_sprite_ptr
|
||||
// irq_cnt = 0
|
||||
lda #0
|
||||
sta.z irq_cnt
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.const toSpritePtr1_return = SIN_SPRITE/$40
|
||||
.const toSpritePtr1_return = $ff&SIN_SPRITE/$40
|
||||
.const vicSelectGfxBank1_toDd001_return = 3
|
||||
.const toD0181_return = (>(PLAYFIELD_SCREEN_1&$3fff)*4)|(>PLAYFIELD_CHARSET)/4&$f
|
||||
.label xpos = 3
|
||||
.label ypos = 2
|
||||
.label xpos = 2
|
||||
.label ypos = 3
|
||||
// CIA2->PORT_A_DDR = %00000011
|
||||
lda #3
|
||||
sta CIA2+OFFSET_STRUCT_MOS6526_CIA_PORT_A_DDR
|
||||
@ -160,7 +154,7 @@ main: {
|
||||
rts
|
||||
}
|
||||
loop: {
|
||||
.label s = 4
|
||||
.label s = 5
|
||||
lda #0
|
||||
sta.z sin_idx
|
||||
__b2:
|
||||
@ -238,7 +232,7 @@ sprites_irq_init: {
|
||||
}
|
||||
// Setup the sprites
|
||||
sprites_init: {
|
||||
.label xpos = 4
|
||||
.label xpos = 5
|
||||
// *SPRITES_ENABLE = %00001111
|
||||
lda #$f
|
||||
sta SPRITES_ENABLE
|
||||
@ -278,8 +272,9 @@ sprites_init: {
|
||||
// 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 toSpritePtr1_return = PLAYFIELD_SPRITES/$40
|
||||
.label raster_sprite_gfx_modify = $a
|
||||
.const toSpritePtr1_return = $ff&PLAYFIELD_SPRITES/$40
|
||||
// Wait for the y-position before changing sprite pointers
|
||||
.label raster_sprite_gfx_modify = $b
|
||||
sta rega+1
|
||||
stx regx+1
|
||||
// asm
|
||||
@ -416,9 +411,11 @@ SIN:
|
||||
.byte 51+AMPL/2+sin(toRadians([i*360]/256))*AMPL/2
|
||||
}
|
||||
|
||||
.pc = PLAYFIELD_SPRITES "PLAYFIELD_SPRITES"
|
||||
.var sprites = LoadPicture("playfield-sprites.png", List().add($010101, $000000))
|
||||
// Put the sprites into memory
|
||||
.pc = $3000 "PLAYFIELD_SPRITES"
|
||||
// Sprites covering the playfield
|
||||
PLAYFIELD_SPRITES:
|
||||
.var sprites = LoadPicture("playfield-sprites.png", List().add($010101, $000000))
|
||||
// Put the sprites into memory
|
||||
.for(var sy=0;sy<10;sy++) {
|
||||
.var sprite_gfx_y = sy*20
|
||||
.for(var sx=0;sx<3;sx++) {
|
||||
@ -432,6 +429,13 @@ SIN:
|
||||
}
|
||||
}
|
||||
|
||||
.pc = SIN_SPRITE "SIN_SPRITE"
|
||||
.fill $40, $ff
|
||||
.pc = $2800 "PLAYFIELD_CHARSET"
|
||||
// Address of the charset
|
||||
PLAYFIELD_CHARSET:
|
||||
.fill 8,$00 // Place a filled char at the start of the charset
|
||||
.import binary "playfield-screen.imap"
|
||||
|
||||
.pc = $3800 "SIN_SPRITE"
|
||||
SIN_SPRITE:
|
||||
.fill $40, $ff
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// The tetris game tries to match NES tetris gameplay pretty closely
|
||||
// Source: https://meatfighter.com/nintendotetrisai/
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
|
||||
.const CIA_INTERRUPT_CLEAR = $7f
|
||||
@ -66,7 +66,6 @@
|
||||
.const OFFSET_STRUCT_MOS6581_SID_CH3_OSC = $1b
|
||||
.const OFFSET_STRUCT_MOS6526_CIA_PORT_B = 1
|
||||
.const OFFSET_STRUCT_MOS6526_CIA_INTERRUPT = $d
|
||||
.const toSpritePtr1_return = PLAYFIELD_SPRITES/$40
|
||||
.label SPRITES_XPOS = $d000
|
||||
.label SPRITES_YPOS = $d001
|
||||
.label SPRITES_COLOR = $d027
|
||||
@ -111,23 +110,25 @@
|
||||
.label PLAYFIELD_SPRITE_PTRS_1 = PLAYFIELD_SCREEN_1+SPRITE_PTRS
|
||||
// Screen Sprite pointers on screen 2
|
||||
.label PLAYFIELD_SPRITE_PTRS_2 = PLAYFIELD_SCREEN_2+SPRITE_PTRS
|
||||
// Address of the sprites covering the playfield
|
||||
.label PLAYFIELD_SPRITES = $3000
|
||||
// Address of the charset
|
||||
.label PLAYFIELD_CHARSET = $2800
|
||||
.label render_screen_showing = $26
|
||||
.label score_bcd = $27
|
||||
.label irq_raster_next = $2b
|
||||
.label irq_sprite_ypos = $2c
|
||||
.label irq_sprite_ptr = $2d
|
||||
.label irq_cnt = $2e
|
||||
// The screen currently being showed to the user. 0x00 for screen 1 / 0x20 for screen 2.
|
||||
.label render_screen_showing = $22
|
||||
// Current score in BCD-format
|
||||
.label score_bcd = $23
|
||||
// The raster line of the next IRQ
|
||||
.label irq_raster_next = $27
|
||||
// Y-pos of the sprites on the next IRQ
|
||||
.label irq_sprite_ypos = $28
|
||||
// Index of the sprites to show on the next IRQ
|
||||
.label irq_sprite_ptr = $29
|
||||
// Counting the 10 IRQs
|
||||
.label irq_cnt = $2a
|
||||
// Keyboard event buffer size. The number of events currently in the event buffer
|
||||
.label keyboard_events_size = $20
|
||||
.label keyboard_events_size = $21
|
||||
// The rate of moving down the current piece (number of frames between moves if movedown is not forced)
|
||||
.label current_movedown_slow = $11
|
||||
.label current_ypos = $d
|
||||
// Position of top left corner of current moving piece on the playfield
|
||||
.label current_xpos = $19
|
||||
.label current_ypos = $d
|
||||
// The curent piece orientation - each piece have 4 orientations (00/0x10/0x20/0x30).
|
||||
// The orientation chooses one of the 4 sub-graphics of the piece.
|
||||
.label current_orientation = $16
|
||||
@ -137,14 +138,6 @@
|
||||
.label current_piece_char = $15
|
||||
// Current level BCD-format
|
||||
.label level_bcd = $12
|
||||
// The current moving piece. Points to the start of the piece definition.
|
||||
.label current_piece = $13
|
||||
// Is the game over?
|
||||
.label game_over = $1b
|
||||
// The index of the next moving piece. (0-6)
|
||||
.label next_piece_idx = $1a
|
||||
// Current level in normal (non-BCD) format
|
||||
.label level = $10
|
||||
// The screen currently being rendered to. 0x00 for screen 1 / 0x20 for screen 2.
|
||||
.label render_screen_render = 3
|
||||
// The screen currently to show next to the user. 0x00 for screen 1 / 0x20 for screen 2.
|
||||
@ -154,6 +147,14 @@
|
||||
.label current_movedown_counter = 4
|
||||
// Current number of cleared lines in BCD-format
|
||||
.label lines_bcd = $e
|
||||
// Current level in normal (non-BCD) format
|
||||
.label level = $10
|
||||
// The current moving piece. Points to the start of the piece definition.
|
||||
.label current_piece = $13
|
||||
// Is the game over?
|
||||
.label game_over = $1b
|
||||
// The index of the next moving piece. (0-6)
|
||||
.label next_piece_idx = $1a
|
||||
// The current moving piece. Points to the start of the piece definition.
|
||||
.label current_piece_1 = $a
|
||||
// The screen currently being rendered to. 0x00 for screen 1 / 0x20 for screen 2.
|
||||
@ -164,40 +165,33 @@
|
||||
.label current_piece_gfx_1 = 7
|
||||
// The char of the current piece
|
||||
.label current_piece_char_1 = 9
|
||||
__bbegin:
|
||||
// render_screen_showing = 0
|
||||
// The screen currently being showed to the user. 0x00 for screen 1 / 0x20 for screen 2.
|
||||
lda #0
|
||||
sta.z render_screen_showing
|
||||
// score_bcd = 0
|
||||
// Current score in BCD-format
|
||||
sta.z score_bcd
|
||||
sta.z score_bcd+1
|
||||
lda #<0>>$10
|
||||
sta.z score_bcd+2
|
||||
lda #>0>>$10
|
||||
sta.z score_bcd+3
|
||||
// kickasm
|
||||
// Tetris Game for the Commodore 64
|
||||
// A sprite multiplexer covering the playfield with a black layer to allow for 3 single-pixel colors
|
||||
// irq_raster_next = IRQ_RASTER_FIRST
|
||||
// The raster line of the next IRQ
|
||||
lda #IRQ_RASTER_FIRST
|
||||
sta.z irq_raster_next
|
||||
// irq_sprite_ypos = SPRITES_FIRST_YPOS + 21
|
||||
// Y-pos of the sprites on the next IRQ
|
||||
lda #SPRITES_FIRST_YPOS+$15
|
||||
sta.z irq_sprite_ypos
|
||||
// irq_sprite_ptr = toSpritePtr(PLAYFIELD_SPRITES) + 3
|
||||
// Index of the sprites to show on the next IRQ
|
||||
lda #toSpritePtr1_return+3
|
||||
sta.z irq_sprite_ptr
|
||||
// irq_cnt = 0
|
||||
// Counting the 10 IRQs
|
||||
lda #0
|
||||
sta.z irq_cnt
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
.const _init1_toSpritePtr1_return = $ff&PLAYFIELD_SPRITES/$40
|
||||
// render_screen_showing = 0
|
||||
lda #0
|
||||
sta.z render_screen_showing
|
||||
// score_bcd = 0
|
||||
sta.z score_bcd
|
||||
sta.z score_bcd+1
|
||||
lda #<0>>$10
|
||||
sta.z score_bcd+2
|
||||
lda #>0>>$10
|
||||
sta.z score_bcd+3
|
||||
// irq_raster_next = IRQ_RASTER_FIRST
|
||||
lda #IRQ_RASTER_FIRST
|
||||
sta.z irq_raster_next
|
||||
// irq_sprite_ypos = SPRITES_FIRST_YPOS + 21
|
||||
lda #SPRITES_FIRST_YPOS+$15
|
||||
sta.z irq_sprite_ypos
|
||||
// irq_sprite_ptr = toSpritePtr(PLAYFIELD_SPRITES) + 3
|
||||
lda #_init1_toSpritePtr1_return+3
|
||||
sta.z irq_sprite_ptr
|
||||
// irq_cnt = 0
|
||||
lda #0
|
||||
sta.z irq_cnt
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// SID->CH3_FREQ = 0xffff
|
||||
lda #<$ffff
|
||||
@ -347,7 +341,7 @@ render_score: {
|
||||
.const lines_offset = $28*1+$16
|
||||
.const level_offset = $28*$13+$1f
|
||||
.label score_bytes = score_bcd
|
||||
.label screen = 7
|
||||
.label screen = $2c
|
||||
// if(render_screen_render==0)
|
||||
lda.z render_screen_render
|
||||
cmp #0
|
||||
@ -419,12 +413,12 @@ render_score: {
|
||||
// - offset: offset on the screen
|
||||
// - bcd: The BCD-value to render
|
||||
// - only_low: if non-zero only renders the low digit
|
||||
// render_bcd(byte* zp(7) screen, word zp($a) offset, byte register(X) bcd, byte register(Y) only_low)
|
||||
// render_bcd(byte* zp($2c) screen, word zp($2e) offset, byte register(X) bcd, byte register(Y) only_low)
|
||||
render_bcd: {
|
||||
.const ZERO_CHAR = $35
|
||||
.label screen = 7
|
||||
.label screen_pos = $a
|
||||
.label offset = $a
|
||||
.label screen = $2c
|
||||
.label screen_pos = $2e
|
||||
.label offset = $2e
|
||||
// screen_pos = screen+offset
|
||||
lda.z screen_pos
|
||||
clc
|
||||
@ -468,12 +462,14 @@ render_bcd: {
|
||||
}
|
||||
// Render the next tetromino in the "next" area
|
||||
render_next: {
|
||||
// Find the screen area
|
||||
// Find the screen area
|
||||
.const next_area_offset = $28*$c+$18+4
|
||||
.label next_piece_char = $3b
|
||||
.label next_piece_gfx = 7
|
||||
.label screen_next_area = $a
|
||||
.label l = 5
|
||||
.label next_piece_char = $32
|
||||
// Render the next piece
|
||||
.label next_piece_gfx = $2c
|
||||
.label screen_next_area = $2e
|
||||
.label l = $c
|
||||
// if(render_screen_render==0)
|
||||
cpx #0
|
||||
beq __b1
|
||||
@ -554,8 +550,8 @@ render_next: {
|
||||
// Ignores cases where parts of the tetromino is outside the playfield (sides/bottom) since the movement collision routine prevents this.
|
||||
render_moving: {
|
||||
.label ypos = $c
|
||||
.label screen_line = $30
|
||||
.label xpos = $21
|
||||
.label screen_line = $2c
|
||||
.label xpos = $1e
|
||||
.label i = $1d
|
||||
.label l = $1c
|
||||
// ypos = current_ypos
|
||||
@ -621,11 +617,12 @@ render_moving: {
|
||||
}
|
||||
// Render the static playfield on the screen (all pieces already locked into place)
|
||||
render_playfield: {
|
||||
.label screen_line = $a
|
||||
.label screen_line = $2c
|
||||
// Do not render the top 2 lines.
|
||||
.label i = $1c
|
||||
.label c = $1d
|
||||
.label l = $c
|
||||
// Do not render the top 2 lines.
|
||||
.label i = $1d
|
||||
.label c = $1e
|
||||
.label l = $1c
|
||||
lda #PLAYFIELD_COLS*2
|
||||
sta.z i
|
||||
lda #2
|
||||
@ -672,11 +669,11 @@ render_playfield: {
|
||||
// Perform any movement of the current piece
|
||||
// key_event is the next keyboard_event() og 0xff if no keyboard event is pending
|
||||
// Returns a byte signaling whether rendering is needed. (0 no render, >0 render needed)
|
||||
// play_movement(byte zp($2f) key_event)
|
||||
// play_movement(byte zp($2b) key_event)
|
||||
play_movement: {
|
||||
.label render = $21
|
||||
.label return = $21
|
||||
.label key_event = $2f
|
||||
.label render = $1f
|
||||
.label return = $1f
|
||||
.label key_event = $2b
|
||||
// play_move_down(key_event)
|
||||
lda.z key_event
|
||||
jsr play_move_down
|
||||
@ -710,6 +707,7 @@ play_movement: {
|
||||
// Return non-zero if a render is needed
|
||||
// play_move_rotate(byte register(A) key_event)
|
||||
play_move_rotate: {
|
||||
// Handle keyboard events
|
||||
// Handle keyboard events
|
||||
.label orientation = $c
|
||||
// if(key_event==KEY_Z)
|
||||
@ -774,21 +772,21 @@ play_move_rotate: {
|
||||
play_collision: {
|
||||
.label xpos = $1c
|
||||
.label ypos = $1d
|
||||
.label piece_gfx = $a
|
||||
.label piece_gfx = $2e
|
||||
.label yp = $1d
|
||||
.label playfield_line = $32
|
||||
.label i = $3b
|
||||
.label xp = $3c
|
||||
.label playfield_line = $30
|
||||
.label i = $32
|
||||
.label xp = $3b
|
||||
.label l = $1e
|
||||
.label i_1 = $1f
|
||||
.label i_1 = $20
|
||||
// piece_gfx = current_piece + orientation
|
||||
txa
|
||||
clc
|
||||
adc.z piece_gfx
|
||||
adc.z current_piece_1
|
||||
sta.z piece_gfx
|
||||
bcc !+
|
||||
inc.z piece_gfx+1
|
||||
!:
|
||||
lda #0
|
||||
adc.z current_piece_1+1
|
||||
sta.z piece_gfx+1
|
||||
lda #0
|
||||
sta.z l
|
||||
sta.z i_1
|
||||
@ -1030,7 +1028,9 @@ play_move_down: {
|
||||
// Spawn a new piece
|
||||
// Moves the next piece into the current and spawns a new next piece
|
||||
play_spawn_current: {
|
||||
.label __7 = $34
|
||||
.label __7 = $33
|
||||
// Spawn a new next piece
|
||||
// Pick a random piece (0-6)
|
||||
// Spawn a new next piece
|
||||
// Pick a random piece (0-6)
|
||||
.label piece_idx = $1a
|
||||
@ -1090,8 +1090,8 @@ play_spawn_current: {
|
||||
// Update the score based on the number of lines removed
|
||||
// play_update_score(byte register(X) removed)
|
||||
play_update_score: {
|
||||
.label lines_before = $34
|
||||
.label add_bcd = $35
|
||||
.label lines_before = $33
|
||||
.label add_bcd = $34
|
||||
// if(removed!=0)
|
||||
cpx #0
|
||||
beq __breturn
|
||||
@ -1221,11 +1221,11 @@ play_increase_level: {
|
||||
// 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 = $3b
|
||||
.label c = $3a
|
||||
.label x = $1e
|
||||
.label y = $1c
|
||||
.label removed = $1d
|
||||
.label full = $1f
|
||||
.label full = $20
|
||||
lda #0
|
||||
sta.z removed
|
||||
sta.z y
|
||||
@ -1290,13 +1290,15 @@ play_remove_lines: {
|
||||
}
|
||||
// Lock the current piece onto the playfield
|
||||
play_lock_current: {
|
||||
.label yp = $d
|
||||
.label playfield_line = $39
|
||||
.label xp = $1f
|
||||
.label i = $3b
|
||||
.label l = $3c
|
||||
.label i_1 = $1e
|
||||
.label yp = $3b
|
||||
.label playfield_line = $38
|
||||
.label xp = $33
|
||||
.label i = $3a
|
||||
.label l = $20
|
||||
.label i_1 = $32
|
||||
// yp = current_ypos
|
||||
lda.z current_ypos
|
||||
sta.z yp
|
||||
lda #0
|
||||
sta.z l
|
||||
sta.z i_1
|
||||
@ -1396,9 +1398,9 @@ 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 = $3c
|
||||
.label keycode = $1f
|
||||
.label row = $1e
|
||||
.label row_scan = $3b
|
||||
.label keycode = $20
|
||||
.label row = $1f
|
||||
lda #0
|
||||
sta.z keycode
|
||||
sta.z row
|
||||
@ -1549,9 +1551,10 @@ render_show: {
|
||||
}
|
||||
// Initialize play data tables
|
||||
play_init: {
|
||||
.label pli = $22
|
||||
.label pli = $2c
|
||||
// Initialize the playfield line pointers;
|
||||
.label idx = $21
|
||||
// Initialize the playfield line pointers;
|
||||
.label idx = $32
|
||||
lda #0
|
||||
sta.z idx
|
||||
lda #<playfield
|
||||
@ -1663,7 +1666,7 @@ sprites_irq_init: {
|
||||
}
|
||||
// Setup the sprites
|
||||
sprites_init: {
|
||||
.label xpos = $21
|
||||
.label xpos = $33
|
||||
// *SPRITES_ENABLE = %00001111
|
||||
lda #$f
|
||||
sta SPRITES_ENABLE
|
||||
@ -1701,10 +1704,11 @@ sprites_init: {
|
||||
}
|
||||
// Initialize rendering
|
||||
render_init: {
|
||||
.const vicSelectGfxBank1_toDd001_return = 3
|
||||
.const vicSelectGfxBank1_toDd001_return = 3^(>PLAYFIELD_CHARSET)/$40
|
||||
// Initialize the screen line pointers;
|
||||
.label li_1 = $22
|
||||
.label li_2 = $30
|
||||
// Initialize the screen line pointers;
|
||||
.label li_1 = $2c
|
||||
.label li_2 = $2e
|
||||
// CIA2->PORT_A_DDR = %00000011
|
||||
lda #3
|
||||
sta CIA2+OFFSET_STRUCT_MOS6526_CIA_PORT_A_DDR
|
||||
@ -1790,14 +1794,14 @@ render_init: {
|
||||
}
|
||||
// Copy the original screen data to the passed screen
|
||||
// Also copies colors to 0xd800
|
||||
// render_screen_original(byte* zp($30) screen)
|
||||
// render_screen_original(byte* zp($2e) screen)
|
||||
render_screen_original: {
|
||||
.const SPACE = 0
|
||||
.label screen = $30
|
||||
.label cols = $24
|
||||
.label oscr = $32
|
||||
.label ocols = $39
|
||||
.label y = $2f
|
||||
.label screen = $2e
|
||||
.label cols = $2c
|
||||
.label oscr = $30
|
||||
.label ocols = $38
|
||||
.label y = $2b
|
||||
lda #0
|
||||
sta.z y
|
||||
lda #<PLAYFIELD_COLORS_ORIGINAL+$20*2
|
||||
@ -1903,8 +1907,9 @@ render_screen_original: {
|
||||
// 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 toSpritePtr1_return = PLAYFIELD_SPRITES/$40
|
||||
.label raster_sprite_gfx_modify = $3d
|
||||
.const toSpritePtr1_return = $ff&PLAYFIELD_SPRITES/$40
|
||||
// Wait for the y-position before changing sprite pointers
|
||||
.label raster_sprite_gfx_modify = $3c
|
||||
sta rega+1
|
||||
stx regx+1
|
||||
// asm
|
||||
@ -2113,13 +2118,11 @@ PLAYFIELD_COLORS_ORIGINAL:
|
||||
// Score values for removing 0-4 lines (in BCD)
|
||||
// These values are updated based on the players level and the base values from SCORE_BASE_BCD
|
||||
score_add_bcd: .fill 4*5, 0
|
||||
.pc = PLAYFIELD_CHARSET "PLAYFIELD_CHARSET"
|
||||
.fill 8,$00 // Place a filled char at the start of the charset
|
||||
.import binary "playfield-screen.imap"
|
||||
|
||||
.pc = PLAYFIELD_SPRITES "PLAYFIELD_SPRITES"
|
||||
.var sprites = LoadPicture("playfield-sprites.png", List().add($010101, $000000))
|
||||
// Put the sprites into memory
|
||||
.pc = $3000 "PLAYFIELD_SPRITES"
|
||||
// Sprites covering the playfield
|
||||
PLAYFIELD_SPRITES:
|
||||
.var sprites = LoadPicture("playfield-sprites.png", List().add($010101, $000000))
|
||||
// Put the sprites into memory
|
||||
.for(var sy=0;sy<10;sy++) {
|
||||
.var sprite_gfx_y = sy*20
|
||||
.for(var sx=0;sx<3;sx++) {
|
||||
@ -2133,3 +2136,9 @@ PLAYFIELD_COLORS_ORIGINAL:
|
||||
}
|
||||
}
|
||||
|
||||
.pc = $2800 "PLAYFIELD_CHARSET"
|
||||
// Address of the charset
|
||||
PLAYFIELD_CHARSET:
|
||||
.fill 8,$00 // Place a filled char at the start of the charset
|
||||
.import binary "playfield-screen.imap"
|
||||
|
||||
|
@ -18,7 +18,22 @@
|
||||
.label BG_COLOR = $d021
|
||||
.label COLS = $d800
|
||||
.segment Code
|
||||
syscall2: {
|
||||
// *(SCREEN+78) = '<'
|
||||
lda #'<'
|
||||
sta SCREEN+$4e
|
||||
// }
|
||||
rts
|
||||
}
|
||||
syscall1: {
|
||||
// *(SCREEN+79) = '>'
|
||||
lda #'>'
|
||||
sta SCREEN+$4f
|
||||
// }
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// Print message
|
||||
// Print message
|
||||
.label sc = 4
|
||||
.label msg = 2
|
||||
@ -124,20 +139,6 @@ memset: {
|
||||
!:
|
||||
jmp __b2
|
||||
}
|
||||
syscall2: {
|
||||
// *(SCREEN+78) = '<'
|
||||
lda #'<'
|
||||
sta SCREEN+$4e
|
||||
// }
|
||||
rts
|
||||
}
|
||||
syscall1: {
|
||||
// *(SCREEN+79) = '>'
|
||||
lda #'>'
|
||||
sta SCREEN+$4f
|
||||
// }
|
||||
rts
|
||||
}
|
||||
.segment Data
|
||||
MESSAGE: .text "hello world!"
|
||||
.byte 0
|
||||
|
@ -3,6 +3,7 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// Create pointers to the palette RGBs in the logo (assumes dimensions are 128x128)
|
||||
// Create pointers to the palette RGBs in the logo (assumes dimensions are 128x128)
|
||||
.label LOGO256_RED = LOGO256+$80*$80
|
||||
.label LOGO256_GREEN = LOGO256_RED+$100
|
||||
|
@ -1,16 +1,17 @@
|
||||
// Tests that constants are identified early
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
.label A = 2
|
||||
__bbegin:
|
||||
// A = 'a'
|
||||
// Not an early constant (address-of is used)
|
||||
lda #'a'
|
||||
sta.z A
|
||||
jsr main
|
||||
rts
|
||||
.label A = 2
|
||||
_start: {
|
||||
// A = 'a'
|
||||
lda #'a'
|
||||
sta.z A
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.const B = 'b'
|
||||
.label addrA = A
|
||||
|
@ -6,6 +6,7 @@
|
||||
.const GREEN = 5
|
||||
.const RED = 2
|
||||
.label BG_COLOR = $d021
|
||||
.label print_screen = $400
|
||||
.label print_char_cursor = 2
|
||||
.label print_line_cursor = 4
|
||||
main: {
|
||||
@ -192,16 +193,16 @@ test_bytes: {
|
||||
.const bc = 2
|
||||
.const bd = bc-4
|
||||
// assert_byte("0=0", bb, 0)
|
||||
lda #<$400
|
||||
lda #<print_screen
|
||||
sta.z print_line_cursor
|
||||
lda #>$400
|
||||
lda #>print_screen
|
||||
sta.z print_line_cursor+1
|
||||
lda #0
|
||||
sta.z assert_byte.c
|
||||
ldx #bb
|
||||
lda #<$400
|
||||
lda #<print_screen
|
||||
sta.z print_char_cursor
|
||||
lda #>$400
|
||||
lda #>print_screen
|
||||
sta.z print_char_cursor+1
|
||||
lda #<msg
|
||||
sta.z assert_byte.msg
|
||||
@ -288,7 +289,7 @@ print_cls: {
|
||||
memset: {
|
||||
.const c = ' '
|
||||
.const num = $3e8
|
||||
.label str = $400
|
||||
.label str = print_screen
|
||||
.label end = str+num
|
||||
.label dst = 7
|
||||
lda #<str
|
||||
|
@ -10,11 +10,16 @@
|
||||
.label COLS = $d800
|
||||
.label CHARSET = $2000
|
||||
.label SCREEN = $2800
|
||||
.label print_screen = $400
|
||||
.label print_char_cursor = 8
|
||||
main: {
|
||||
.const toD0181_return = (>(SCREEN&$3fff)*4)|(>CHARSET)/4&$f
|
||||
.label col00 = COLS+$c*$28+$13
|
||||
.label __4 = $a
|
||||
//byte angle_b = atan2_8(x, y);
|
||||
//diff_sum += diff(angle_b, *screen_ref);
|
||||
//*screen = angle_b - *screen_ref++;
|
||||
//*screen = angle_b;
|
||||
.label xw = $17
|
||||
.label yw = $19
|
||||
.label angle_w = $a
|
||||
@ -120,9 +125,9 @@ print_uint: {
|
||||
.label w = 4
|
||||
// print_uchar(>w)
|
||||
ldx.z w+1
|
||||
lda #<$400
|
||||
lda #<print_screen
|
||||
sta.z print_char_cursor
|
||||
lda #>$400
|
||||
lda #>print_screen
|
||||
sta.z print_char_cursor+1
|
||||
jsr print_uchar
|
||||
// print_uchar(<w)
|
||||
@ -197,6 +202,7 @@ atan2_16: {
|
||||
.label yi = $e
|
||||
.label xi = $11
|
||||
.label angle = $a
|
||||
// Optimized shift of 2 values: xd=xi>>i; yd=yi>>i
|
||||
.label xd = $c
|
||||
.label yd = $13
|
||||
.label return = $a
|
||||
|
@ -90,6 +90,7 @@ atan2_16: {
|
||||
.label yi = $a
|
||||
.label xi = $d
|
||||
.label angle = 6
|
||||
// Optimized shift of 2 values: xd=xi>>i; yd=yi>>i
|
||||
.label xd = 8
|
||||
.label yd = $f
|
||||
.label return = 6
|
||||
|
@ -13,6 +13,7 @@
|
||||
main: {
|
||||
.const toD0181_return = (>(SCREEN&$3fff)*4)|(>CHARSET)/4&$f
|
||||
// Clear the screen by modifying the charset
|
||||
// Clear the screen by modifying the charset
|
||||
.label clear_char = 2
|
||||
// init_font_hex(CHARSET)
|
||||
jsr init_font_hex
|
||||
@ -177,6 +178,7 @@ atan2_16: {
|
||||
.label yi = $11
|
||||
.label xi = 4
|
||||
.label angle = 6
|
||||
// Optimized shift of 2 values: xd=xi>>i; yd=yi>>i
|
||||
.label xd = $a
|
||||
.label yd = 8
|
||||
.label return = 6
|
||||
|
@ -1,16 +1,17 @@
|
||||
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
|
||||
// Test a zeropage notregister variable
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
.label idx = 2
|
||||
__bbegin:
|
||||
// idx
|
||||
lda #0
|
||||
sta.z idx
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// idx
|
||||
lda #0
|
||||
sta.z idx
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
ldx #0
|
||||
__b1:
|
||||
|
@ -1,16 +1,17 @@
|
||||
// Test declaring a variable as "memory", meaning it will be stored in main memory
|
||||
// Test a fixed main memory address __notssa variable
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
.label idx = $1000
|
||||
__bbegin:
|
||||
// idx
|
||||
lda #0
|
||||
sta idx
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// idx
|
||||
lda #0
|
||||
sta idx
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
ldx #0
|
||||
__b1:
|
||||
|
@ -1,18 +1,19 @@
|
||||
// Tests declaring variables as __ssa / __notssa
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN1 = $400
|
||||
.label SCREEN2 = $400+$28
|
||||
.label SCREEN3 = $400+$50
|
||||
.label SCREEN4 = $400+$78
|
||||
.label idx_nssa_g = 2
|
||||
__bbegin:
|
||||
// idx_nssa_g
|
||||
lda #0
|
||||
sta.z idx_nssa_g
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// idx_nssa_g
|
||||
lda #0
|
||||
sta.z idx_nssa_g
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.label idx_nssa_l = 3
|
||||
// idx_nssa_l
|
||||
|
@ -700,11 +700,5 @@ f98: {
|
||||
}
|
||||
f99: {
|
||||
.label return = 1
|
||||
// f100(x)
|
||||
jsr f100
|
||||
// }
|
||||
rts
|
||||
}
|
||||
f100: {
|
||||
rts
|
||||
}
|
||||
|
13
src/test/ref/empty-function-0.asm
Normal file
13
src/test/ref/empty-function-0.asm
Normal file
@ -0,0 +1,13 @@
|
||||
// Test removal of empty function
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const v = 7
|
||||
.label SCREEN = $400
|
||||
main: {
|
||||
// SCREEN[0] = v
|
||||
lda #v
|
||||
sta SCREEN
|
||||
// }
|
||||
rts
|
||||
}
|
12
src/test/ref/empty-function-1.asm
Normal file
12
src/test/ref/empty-function-1.asm
Normal file
@ -0,0 +1,12 @@
|
||||
// Test removal of empty function
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
main: {
|
||||
// SCREEN[0] = 'x'
|
||||
lda #'x'
|
||||
sta SCREEN
|
||||
// }
|
||||
rts
|
||||
}
|
9
src/test/ref/empty-function-2.asm
Normal file
9
src/test/ref/empty-function-2.asm
Normal file
@ -0,0 +1,9 @@
|
||||
// Test removal of empty function
|
||||
// main() should not be removed!
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
// }
|
||||
rts
|
||||
}
|
@ -6,21 +6,22 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.label print_line_cursor = 4
|
||||
.label print_char_cursor = 6
|
||||
.label print_screen = $400
|
||||
.label print_line_cursor = 6
|
||||
.label print_char_cursor = 4
|
||||
main: {
|
||||
// print_cls()
|
||||
jsr print_cls
|
||||
// print_euclid(128,2)
|
||||
lda #<$400
|
||||
lda #<print_screen
|
||||
sta.z print_line_cursor
|
||||
lda #>$400
|
||||
lda #>print_screen
|
||||
sta.z print_line_cursor+1
|
||||
lda #2
|
||||
sta.z print_euclid.b
|
||||
lda #<$400
|
||||
lda #<print_screen
|
||||
sta.z print_char_cursor
|
||||
lda #>$400
|
||||
lda #>print_screen
|
||||
sta.z print_char_cursor+1
|
||||
lda #$80
|
||||
sta.z print_euclid.a
|
||||
@ -206,9 +207,9 @@ print_cls: {
|
||||
memset: {
|
||||
.const c = ' '
|
||||
.const num = $3e8
|
||||
.label str = $400
|
||||
.label str = print_screen
|
||||
.label end = str+num
|
||||
.label dst = 8
|
||||
.label dst = 6
|
||||
lda #<str
|
||||
sta.z dst
|
||||
lda #>str
|
||||
|
@ -21,25 +21,25 @@
|
||||
// The VIC-II MOS 6567/6569
|
||||
.label VICII = $d000
|
||||
// The rotated point - updated by calling rotate_matrix()
|
||||
// The rotated point - updated by calling rotate_matrix()
|
||||
.label xr = $f0
|
||||
.label yr = $f1
|
||||
.label zr = $f2
|
||||
// The rotated point with perspective
|
||||
// The rotated point with perspective
|
||||
.label pp = $f3
|
||||
.label xp = $f4
|
||||
.label yp = $f5
|
||||
// Pointers used to multiply perspective (d/z0-z) onto x- & y-coordinates. Points into mulf_sqr1 / mulf_sqr2
|
||||
// Pointers used to multiply perspective (d/z0-z) onto x- & y-coordinates. Points into mulf_sqr1 / mulf_sqr2
|
||||
.label psp1 = $f6
|
||||
.label psp2 = $f8
|
||||
.label SCREEN = $400
|
||||
// A single sprite
|
||||
.label SPRITE = $3000
|
||||
.label COSH = SINH+$40
|
||||
.label COSQ = SINQ+$40
|
||||
.label print_screen = $400
|
||||
.label sx = 2
|
||||
.label sy = 3
|
||||
// kickasm
|
||||
.label sx = 3
|
||||
.label sy = 4
|
||||
main: {
|
||||
// asm
|
||||
sei
|
||||
@ -65,7 +65,7 @@ main: {
|
||||
rts
|
||||
}
|
||||
anim: {
|
||||
.label i = 4
|
||||
.label i = 2
|
||||
lda #0
|
||||
sta.z sy
|
||||
sta.z sx
|
||||
@ -188,8 +188,8 @@ debug_print: {
|
||||
.const print_schar_pos12_row = 6
|
||||
.const print_schar_pos12_col = $25
|
||||
.label at_line = SCREEN+$13*$28
|
||||
.label c = 5
|
||||
.label i = 6
|
||||
.label c = 6
|
||||
.label i = 7
|
||||
// print_schar_pos(sx, 0, 37)
|
||||
lda.z sx
|
||||
// print_schar_at(sb, print_screen+row*40+col)
|
||||
@ -389,9 +389,9 @@ debug_print: {
|
||||
rts
|
||||
}
|
||||
// Print a signed char as hex at a specific screen position
|
||||
// print_schar_at(signed byte zp(7) b, byte* zp($e) at)
|
||||
// print_schar_at(signed byte zp(5) b, byte* zp($e) at)
|
||||
print_schar_at: {
|
||||
.label b = 7
|
||||
.label b = 5
|
||||
.label at = $e
|
||||
// if(b<0)
|
||||
lda.z b
|
||||
@ -432,9 +432,9 @@ print_char_at: {
|
||||
rts
|
||||
}
|
||||
// Print a char as HEX at a specific position
|
||||
// print_uchar_at(byte zp(7) b, byte* zp($e) at)
|
||||
// print_uchar_at(byte zp(5) b, byte* zp($e) at)
|
||||
print_uchar_at: {
|
||||
.label b = 7
|
||||
.label b = 5
|
||||
.label at = $e
|
||||
// b>>4
|
||||
lda.z b
|
||||
@ -615,17 +615,21 @@ store_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(signed byte register(X) sx, signed byte zp(3) sy)
|
||||
// calculate_matrix(signed byte register(X) sx, signed byte zp(4) sy)
|
||||
calculate_matrix: {
|
||||
.label sy = 3
|
||||
.label sy = 4
|
||||
.label t1 = 5
|
||||
.label t2 = 6
|
||||
.label t3 = 7
|
||||
.label t4 = 8
|
||||
.label t5 = 9
|
||||
// = sx+sy+sz
|
||||
.label t6 = $a
|
||||
// = sx-sy+sz
|
||||
.label t7 = $b
|
||||
// = sx+sy-sz
|
||||
.label t8 = $c
|
||||
// = sy+sz-sx
|
||||
.label t9 = $d
|
||||
// t1 = sy-sz
|
||||
lda.z sy
|
||||
@ -818,8 +822,8 @@ debug_print_init: {
|
||||
.label __59 = $1a
|
||||
.label __62 = $1c
|
||||
.label __65 = $1e
|
||||
.label c = 4
|
||||
.label i = 5
|
||||
.label c = 3
|
||||
.label i = 4
|
||||
// print_cls()
|
||||
jsr print_cls
|
||||
// print_str_at("sx", SCREEN+40*0+34)
|
||||
@ -1210,7 +1214,7 @@ sprites_init: {
|
||||
ldx #0
|
||||
__b1:
|
||||
// sprites_ptr[i] = (char)(SPRITE/$40)
|
||||
lda #SPRITE/$40
|
||||
lda #$ff&SPRITE/$40
|
||||
sta sprites_ptr,x
|
||||
// SPRITES_COLOR[i] = GREEN
|
||||
lda #GREEN
|
||||
@ -1301,8 +1305,10 @@ SINQ:
|
||||
}
|
||||
}
|
||||
|
||||
.pc = SPRITE "SPRITE"
|
||||
.var pic = LoadPicture("balloon.png", List().add($000000, $ffffff))
|
||||
.pc = $3000 "SPRITE"
|
||||
// A single sprite
|
||||
SPRITE:
|
||||
.var pic = LoadPicture("balloon.png", List().add($000000, $ffffff))
|
||||
.for (var y=0; y<21; y++)
|
||||
.for (var x=0;x<3; x++)
|
||||
.byte pic.getSinglecolorByte(x,y)
|
||||
|
@ -8,13 +8,16 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// The rotated point - updated by calling rotate()
|
||||
// The rotated point - updated by calling rotate()
|
||||
.label xr = $f0
|
||||
.label yr = $f1
|
||||
.label zr = $f2
|
||||
// Pointers used to multiply perspective (d/z0-z) onto x- & y-coordinates. Points into mulf_sqr1 / mulf_sqr2.
|
||||
// Pointers used to multiply perspective (d/z0-z) onto x- & y-coordinates. Points into mulf_sqr1 / mulf_sqr2.
|
||||
.label psp1 = $f3
|
||||
.label psp2 = $f5
|
||||
.label print_screen = $400
|
||||
.label print_char_cursor = 4
|
||||
.label print_line_cursor = 2
|
||||
main: {
|
||||
@ -44,9 +47,9 @@ do_perspective: {
|
||||
.label y = -$47
|
||||
.label z = $36
|
||||
// print_str("(")
|
||||
lda #<$400
|
||||
lda #<print_screen
|
||||
sta.z print_char_cursor
|
||||
lda #>$400
|
||||
lda #>print_screen
|
||||
sta.z print_char_cursor+1
|
||||
lda #<str
|
||||
sta.z print_str.str
|
||||
@ -115,9 +118,9 @@ do_perspective: {
|
||||
}
|
||||
// Print a newline
|
||||
print_ln: {
|
||||
lda #<$400
|
||||
lda #<print_screen
|
||||
sta.z print_line_cursor
|
||||
lda #>$400
|
||||
lda #>print_screen
|
||||
sta.z print_line_cursor+1
|
||||
__b1:
|
||||
// print_line_cursor + $28
|
||||
@ -141,9 +144,9 @@ print_ln: {
|
||||
rts
|
||||
}
|
||||
// Print a zero-terminated string
|
||||
// print_str(byte* zp(6) str)
|
||||
// print_str(byte* zp(2) str)
|
||||
print_str: {
|
||||
.label str = 6
|
||||
.label str = 2
|
||||
__b1:
|
||||
// while(*str)
|
||||
ldy #0
|
||||
@ -272,9 +275,9 @@ print_cls: {
|
||||
memset: {
|
||||
.const c = ' '
|
||||
.const num = $3e8
|
||||
.label str = $400
|
||||
.label str = print_screen
|
||||
.label end = str+num
|
||||
.label dst = 6
|
||||
.label dst = 4
|
||||
lda #<str
|
||||
sta.z dst
|
||||
lda #>str
|
||||
@ -303,9 +306,9 @@ memset: {
|
||||
}
|
||||
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x) and g(x) = f(1-x)
|
||||
mulf_init: {
|
||||
.label val = $a
|
||||
.label sqr = 6
|
||||
.label add = 8
|
||||
.label val = 6
|
||||
.label sqr = 2
|
||||
.label add = 4
|
||||
lda #<1
|
||||
sta.z add
|
||||
lda #>1
|
||||
|
@ -8,9 +8,9 @@
|
||||
.segmentdef Data [startAfter="Code",max=$fff9]
|
||||
.segmentdef Vectors [start=$fffa,max=$ffff]
|
||||
.segment Vectors
|
||||
.word __bbegin // NMI
|
||||
.word __bbegin // RESET
|
||||
.word __bbegin // IRQ
|
||||
.word _start // NMI
|
||||
.word _start // RESET
|
||||
.word _start // IRQ
|
||||
.segment Code
|
||||
|
||||
// The number of CPU cycles per scanline
|
||||
@ -34,20 +34,21 @@
|
||||
.label TIA = 0
|
||||
// Atari RIOT registers
|
||||
.label RIOT = $280
|
||||
// Player 0 X position
|
||||
.label p0_xpos = $82
|
||||
// Counts frames
|
||||
.label idx = $80
|
||||
// Player 0 Y position
|
||||
.label p0_ypos = $83
|
||||
.label idx2 = $81
|
||||
__bbegin:
|
||||
// p0_xpos
|
||||
// Player 0 X position
|
||||
lda #0
|
||||
sta.z p0_xpos
|
||||
jsr main
|
||||
rts
|
||||
.segment Code
|
||||
_start: {
|
||||
// p0_xpos
|
||||
lda #0
|
||||
sta.z p0_xpos
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// asm
|
||||
cld
|
||||
|
@ -236,6 +236,7 @@ bitmap_line_xdyi: {
|
||||
}
|
||||
// bitmap_plot(byte register(X) x, byte register(Y) y)
|
||||
bitmap_plot: {
|
||||
// Needs unsigned int arrays arranged as two underlying char arrays to allow char* plotter_x = plot_x[x]; - and eventually - char* plotter = plot_x[x] + plot_y[y];
|
||||
.label plotter_x = 9
|
||||
.label plotter_y = $b
|
||||
.label plotter = 9
|
||||
|
@ -73,8 +73,10 @@ main: {
|
||||
.label i = 4
|
||||
.label ch = 7
|
||||
// Which char canvas to use
|
||||
// Which char canvas to use
|
||||
.label cur_pos = 5
|
||||
// Is shift pressed
|
||||
// Is shift pressed
|
||||
.label shift = 6
|
||||
lda #<SCREEN
|
||||
sta.z sc
|
||||
|
@ -2,7 +2,7 @@
|
||||
// From CC65 sample "Eine kleine Nachtmusik" by Ullrich von Bassewitz
|
||||
// https://github.com/cc65/cc65/blob/master/samples/nachtm.c
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.const LIGHT_BLUE = $e
|
||||
// The horizontal line character
|
||||
@ -28,51 +28,52 @@
|
||||
.label COLORRAM = $d800
|
||||
// Default address of screen character matrix
|
||||
.label DEFAULT_SCREEN = $400
|
||||
// The number of bytes on the screen
|
||||
// The current cursor x-position
|
||||
.label conio_cursor_x = $b
|
||||
// The current cursor y-position
|
||||
.label conio_cursor_y = $c
|
||||
// The current text cursor line start
|
||||
.label conio_line_text = $d
|
||||
// The current color cursor line start
|
||||
.label conio_line_color = $f
|
||||
// The current text color
|
||||
.label conio_textcolor = $11
|
||||
// Is scrolling enabled when outputting beyond the end of the screen (1: yes, 0: no).
|
||||
// If disabled the cursor just moves back to (0,0) instead
|
||||
.label conio_scroll_enable = $12
|
||||
.label XSize = $13
|
||||
.label YSize = $14
|
||||
__bbegin:
|
||||
// conio_cursor_x = 0
|
||||
// The number of bytes on the screen
|
||||
// The current cursor x-position
|
||||
lda #0
|
||||
sta.z conio_cursor_x
|
||||
// conio_cursor_y = 0
|
||||
// The current cursor y-position
|
||||
sta.z conio_cursor_y
|
||||
// conio_line_text = CONIO_SCREEN_TEXT
|
||||
// The current text cursor line start
|
||||
lda #<DEFAULT_SCREEN
|
||||
sta.z conio_line_text
|
||||
lda #>DEFAULT_SCREEN
|
||||
sta.z conio_line_text+1
|
||||
// conio_line_color = CONIO_SCREEN_COLORS
|
||||
// The current color cursor line start
|
||||
lda #<COLORRAM
|
||||
sta.z conio_line_color
|
||||
lda #>COLORRAM
|
||||
sta.z conio_line_color+1
|
||||
// conio_textcolor = CONIO_TEXTCOLOR_DEFAULT
|
||||
// The current text color
|
||||
lda #LIGHT_BLUE
|
||||
sta.z conio_textcolor
|
||||
// conio_scroll_enable = 1
|
||||
// Is scrolling enabled when outputting beyond the end of the screen (1: yes, 0: no).
|
||||
// If disabled the cursor just moves back to (0,0) instead
|
||||
lda #1
|
||||
sta.z conio_scroll_enable
|
||||
// XSize
|
||||
lda #0
|
||||
sta.z XSize
|
||||
// YSize
|
||||
sta.z YSize
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// conio_cursor_x = 0
|
||||
lda #0
|
||||
sta.z conio_cursor_x
|
||||
// conio_cursor_y = 0
|
||||
sta.z conio_cursor_y
|
||||
// conio_line_text = CONIO_SCREEN_TEXT
|
||||
lda #<DEFAULT_SCREEN
|
||||
sta.z conio_line_text
|
||||
lda #>DEFAULT_SCREEN
|
||||
sta.z conio_line_text+1
|
||||
// conio_line_color = CONIO_SCREEN_COLORS
|
||||
lda #<COLORRAM
|
||||
sta.z conio_line_color
|
||||
lda #>COLORRAM
|
||||
sta.z conio_line_color+1
|
||||
// conio_textcolor = CONIO_TEXTCOLOR_DEFAULT
|
||||
lda #LIGHT_BLUE
|
||||
sta.z conio_textcolor
|
||||
// conio_scroll_enable = 1
|
||||
lda #1
|
||||
sta.z conio_scroll_enable
|
||||
// XSize
|
||||
lda #0
|
||||
sta.z XSize
|
||||
// YSize
|
||||
sta.z YSize
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// *VIC_MEMORY = 0x17
|
||||
lda #$17
|
||||
@ -193,8 +194,6 @@ MakeNiceScreen: {
|
||||
jsr bgcolor
|
||||
// clrscr ()
|
||||
jsr clrscr
|
||||
// cursor (0)
|
||||
jsr cursor
|
||||
// cputcxy (0, 0, CH_ULCORNER)
|
||||
/* Top line */
|
||||
ldy #CH_ULCORNER
|
||||
@ -782,13 +781,6 @@ cvline: {
|
||||
inc.z i
|
||||
jmp __b1
|
||||
}
|
||||
// If onoff is 1, a cursor is displayed when waiting for keyboard input.
|
||||
// If onoff is 0, the cursor is hidden when waiting for keyboard input.
|
||||
// The function returns the old cursor setting.
|
||||
cursor: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Set the color for the background. The old color setting is returned.
|
||||
bgcolor: {
|
||||
// The background color register address
|
||||
|
@ -4,7 +4,7 @@
|
||||
//
|
||||
// This is a recursive solution
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.const LIGHT_BLUE = $e
|
||||
.const OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS = 1
|
||||
@ -25,43 +25,44 @@
|
||||
.label DEFAULT_SCREEN = $400
|
||||
// The CIA#1: keyboard matrix, joystick #1/#2
|
||||
.label CIA1 = $dc00
|
||||
.label conio_cursor_x = $14
|
||||
.label conio_cursor_y = $15
|
||||
.label conio_line_text = $16
|
||||
.label conio_line_color = $18
|
||||
.label count = 2
|
||||
__bbegin:
|
||||
// conio_cursor_x = 0
|
||||
// The number of bytes on the screen
|
||||
// The current cursor x-position
|
||||
lda #0
|
||||
sta.z conio_cursor_x
|
||||
// conio_cursor_y = 0
|
||||
.label conio_cursor_x = $14
|
||||
// The current cursor y-position
|
||||
sta.z conio_cursor_y
|
||||
// conio_line_text = CONIO_SCREEN_TEXT
|
||||
.label conio_cursor_y = $15
|
||||
// The current text cursor line start
|
||||
lda #<DEFAULT_SCREEN
|
||||
sta.z conio_line_text
|
||||
lda #>DEFAULT_SCREEN
|
||||
sta.z conio_line_text+1
|
||||
// conio_line_color = CONIO_SCREEN_COLORS
|
||||
.label conio_line_text = $16
|
||||
// The current color cursor line start
|
||||
lda #<COLORRAM
|
||||
sta.z conio_line_color
|
||||
lda #>COLORRAM
|
||||
sta.z conio_line_color+1
|
||||
// count = 0
|
||||
.label conio_line_color = $18
|
||||
// The number of found solutions
|
||||
lda #<0
|
||||
sta.z count
|
||||
sta.z count+1
|
||||
lda #<0>>$10
|
||||
sta.z count+2
|
||||
lda #>0>>$10
|
||||
sta.z count+3
|
||||
jsr main
|
||||
rts
|
||||
.label count = 2
|
||||
_start: {
|
||||
// conio_cursor_x = 0
|
||||
lda #0
|
||||
sta.z conio_cursor_x
|
||||
// conio_cursor_y = 0
|
||||
sta.z conio_cursor_y
|
||||
// conio_line_text = CONIO_SCREEN_TEXT
|
||||
lda #<DEFAULT_SCREEN
|
||||
sta.z conio_line_text
|
||||
lda #>DEFAULT_SCREEN
|
||||
sta.z conio_line_text+1
|
||||
// conio_line_color = CONIO_SCREEN_COLORS
|
||||
lda #<COLORRAM
|
||||
sta.z conio_line_color
|
||||
lda #>COLORRAM
|
||||
sta.z conio_line_color+1
|
||||
// count = 0
|
||||
lda #<0
|
||||
sta.z count
|
||||
sta.z count+1
|
||||
lda #<0>>$10
|
||||
sta.z count+2
|
||||
lda #>0>>$10
|
||||
sta.z count+3
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// clrscr()
|
||||
jsr clrscr
|
||||
@ -411,6 +412,7 @@ printf_ulong: {
|
||||
printf_number_buffer: {
|
||||
.label __19 = $a
|
||||
.label buffer_sign = $1a
|
||||
// There is a minimum length - work out the padding
|
||||
.label len = $11
|
||||
.label padding = $10
|
||||
.label format_min_length = $10
|
||||
|
@ -4,7 +4,7 @@
|
||||
//
|
||||
// This is an iterative solution.
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.const LIGHT_BLUE = $e
|
||||
.const OFFSET_STRUCT_PRINTF_BUFFER_NUMBER_DIGITS = 1
|
||||
@ -13,35 +13,36 @@
|
||||
.label COLORRAM = $d800
|
||||
// Default address of screen character matrix
|
||||
.label DEFAULT_SCREEN = $400
|
||||
// The number of bytes on the screen
|
||||
// The current cursor x-position
|
||||
.label conio_cursor_x = $19
|
||||
// The current cursor y-position
|
||||
.label conio_cursor_y = $1a
|
||||
// The current text cursor line start
|
||||
.label conio_line_text = $1b
|
||||
// The current color cursor line start
|
||||
.label conio_line_color = $1d
|
||||
// The number of found solutions
|
||||
.label count = 2
|
||||
__bbegin:
|
||||
// conio_cursor_x = 0
|
||||
// The number of bytes on the screen
|
||||
// The current cursor x-position
|
||||
lda #0
|
||||
sta.z conio_cursor_x
|
||||
// conio_cursor_y = 0
|
||||
// The current cursor y-position
|
||||
sta.z conio_cursor_y
|
||||
// conio_line_text = CONIO_SCREEN_TEXT
|
||||
// The current text cursor line start
|
||||
lda #<DEFAULT_SCREEN
|
||||
sta.z conio_line_text
|
||||
lda #>DEFAULT_SCREEN
|
||||
sta.z conio_line_text+1
|
||||
// conio_line_color = CONIO_SCREEN_COLORS
|
||||
// The current color cursor line start
|
||||
lda #<COLORRAM
|
||||
sta.z conio_line_color
|
||||
lda #>COLORRAM
|
||||
sta.z conio_line_color+1
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// conio_cursor_x = 0
|
||||
lda #0
|
||||
sta.z conio_cursor_x
|
||||
// conio_cursor_y = 0
|
||||
sta.z conio_cursor_y
|
||||
// conio_line_text = CONIO_SCREEN_TEXT
|
||||
lda #<DEFAULT_SCREEN
|
||||
sta.z conio_line_text
|
||||
lda #>DEFAULT_SCREEN
|
||||
sta.z conio_line_text+1
|
||||
// conio_line_color = CONIO_SCREEN_COLORS
|
||||
lda #<COLORRAM
|
||||
sta.z conio_line_color
|
||||
lda #>COLORRAM
|
||||
sta.z conio_line_color+1
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// clrscr()
|
||||
jsr clrscr
|
||||
@ -710,6 +711,7 @@ ultoa_append: {
|
||||
// The solution uses the board itself as a "cursor" moving through all possibilities
|
||||
// When all columns on a row is exhausted move back down to the lower level and move forward one position until we are done with the last position on the first row
|
||||
queens: {
|
||||
// The current row where the queen is moving
|
||||
// The current row where the queen is moving
|
||||
.label row = $d
|
||||
lda #<0
|
||||
|
@ -8,6 +8,7 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// Pointers to a, b and c=a*b
|
||||
// Pointers to a, b and c=a*b
|
||||
.label ap = $fd
|
||||
.label bp = $fe
|
||||
|
@ -98,7 +98,9 @@ main: {
|
||||
}
|
||||
// Animate the fire on the passed screen. Uses BUFFER to store the current values.
|
||||
fire: {
|
||||
// Average characters from below the current character (24 lines)
|
||||
.label screen = 2
|
||||
// Average characters from below the current character (24 lines)
|
||||
.label screen_1 = $b
|
||||
.label buffer = 4
|
||||
.label buffer_1 = 9
|
||||
|
@ -1,39 +1,40 @@
|
||||
// Functions for performing input and output.
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.const LIGHT_BLUE = $e
|
||||
// Color Ram
|
||||
.label COLORRAM = $d800
|
||||
// Default address of screen character matrix
|
||||
.label DEFAULT_SCREEN = $400
|
||||
.label conio_cursor_x = 6
|
||||
.label conio_cursor_y = 7
|
||||
.label conio_line_text = 8
|
||||
.label conio_line_color = $a
|
||||
__bbegin:
|
||||
// conio_cursor_x = 0
|
||||
// The number of bytes on the screen
|
||||
// The current cursor x-position
|
||||
lda #0
|
||||
sta.z conio_cursor_x
|
||||
// conio_cursor_y = 0
|
||||
.label conio_cursor_x = 6
|
||||
// The current cursor y-position
|
||||
sta.z conio_cursor_y
|
||||
// conio_line_text = CONIO_SCREEN_TEXT
|
||||
.label conio_cursor_y = 7
|
||||
// The current text cursor line start
|
||||
lda #<DEFAULT_SCREEN
|
||||
sta.z conio_line_text
|
||||
lda #>DEFAULT_SCREEN
|
||||
sta.z conio_line_text+1
|
||||
// conio_line_color = CONIO_SCREEN_COLORS
|
||||
.label conio_line_text = 8
|
||||
// The current color cursor line start
|
||||
lda #<COLORRAM
|
||||
sta.z conio_line_color
|
||||
lda #>COLORRAM
|
||||
sta.z conio_line_color+1
|
||||
jsr main
|
||||
rts
|
||||
.label conio_line_color = $a
|
||||
_start: {
|
||||
// conio_cursor_x = 0
|
||||
lda #0
|
||||
sta.z conio_cursor_x
|
||||
// conio_cursor_y = 0
|
||||
sta.z conio_cursor_y
|
||||
// conio_line_text = CONIO_SCREEN_TEXT
|
||||
lda #<DEFAULT_SCREEN
|
||||
sta.z conio_line_text
|
||||
lda #>DEFAULT_SCREEN
|
||||
sta.z conio_line_text+1
|
||||
// conio_line_color = CONIO_SCREEN_COLORS
|
||||
lda #<COLORRAM
|
||||
sta.z conio_line_color
|
||||
lda #>COLORRAM
|
||||
sta.z conio_line_color+1
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// printf("hello world!\n")
|
||||
jsr cputs
|
||||
|
@ -25,39 +25,6 @@
|
||||
// The vector used when the KERNAL serves IRQ interrupts
|
||||
.label KERNEL_IRQ = $314
|
||||
.label GHOST_BYTE = $3fff
|
||||
main: {
|
||||
// *GHOST_BYTE = 0
|
||||
lda #0
|
||||
sta GHOST_BYTE
|
||||
// asm
|
||||
sei
|
||||
// CIA1->INTERRUPT = CIA_INTERRUPT_CLEAR
|
||||
// Disable CIA 1 Timer IRQ
|
||||
lda #CIA_INTERRUPT_CLEAR
|
||||
sta CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT
|
||||
// VICII->CONTROL1 &=$7f
|
||||
// Set raster line to $fa
|
||||
lda #$7f
|
||||
and VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1
|
||||
sta VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1
|
||||
// VICII->RASTER = $fa
|
||||
lda #$fa
|
||||
sta VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER
|
||||
// VICII->IRQ_ENABLE = IRQ_RASTER
|
||||
// Enable Raster Interrupt
|
||||
lda #IRQ_RASTER
|
||||
sta VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE
|
||||
// *KERNEL_IRQ = &irq_bottom_1
|
||||
// Set the IRQ routine
|
||||
lda #<irq_bottom_1
|
||||
sta KERNEL_IRQ
|
||||
lda #>irq_bottom_1
|
||||
sta KERNEL_IRQ+1
|
||||
// asm
|
||||
cli
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Interrupt Routine 2
|
||||
irq_bottom_2: {
|
||||
// VICII->BORDER_COLOR = WHITE
|
||||
@ -116,3 +83,36 @@ irq_bottom_1: {
|
||||
// }
|
||||
jmp $ea81
|
||||
}
|
||||
main: {
|
||||
// *GHOST_BYTE = 0
|
||||
lda #0
|
||||
sta GHOST_BYTE
|
||||
// asm
|
||||
sei
|
||||
// CIA1->INTERRUPT = CIA_INTERRUPT_CLEAR
|
||||
// Disable CIA 1 Timer IRQ
|
||||
lda #CIA_INTERRUPT_CLEAR
|
||||
sta CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT
|
||||
// VICII->CONTROL1 &=$7f
|
||||
// Set raster line to $fa
|
||||
lda #$7f
|
||||
and VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1
|
||||
sta VICII+OFFSET_STRUCT_MOS6569_VICII_CONTROL1
|
||||
// VICII->RASTER = $fa
|
||||
lda #$fa
|
||||
sta VICII+OFFSET_STRUCT_MOS6569_VICII_RASTER
|
||||
// VICII->IRQ_ENABLE = IRQ_RASTER
|
||||
// Enable Raster Interrupt
|
||||
lda #IRQ_RASTER
|
||||
sta VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_ENABLE
|
||||
// *KERNEL_IRQ = &irq_bottom_1
|
||||
// Set the IRQ routine
|
||||
lda #<irq_bottom_1
|
||||
sta KERNEL_IRQ
|
||||
lda #>irq_bottom_1
|
||||
sta KERNEL_IRQ+1
|
||||
// asm
|
||||
cli
|
||||
// }
|
||||
rts
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
// The MOS 6526 Complex Interface Adapter (CIA)
|
||||
// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.const VIC_RST8 = $80
|
||||
.const VIC_DEN = $10
|
||||
@ -24,33 +24,33 @@
|
||||
// The VIC-II MOS 6567/6569
|
||||
.label VICII = $d000
|
||||
// Location of screen & sprites
|
||||
// Location of screen & sprites
|
||||
.label SCREEN = $400
|
||||
.label SPRITE = $2000
|
||||
// The address of the sprite pointers on the current screen (screen+0x3f8).
|
||||
.label PLEX_SCREEN_PTR = SCREEN+$3f8
|
||||
.label plex_show_idx = 6
|
||||
.label plex_sprite_idx = 7
|
||||
.label plex_sprite_msb = 8
|
||||
.label plex_free_next = 9
|
||||
__bbegin:
|
||||
// plex_show_idx=0
|
||||
// The index in the PLEX tables of the next sprite to show
|
||||
lda #0
|
||||
sta.z plex_show_idx
|
||||
// plex_sprite_idx=0
|
||||
.label plex_show_idx = 6
|
||||
// The index the next sprite to use for showing (sprites are used round-robin)
|
||||
sta.z plex_sprite_idx
|
||||
// plex_sprite_msb=1
|
||||
.label plex_sprite_idx = 7
|
||||
// The MSB bit of the next sprite to use for showing
|
||||
lda #1
|
||||
sta.z plex_sprite_msb
|
||||
// plex_free_next = 0
|
||||
.label plex_sprite_msb = 8
|
||||
// The index of the sprite that is free next. Since sprites are used round-robin this moves forward each time a sprite is shown.
|
||||
lda #0
|
||||
sta.z plex_free_next
|
||||
// kickasm
|
||||
jsr main
|
||||
rts
|
||||
.label plex_free_next = 9
|
||||
_start: {
|
||||
// plex_show_idx=0
|
||||
lda #0
|
||||
sta.z plex_show_idx
|
||||
// plex_sprite_idx=0
|
||||
sta.z plex_sprite_idx
|
||||
// plex_sprite_msb=1
|
||||
lda #1
|
||||
sta.z plex_sprite_msb
|
||||
// plex_free_next = 0
|
||||
lda #0
|
||||
sta.z plex_free_next
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// asm
|
||||
sei
|
||||
@ -63,6 +63,7 @@ main: {
|
||||
}
|
||||
// The raster loop
|
||||
loop: {
|
||||
// The current index into the y-sinus
|
||||
// The current index into the y-sinus
|
||||
.label sin_idx = 2
|
||||
.label plexFreeNextYpos1_return = $a
|
||||
@ -300,6 +301,7 @@ plexSort: {
|
||||
}
|
||||
// Initialize the program
|
||||
init: {
|
||||
// Set the x-positions & pointers
|
||||
// Set the x-positions & pointers
|
||||
.label xp = 4
|
||||
// *D011 = VIC_DEN | VIC_RSEL | 3
|
||||
@ -315,7 +317,7 @@ init: {
|
||||
ldx #0
|
||||
__b1:
|
||||
// PLEX_PTR[sx] = (char)(SPRITE/$40)
|
||||
lda #SPRITE/$40
|
||||
lda #$ff&SPRITE/$40
|
||||
sta PLEX_PTR,x
|
||||
// PLEX_XPOS[sx] = xp
|
||||
txa
|
||||
@ -385,8 +387,9 @@ YSIN:
|
||||
.for(var i=0;i<256;i++)
|
||||
.byte round(min+(ampl/2)+(ampl/2)*sin(toRadians(360*i/256)))
|
||||
|
||||
.pc = SPRITE "SPRITE"
|
||||
.var pic = LoadPicture("balloon.png", List().add($000000, $ffffff))
|
||||
.pc = $2000 "SPRITE"
|
||||
SPRITE:
|
||||
.var pic = LoadPicture("balloon.png", List().add($000000, $ffffff))
|
||||
.for (var y=0; y<21; y++)
|
||||
.for (var x=0;x<3; x++)
|
||||
.byte pic.getSinglecolorByte(x,y)
|
||||
|
@ -9,17 +9,17 @@
|
||||
.const OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR = $20
|
||||
// The VIC-II MOS 6567/6569
|
||||
.label VICII = $d000
|
||||
.label MUSIC = $1000
|
||||
// kickasm
|
||||
// Load the SID
|
||||
.const music = LoadSid("toiletrensdyr.sid")
|
||||
|
||||
// Place the SID into memory
|
||||
// Pointer to the music init routine
|
||||
// Pointer to the music init routine
|
||||
.label musicInit = MUSIC
|
||||
// Pointer to the music play routine
|
||||
// Pointer to the music play routine
|
||||
.label musicPlay = MUSIC+3
|
||||
// Play the music
|
||||
main: {
|
||||
// asm
|
||||
// (*musicInit)()
|
||||
// Initialize the music
|
||||
jsr music.init
|
||||
jsr musicInit
|
||||
// Wait for the RASTER
|
||||
__b1:
|
||||
// while (VICII->RASTER != $fd)
|
||||
@ -28,13 +28,16 @@ main: {
|
||||
bne __b1
|
||||
// (VICII->BORDER_COLOR)++;
|
||||
inc VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR
|
||||
// asm
|
||||
// (*musicPlay)()
|
||||
// Play the music
|
||||
jsr music.play
|
||||
jsr musicPlay
|
||||
// (VICII->BORDER_COLOR)--;
|
||||
dec VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR
|
||||
jmp __b1
|
||||
}
|
||||
.pc = MUSIC "MUSIC"
|
||||
.fill music.size, music.getData(i)
|
||||
.pc = $1000 "MUSIC"
|
||||
// SID tune at an absolute address
|
||||
MUSIC:
|
||||
.const music = LoadSid("toiletrensdyr.sid")
|
||||
.fill music.size, music.getData(i)
|
||||
|
||||
|
@ -21,17 +21,34 @@
|
||||
.label CIA1 = $dc00
|
||||
// The vector used when the KERNAL serves IRQ interrupts
|
||||
.label KERNEL_IRQ = $314
|
||||
.label MUSIC = $1000
|
||||
// kickasm
|
||||
// Load the SID
|
||||
.const music = LoadSid("toiletrensdyr.sid")
|
||||
|
||||
// Place the SID into memory
|
||||
// Pointer to the music init routine
|
||||
// Pointer to the music init routine
|
||||
.label musicInit = MUSIC
|
||||
// Pointer to the music play routine
|
||||
// Pointer to the music play routine
|
||||
.label musicPlay = MUSIC+3
|
||||
// Raster IRQ Routine playing music
|
||||
irq_play: {
|
||||
// (VICII->BORDER_COLOR)++;
|
||||
inc VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR
|
||||
// (*musicPlay)()
|
||||
// Play SID
|
||||
jsr musicPlay
|
||||
// VICII->IRQ_STATUS = IRQ_RASTER
|
||||
// Acknowledge the IRQ
|
||||
lda #IRQ_RASTER
|
||||
sta VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_STATUS
|
||||
// (VICII->BORDER_COLOR)--;
|
||||
dec VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR
|
||||
// }
|
||||
jmp $ea31
|
||||
}
|
||||
// Setup Raster IRQ and initialize SID player
|
||||
main: {
|
||||
// asm
|
||||
sei
|
||||
jsr music.init
|
||||
// (*musicInit)()
|
||||
jsr musicInit
|
||||
// CIA1->INTERRUPT = CIA_INTERRUPT_CLEAR
|
||||
// Disable CIA 1 Timer IRQ
|
||||
lda #CIA_INTERRUPT_CLEAR
|
||||
@ -59,22 +76,9 @@ main: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Raster IRQ Routine playing music
|
||||
irq_play: {
|
||||
// (VICII->BORDER_COLOR)++;
|
||||
inc VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR
|
||||
// asm
|
||||
// Play SID
|
||||
jsr music.play
|
||||
// VICII->IRQ_STATUS = IRQ_RASTER
|
||||
// Acknowledge the IRQ
|
||||
lda #IRQ_RASTER
|
||||
sta VICII+OFFSET_STRUCT_MOS6569_VICII_IRQ_STATUS
|
||||
// (VICII->BORDER_COLOR)--;
|
||||
dec VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR
|
||||
// }
|
||||
jmp $ea31
|
||||
}
|
||||
.pc = MUSIC "MUSIC"
|
||||
.fill music.size, music.getData(i)
|
||||
.pc = $1000 "MUSIC"
|
||||
// SID tune at an absolute address
|
||||
MUSIC:
|
||||
.const music = LoadSid("toiletrensdyr.sid")
|
||||
.fill music.size, music.getData(i)
|
||||
|
||||
|
@ -81,36 +81,39 @@
|
||||
// Pointer to the start of RAM memory
|
||||
.label MEMORY = 0
|
||||
// NES Picture Processing Unit (PPU)
|
||||
// NES Picture Processing Unit (PPU)
|
||||
.label PPU = $2000
|
||||
// NES CPU and audion processing unit (APU)
|
||||
// NES CPU and audion processing unit (APU)
|
||||
.label APU = $4000
|
||||
// The current cursor x-position
|
||||
.label conio_cursor_x = $11
|
||||
// The current cursor y-position
|
||||
.label conio_cursor_y = $12
|
||||
// The current text cursor line start
|
||||
.label conio_line_text = $13
|
||||
.label x_scroll = $15
|
||||
.label y_scroll = $16
|
||||
__bbegin:
|
||||
// conio_cursor_x = 0
|
||||
// The current cursor x-position
|
||||
lda #0
|
||||
sta.z conio_cursor_x
|
||||
// conio_cursor_y = 0
|
||||
// The current cursor y-position
|
||||
sta.z conio_cursor_y
|
||||
// conio_line_text = CONIO_SCREEN_TEXT
|
||||
// The current text cursor line start
|
||||
lda #<PPU_NAME_TABLE_0
|
||||
sta.z conio_line_text
|
||||
lda #>PPU_NAME_TABLE_0
|
||||
sta.z conio_line_text+1
|
||||
// x_scroll
|
||||
lda #0
|
||||
sta.z x_scroll
|
||||
// y_scroll
|
||||
sta.z y_scroll
|
||||
jsr main
|
||||
rts
|
||||
.segment Code
|
||||
_start: {
|
||||
// conio_cursor_x = 0
|
||||
lda #0
|
||||
sta.z conio_cursor_x
|
||||
// conio_cursor_y = 0
|
||||
sta.z conio_cursor_y
|
||||
// conio_line_text = CONIO_SCREEN_TEXT
|
||||
lda #<PPU_NAME_TABLE_0
|
||||
sta.z conio_line_text
|
||||
lda #>PPU_NAME_TABLE_0
|
||||
sta.z conio_line_text+1
|
||||
// x_scroll
|
||||
lda #0
|
||||
sta.z x_scroll
|
||||
// y_scroll
|
||||
sta.z y_scroll
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
// RESET Called when the NES is reset, including when it is turned on.
|
||||
main: {
|
||||
.const screensizex1_return = $20
|
||||
@ -363,6 +366,7 @@ cputln: {
|
||||
}
|
||||
// Scroll the entire screen if the cursor is beyond the last line
|
||||
cscroll: {
|
||||
// Scroll lines up
|
||||
// Scroll lines up
|
||||
.label line1 = $17
|
||||
.label line2 = $f
|
||||
@ -456,6 +460,7 @@ cscroll: {
|
||||
// ppuDataTransfer(void* zp(5) ppuData, void* zp(7) cpuData, word zp(9) size)
|
||||
ppuDataTransfer: {
|
||||
.label ppuDataPrepare1_ppuData = 5
|
||||
// Transfer to PPU
|
||||
.label cpuSrc = 7
|
||||
.label i = $b
|
||||
.label ppuData = 5
|
||||
@ -511,6 +516,7 @@ ppuDataFetch: {
|
||||
.const size = $20
|
||||
.label cpuData = conio_cscroll_buffer
|
||||
// Fetch from PPU to CPU
|
||||
// Fetch from PPU to CPU
|
||||
.label cpuDst = 7
|
||||
.label i = 5
|
||||
.label ppuData = $19
|
||||
@ -626,9 +632,9 @@ ppuDataSet: {
|
||||
// Set the cursor to the specified position
|
||||
// gotoxy(byte register(X) x, byte register(A) y)
|
||||
gotoxy: {
|
||||
.label __5 = $13
|
||||
.label __6 = $13
|
||||
.label line_offset = $13
|
||||
.label __5 = $1b
|
||||
.label __6 = $1b
|
||||
.label line_offset = $1b
|
||||
// if(y>CONIO_HEIGHT)
|
||||
cmp #$1e+1
|
||||
bcc __b1
|
||||
@ -667,6 +673,10 @@ gotoxy: {
|
||||
adc #>PPU_NAME_TABLE_0
|
||||
sta.z __5+1
|
||||
// conio_line_text = CONIO_SCREEN_TEXT + line_offset
|
||||
lda.z __5
|
||||
sta.z conio_line_text
|
||||
lda.z __5+1
|
||||
sta.z conio_line_text+1
|
||||
// }
|
||||
rts
|
||||
}
|
||||
@ -682,9 +692,9 @@ cputsxy: {
|
||||
rts
|
||||
}
|
||||
// Output a NUL-terminated string at the current cursor position
|
||||
// cputs(byte* zp($d) s)
|
||||
// cputs(byte* zp($1b) s)
|
||||
cputs: {
|
||||
.label s = $d
|
||||
.label s = $1b
|
||||
lda #<num_buffer
|
||||
sta.z s
|
||||
lda #>num_buffer
|
||||
@ -716,10 +726,10 @@ cputs: {
|
||||
// uctoa(byte register(X) value, byte* zp($f) buffer)
|
||||
uctoa: {
|
||||
.const max_digits = 2
|
||||
.label digit_value = $1b
|
||||
.label digit_value = $1d
|
||||
.label buffer = $f
|
||||
.label digit = $11
|
||||
.label started = $12
|
||||
.label digit = $d
|
||||
.label started = $e
|
||||
lda #<num_buffer
|
||||
sta.z buffer
|
||||
lda #>num_buffer
|
||||
@ -784,10 +794,10 @@ uctoa: {
|
||||
// - sub : the value of a '1' in the digit. Subtracted continually while the digit is increased.
|
||||
// (For decimal the subs used are 10000, 1000, 100, 10, 1)
|
||||
// returns : the value reduced by sub * digit so that it is less than sub.
|
||||
// uctoa_append(byte* zp($f) buffer, byte register(X) value, byte zp($1b) sub)
|
||||
// uctoa_append(byte* zp($f) buffer, byte register(X) value, byte zp($1d) sub)
|
||||
uctoa_append: {
|
||||
.label buffer = $f
|
||||
.label sub = $1b
|
||||
.label sub = $1d
|
||||
ldy #0
|
||||
__b1:
|
||||
// while (value >= sub)
|
||||
@ -919,7 +929,7 @@ vblank: {
|
||||
// - bit 6: B
|
||||
// - bit 7: A
|
||||
readJoy1: {
|
||||
.label __1 = $1c
|
||||
.label __1 = $1e
|
||||
// APU->JOY1 = 1
|
||||
// Latch the controller buttons
|
||||
lda #1
|
||||
|
@ -82,10 +82,143 @@
|
||||
// Pointer to the start of RAM memory
|
||||
.label MEMORY = 0
|
||||
// NES Picture Processing Unit (PPU)
|
||||
// NES Picture Processing Unit (PPU)
|
||||
.label PPU = $2000
|
||||
// NES CPU and audion processing unit (APU)
|
||||
// NES CPU and audion processing unit (APU)
|
||||
.label APU = $4000
|
||||
.segment Code
|
||||
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
|
||||
vblank: {
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
// readJoy1()
|
||||
jsr readJoy1
|
||||
// joy = readJoy1()
|
||||
tax
|
||||
// joy&JOY_DOWN
|
||||
txa
|
||||
and #JOY_DOWN
|
||||
// if(joy&JOY_DOWN)
|
||||
cmp #0
|
||||
beq __b1
|
||||
// SPRITE_BUFFER[0].y++;
|
||||
inc SPRITE_BUFFER
|
||||
// SPRITE_BUFFER[1].y++;
|
||||
inc SPRITE_BUFFER+1*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[2].y++;
|
||||
inc SPRITE_BUFFER+2*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[3].y++;
|
||||
inc SPRITE_BUFFER+3*SIZEOF_STRUCT_SPRITEDATA
|
||||
__b1:
|
||||
// joy&JOY_UP
|
||||
txa
|
||||
and #JOY_UP
|
||||
// if(joy&JOY_UP)
|
||||
cmp #0
|
||||
beq __b2
|
||||
// SPRITE_BUFFER[0].y--;
|
||||
dec SPRITE_BUFFER
|
||||
// SPRITE_BUFFER[1].y--;
|
||||
dec SPRITE_BUFFER+1*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[2].y--;
|
||||
dec SPRITE_BUFFER+2*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[3].y--;
|
||||
dec SPRITE_BUFFER+3*SIZEOF_STRUCT_SPRITEDATA
|
||||
__b2:
|
||||
// joy&JOY_LEFT
|
||||
txa
|
||||
and #JOY_LEFT
|
||||
// if(joy&JOY_LEFT)
|
||||
cmp #0
|
||||
beq __b3
|
||||
// SPRITE_BUFFER[0].x--;
|
||||
dec SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X
|
||||
// SPRITE_BUFFER[1].x--;
|
||||
dec SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X+1*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[2].x--;
|
||||
dec SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X+2*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[3].x--;
|
||||
dec SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X+3*SIZEOF_STRUCT_SPRITEDATA
|
||||
__b3:
|
||||
// joy&JOY_RIGHT
|
||||
txa
|
||||
and #JOY_RIGHT
|
||||
// if(joy&JOY_RIGHT)
|
||||
cmp #0
|
||||
beq ppuSpriteBufferDmaTransfer1
|
||||
// SPRITE_BUFFER[0].x++;
|
||||
inc SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X
|
||||
// SPRITE_BUFFER[1].x++;
|
||||
inc SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X+1*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[2].x++;
|
||||
inc SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X+2*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[3].x++;
|
||||
inc SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X+3*SIZEOF_STRUCT_SPRITEDATA
|
||||
ppuSpriteBufferDmaTransfer1:
|
||||
// PPU->OAMADDR = 0
|
||||
lda #0
|
||||
sta PPU+OFFSET_STRUCT_RICOH_2C02_OAMADDR
|
||||
// APU->OAMDMA = >spriteBuffer
|
||||
lda #>SPRITE_BUFFER
|
||||
sta APU+OFFSET_STRUCT_RICOH_2A03_OAMDMA
|
||||
// PPU->PPUSCROLL = 0
|
||||
// Set scroll
|
||||
lda #0
|
||||
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUSCROLL
|
||||
// PPU->PPUSCROLL = -8
|
||||
lda #-8
|
||||
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUSCROLL
|
||||
// }
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
rti
|
||||
}
|
||||
// Read Standard Controller #1
|
||||
// Returns a byte representing the pushed buttons
|
||||
// - bit 0: right
|
||||
// - bit 1: left
|
||||
// - bit 2: down
|
||||
// - bit 3: up
|
||||
// - bit 4: start
|
||||
// - bit 5: select
|
||||
// - bit 6: B
|
||||
// - bit 7: A
|
||||
readJoy1: {
|
||||
.label __1 = 8
|
||||
// APU->JOY1 = 1
|
||||
// Latch the controller buttons
|
||||
lda #1
|
||||
sta APU+OFFSET_STRUCT_RICOH_2A03_JOY1
|
||||
// APU->JOY1 = 0
|
||||
lda #0
|
||||
sta APU+OFFSET_STRUCT_RICOH_2A03_JOY1
|
||||
tax
|
||||
__b1:
|
||||
// for(char i=0;i<8;i++)
|
||||
cpx #8
|
||||
bcc __b2
|
||||
// }
|
||||
rts
|
||||
__b2:
|
||||
// joy<<1
|
||||
asl
|
||||
sta.z __1
|
||||
// APU->JOY1&1
|
||||
lda #1
|
||||
and APU+OFFSET_STRUCT_RICOH_2A03_JOY1
|
||||
// joy = joy<<1 | APU->JOY1&1
|
||||
ora.z __1
|
||||
// for(char i=0;i<8;i++)
|
||||
inx
|
||||
jmp __b1
|
||||
}
|
||||
// RESET Called when the NES is reset, including when it is turned on.
|
||||
main: {
|
||||
// asm
|
||||
@ -368,6 +501,7 @@ ppuDataTransfer: {
|
||||
.label ppuData = PPU_PALETTE
|
||||
.label cpuData = PALETTE
|
||||
// Transfer to PPU
|
||||
// Transfer to PPU
|
||||
.label cpuSrc = 6
|
||||
.label i = 4
|
||||
// PPU->PPUADDR = >ppuData
|
||||
@ -413,137 +547,6 @@ ppuDataTransfer: {
|
||||
!:
|
||||
jmp __b1
|
||||
}
|
||||
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
|
||||
vblank: {
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
// readJoy1()
|
||||
jsr readJoy1
|
||||
// joy = readJoy1()
|
||||
tax
|
||||
// joy&JOY_DOWN
|
||||
txa
|
||||
and #JOY_DOWN
|
||||
// if(joy&JOY_DOWN)
|
||||
cmp #0
|
||||
beq __b1
|
||||
// SPRITE_BUFFER[0].y++;
|
||||
inc SPRITE_BUFFER
|
||||
// SPRITE_BUFFER[1].y++;
|
||||
inc SPRITE_BUFFER+1*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[2].y++;
|
||||
inc SPRITE_BUFFER+2*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[3].y++;
|
||||
inc SPRITE_BUFFER+3*SIZEOF_STRUCT_SPRITEDATA
|
||||
__b1:
|
||||
// joy&JOY_UP
|
||||
txa
|
||||
and #JOY_UP
|
||||
// if(joy&JOY_UP)
|
||||
cmp #0
|
||||
beq __b2
|
||||
// SPRITE_BUFFER[0].y--;
|
||||
dec SPRITE_BUFFER
|
||||
// SPRITE_BUFFER[1].y--;
|
||||
dec SPRITE_BUFFER+1*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[2].y--;
|
||||
dec SPRITE_BUFFER+2*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[3].y--;
|
||||
dec SPRITE_BUFFER+3*SIZEOF_STRUCT_SPRITEDATA
|
||||
__b2:
|
||||
// joy&JOY_LEFT
|
||||
txa
|
||||
and #JOY_LEFT
|
||||
// if(joy&JOY_LEFT)
|
||||
cmp #0
|
||||
beq __b3
|
||||
// SPRITE_BUFFER[0].x--;
|
||||
dec SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X
|
||||
// SPRITE_BUFFER[1].x--;
|
||||
dec SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X+1*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[2].x--;
|
||||
dec SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X+2*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[3].x--;
|
||||
dec SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X+3*SIZEOF_STRUCT_SPRITEDATA
|
||||
__b3:
|
||||
// joy&JOY_RIGHT
|
||||
txa
|
||||
and #JOY_RIGHT
|
||||
// if(joy&JOY_RIGHT)
|
||||
cmp #0
|
||||
beq ppuSpriteBufferDmaTransfer1
|
||||
// SPRITE_BUFFER[0].x++;
|
||||
inc SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X
|
||||
// SPRITE_BUFFER[1].x++;
|
||||
inc SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X+1*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[2].x++;
|
||||
inc SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X+2*SIZEOF_STRUCT_SPRITEDATA
|
||||
// SPRITE_BUFFER[3].x++;
|
||||
inc SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X+3*SIZEOF_STRUCT_SPRITEDATA
|
||||
ppuSpriteBufferDmaTransfer1:
|
||||
// PPU->OAMADDR = 0
|
||||
lda #0
|
||||
sta PPU+OFFSET_STRUCT_RICOH_2C02_OAMADDR
|
||||
// APU->OAMDMA = >spriteBuffer
|
||||
lda #>SPRITE_BUFFER
|
||||
sta APU+OFFSET_STRUCT_RICOH_2A03_OAMDMA
|
||||
// PPU->PPUSCROLL = 0
|
||||
// Set scroll
|
||||
lda #0
|
||||
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUSCROLL
|
||||
// PPU->PPUSCROLL = -8
|
||||
lda #-8
|
||||
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUSCROLL
|
||||
// }
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
rti
|
||||
}
|
||||
// Read Standard Controller #1
|
||||
// Returns a byte representing the pushed buttons
|
||||
// - bit 0: right
|
||||
// - bit 1: left
|
||||
// - bit 2: down
|
||||
// - bit 3: up
|
||||
// - bit 4: start
|
||||
// - bit 5: select
|
||||
// - bit 6: B
|
||||
// - bit 7: A
|
||||
readJoy1: {
|
||||
.label __1 = 8
|
||||
// APU->JOY1 = 1
|
||||
// Latch the controller buttons
|
||||
lda #1
|
||||
sta APU+OFFSET_STRUCT_RICOH_2A03_JOY1
|
||||
// APU->JOY1 = 0
|
||||
lda #0
|
||||
sta APU+OFFSET_STRUCT_RICOH_2A03_JOY1
|
||||
tax
|
||||
__b1:
|
||||
// for(char i=0;i<8;i++)
|
||||
cpx #8
|
||||
bcc __b2
|
||||
// }
|
||||
rts
|
||||
__b2:
|
||||
// joy<<1
|
||||
asl
|
||||
sta.z __1
|
||||
// APU->JOY1&1
|
||||
lda #1
|
||||
and APU+OFFSET_STRUCT_RICOH_2A03_JOY1
|
||||
// joy = joy<<1 | APU->JOY1&1
|
||||
ora.z __1
|
||||
// for(char i=0;i<8;i++)
|
||||
inx
|
||||
jmp __b1
|
||||
}
|
||||
.segment Data
|
||||
// Flag tile
|
||||
FLAG: .byte $54, $55, $56, $57
|
||||
|
@ -74,28 +74,31 @@
|
||||
// Pointer to the start of RAM memory
|
||||
.label MEMORY = 0
|
||||
// NES Picture Processing Unit (PPU)
|
||||
// NES Picture Processing Unit (PPU)
|
||||
.label PPU = $2000
|
||||
// NES CPU and audion processing unit (APU)
|
||||
// NES CPU and audion processing unit (APU)
|
||||
.label APU = $4000
|
||||
.label y_sin_idx = $c
|
||||
.label x_sin_idx = $d
|
||||
.label x_sin_idx_2 = $e
|
||||
__bbegin:
|
||||
// y_sin_idx = 0
|
||||
// Index into the Y sine
|
||||
lda #0
|
||||
sta.z y_sin_idx
|
||||
// x_sin_idx = 73
|
||||
.label y_sin_idx = $c
|
||||
// Index into the X sine
|
||||
lda #$49
|
||||
sta.z x_sin_idx
|
||||
// x_sin_idx_2 = 82
|
||||
.label x_sin_idx = $d
|
||||
// Index into the small X sine
|
||||
lda #$52
|
||||
sta.z x_sin_idx_2
|
||||
jsr main
|
||||
rts
|
||||
.label x_sin_idx_2 = $e
|
||||
.segment Code
|
||||
_start: {
|
||||
// y_sin_idx = 0
|
||||
lda #0
|
||||
sta.z y_sin_idx
|
||||
// x_sin_idx = 73
|
||||
lda #$49
|
||||
sta.z x_sin_idx
|
||||
// x_sin_idx_2 = 82
|
||||
lda #$52
|
||||
sta.z x_sin_idx_2
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
// RESET Called when the NES is reset, including when it is turned on.
|
||||
main: {
|
||||
// asm
|
||||
@ -263,6 +266,7 @@ ppuDataTransfer: {
|
||||
.label ppuData = PPU_PALETTE
|
||||
.label cpuData = PALETTE
|
||||
// Transfer to PPU
|
||||
// Transfer to PPU
|
||||
.label cpuSrc = 6
|
||||
.label i = 4
|
||||
// PPU->PPUADDR = >ppuData
|
||||
@ -315,6 +319,7 @@ vblank: {
|
||||
.label __23 = $b
|
||||
.label __25 = $b
|
||||
.label __28 = $f
|
||||
// Update sprite positions
|
||||
.label y_idx = 9
|
||||
.label x_idx = $a
|
||||
.label x_idx_2 = $b
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Code by Scan of Desire (Richard-William Loerakker)
|
||||
// Sample from ART OF NOISE: MOMENTS IN LOVE
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
|
||||
.const CIA_INTERRUPT_CLEAR = $7f
|
||||
@ -23,14 +23,15 @@
|
||||
// The vector used when the KERNAL serves NMI interrupts
|
||||
.label KERNEL_NMI = $318
|
||||
.label sample = 2
|
||||
__bbegin:
|
||||
// sample = SAMPLE
|
||||
lda #<SAMPLE
|
||||
sta.z sample
|
||||
lda #>SAMPLE
|
||||
sta.z sample+1
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// sample = SAMPLE
|
||||
lda #<SAMPLE
|
||||
sta.z sample
|
||||
lda #>SAMPLE
|
||||
sta.z sample+1
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// asm
|
||||
// Boosting 8580 Digis
|
||||
|
@ -27,13 +27,13 @@
|
||||
.label COLS = $d800
|
||||
.label SCREEN1 = $2800
|
||||
.label CHARSET = $2000
|
||||
.label print_line_cursor = $400
|
||||
.label print_screen = $400
|
||||
.label print_char_cursor = $b
|
||||
// Plasma state variables
|
||||
.label c1A = 2
|
||||
.label c1B = 3
|
||||
.label c2A = 4
|
||||
.label c2B = 5
|
||||
.label c1A = $d
|
||||
.label c1B = $f
|
||||
.label c2A = $12
|
||||
.label c2B = 2
|
||||
main: {
|
||||
.const toD0181_return = (>(SCREEN1&$3fff)*4)|(>CHARSET)/4&$f
|
||||
.label col = $b
|
||||
@ -82,10 +82,10 @@ main: {
|
||||
}
|
||||
// Render plasma to the passed screen
|
||||
doplasma: {
|
||||
.label c1a = $f
|
||||
.label c1b = $12
|
||||
.label c1a = 4
|
||||
.label c1b = 5
|
||||
.label yval = $e
|
||||
.label i = $d
|
||||
.label i = 3
|
||||
.label c2a = 7
|
||||
.label c2b = 8
|
||||
.label i1 = 6
|
||||
@ -348,9 +348,9 @@ makecharset: {
|
||||
sta SID+OFFSET_STRUCT_MOS6581_SID_CH3_CONTROL
|
||||
// print_cls()
|
||||
jsr print_cls
|
||||
lda #<print_line_cursor
|
||||
lda #<print_screen
|
||||
sta.z print_char_cursor
|
||||
lda #>print_line_cursor
|
||||
lda #>print_screen
|
||||
sta.z print_char_cursor+1
|
||||
lda #<0
|
||||
sta.z c
|
||||
@ -481,7 +481,7 @@ print_cls: {
|
||||
memset: {
|
||||
.const c = ' '
|
||||
.const num = $3e8
|
||||
.label str = print_line_cursor
|
||||
.label str = print_screen
|
||||
.label end = str+num
|
||||
.label dst = $10
|
||||
lda #<str
|
||||
|
@ -26,13 +26,13 @@
|
||||
.label SCREEN1 = $2800
|
||||
.label SCREEN2 = $2c00
|
||||
.label CHARSET = $2000
|
||||
.label print_line_cursor = $400
|
||||
.label print_screen = $400
|
||||
.label print_char_cursor = $b
|
||||
// Plasma state variables
|
||||
.label c1A = 2
|
||||
.label c1B = 3
|
||||
.label c2A = 4
|
||||
.label c2B = 5
|
||||
.label c1A = $d
|
||||
.label c1B = $e
|
||||
.label c2A = $11
|
||||
.label c2B = 2
|
||||
main: {
|
||||
.const toD0181_return = (>(SCREEN1&$3fff)*4)|(>CHARSET)/4&$f
|
||||
.const toD0182_return = (>(SCREEN2&$3fff)*4)|(>CHARSET)/4&$f
|
||||
@ -96,9 +96,9 @@ main: {
|
||||
// Render plasma to the passed screen
|
||||
// doplasma(byte* zp(9) screen)
|
||||
doplasma: {
|
||||
.label c1a = $e
|
||||
.label c1b = $11
|
||||
.label i = $d
|
||||
.label c1a = 4
|
||||
.label c1b = 5
|
||||
.label i = 3
|
||||
.label c2a = 7
|
||||
.label c2b = 8
|
||||
.label i1 = 6
|
||||
@ -244,9 +244,9 @@ makecharset: {
|
||||
sta SID+OFFSET_STRUCT_MOS6581_SID_CH3_CONTROL
|
||||
// print_cls()
|
||||
jsr print_cls
|
||||
lda #<print_line_cursor
|
||||
lda #<print_screen
|
||||
sta.z print_char_cursor
|
||||
lda #>print_line_cursor
|
||||
lda #>print_screen
|
||||
sta.z print_char_cursor+1
|
||||
lda #<0
|
||||
sta.z c
|
||||
@ -377,7 +377,7 @@ print_cls: {
|
||||
memset: {
|
||||
.const c = ' '
|
||||
.const num = $3e8
|
||||
.label str = print_line_cursor
|
||||
.label str = print_screen
|
||||
.label end = str+num
|
||||
.label dst = $f
|
||||
lda #<str
|
||||
|
@ -262,11 +262,11 @@ rand: {
|
||||
rts
|
||||
}
|
||||
// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str.
|
||||
// memset(void* zp(5) str, byte register(X) c)
|
||||
// memset(void* zp(3) str, byte register(X) c)
|
||||
memset: {
|
||||
.label end = $13
|
||||
.label dst = 5
|
||||
.label str = 5
|
||||
.label dst = 3
|
||||
.label str = 3
|
||||
// end = (char*)str + num
|
||||
lda.z str
|
||||
clc
|
||||
|
@ -48,14 +48,19 @@ anim: {
|
||||
.label __12 = 3
|
||||
.label __26 = $13
|
||||
.label x = $b
|
||||
// signed fixed[7.0]
|
||||
.label y = $c
|
||||
.label xr = $d
|
||||
// signed fixed[8.8]
|
||||
.label yr = $f
|
||||
// signed fixed[8.8]
|
||||
.label xpos = $11
|
||||
// signed fixed[0.7]
|
||||
// signed fixed[0.7]
|
||||
.label sprite_msb = 2
|
||||
.label i = $a
|
||||
.label angle = 7
|
||||
// Calculate the cycle count - 0x12 is the base usage of start/read
|
||||
.label cyclecount = $13
|
||||
lda #0
|
||||
sta.z angle
|
||||
@ -470,17 +475,22 @@ init: {
|
||||
}
|
||||
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
|
||||
mulf_init: {
|
||||
// x/2
|
||||
// x/2
|
||||
.label c = 7
|
||||
// Counter used for determining x%2==0
|
||||
// Counter used for determining x%2==0
|
||||
.label sqr1_hi = 8
|
||||
// Fill mulf_sqr1 = f(x) = int(x*x/4): If f(x) = x*x/4 then f(x+1) = f(x) + x/2 + 1/4
|
||||
// Fill mulf_sqr1 = f(x) = int(x*x/4): If f(x) = x*x/4 then f(x+1) = f(x) + x/2 + 1/4
|
||||
.label sqr = $11
|
||||
.label sqr1_lo = 5
|
||||
// Decrease or increase x_255 - initially we decrease
|
||||
// Decrease or increase x_255 - initially we decrease
|
||||
.label sqr2_hi = $f
|
||||
.label sqr2_lo = $d
|
||||
//Start with g(0)=f(255)
|
||||
//Start with g(0)=f(255)
|
||||
.label dir = $a
|
||||
ldx #0
|
||||
lda #<mulf_sqr1_hi+1
|
||||
|
@ -17,7 +17,7 @@
|
||||
.label SCREEN = $400
|
||||
.label current_bit = 2
|
||||
// Scroll the next bit from the current char onto the screen - trigger next char if needed
|
||||
.label current_chargen = 3
|
||||
.label current_chargen = 7
|
||||
.label nxt = 5
|
||||
main: {
|
||||
// fillscreen(SCREEN, $20)
|
||||
@ -67,9 +67,9 @@ scroll_soft: {
|
||||
rts
|
||||
}
|
||||
scroll_bit: {
|
||||
.label __7 = 3
|
||||
.label c = 3
|
||||
.label sc = 7
|
||||
.label __7 = 7
|
||||
.label c = 7
|
||||
.label sc = 3
|
||||
// current_bit = current_bit/2
|
||||
lsr.z current_bit
|
||||
// if(current_bit==0)
|
||||
|
@ -29,6 +29,7 @@
|
||||
// Color Ram
|
||||
.label COLS = $d800
|
||||
.label SCREEN = $400
|
||||
// Remainder after unsigned 16-bit division
|
||||
.label rem16u = $1d
|
||||
.label xsin_idx = $27
|
||||
main: {
|
||||
@ -322,10 +323,14 @@ sin16s_gen2: {
|
||||
.label ampl = max-min
|
||||
.label __6 = 8
|
||||
.label __8 = $1d
|
||||
// ampl is always positive so shifting left does not alter the sign
|
||||
// u[4.28] step = PI*2/wavelength
|
||||
.label step = $19
|
||||
.label sintab = $14
|
||||
// u[4.28]
|
||||
// Iterate over the table
|
||||
// u[4.28]
|
||||
// Iterate over the table
|
||||
.label x = 4
|
||||
.label i = $27
|
||||
// div32u16u(PI2_u4f28, wavelength)
|
||||
@ -529,14 +534,23 @@ sin16s: {
|
||||
.label __4 = $1f
|
||||
.label x = $c
|
||||
.label return = $12
|
||||
// sinx = x - x^3/6 + x5/128;
|
||||
.label x1 = $23
|
||||
// u[1.15]
|
||||
.label x2 = $16
|
||||
// u[2.14] x^2
|
||||
.label x3 = $16
|
||||
// u[2.14] x^3
|
||||
.label x3_6 = $25
|
||||
// u[1.15] x^3/6;
|
||||
.label usinx = $12
|
||||
// u[1.15] x - x^3/6
|
||||
.label x4 = $16
|
||||
// u[3.13] x^4
|
||||
.label x5 = $25
|
||||
// u[4.12] x^5
|
||||
.label x5_128 = $25
|
||||
// u[1.15] (first bit is always zero)
|
||||
.label sinx = $12
|
||||
// if(x >= PI_u4f28 )
|
||||
lda.z x+3
|
||||
|
@ -35,7 +35,7 @@
|
||||
.label SCREEN = $400
|
||||
.label BITMAP = $2000
|
||||
// Remainder after unsigned 16-bit division
|
||||
.label rem16u = $12
|
||||
.label rem16u = $16
|
||||
main: {
|
||||
.const vicSelectGfxBank1_toDd001_return = 3
|
||||
.const toD0181_return = (>(SCREEN&$3fff)*4)|(>BITMAP)/4&$f
|
||||
@ -282,10 +282,14 @@ sin16s_gen2: {
|
||||
.label ampl = max-min
|
||||
.label __6 = 8
|
||||
.label __8 = $1c
|
||||
// ampl is always positive so shifting left does not alter the sign
|
||||
// u[4.28] step = PI*2/wavelength
|
||||
.label step = $18
|
||||
.label sintab = 6
|
||||
// u[4.28]
|
||||
// Iterate over the table
|
||||
// u[4.28]
|
||||
// Iterate over the table
|
||||
.label x = 2
|
||||
.label i = $14
|
||||
// div32u16u(PI2_u4f28, wavelength)
|
||||
@ -375,13 +379,13 @@ sin16s_gen2: {
|
||||
}
|
||||
// Multiply of two signed ints to a signed long
|
||||
// Fixes offsets introduced by using unsigned multiplication
|
||||
// mul16s(signed word zp($16) a)
|
||||
// mul16s(signed word zp($1c) a)
|
||||
mul16s: {
|
||||
.label __6 = $22
|
||||
.label __11 = $22
|
||||
.label m = 8
|
||||
.label return = 8
|
||||
.label a = $16
|
||||
.label a = $1c
|
||||
// mul16u((unsigned int)a, (unsigned int) b)
|
||||
lda.z a
|
||||
sta.z mul16u.a
|
||||
@ -420,10 +424,10 @@ mul16s: {
|
||||
rts
|
||||
}
|
||||
// Perform binary multiplication of two unsigned 16-bit unsigned ints into a 32-bit unsigned long
|
||||
// mul16u(word zp($12) a, word zp($c) b)
|
||||
// mul16u(word zp($16) a, word zp($c) b)
|
||||
mul16u: {
|
||||
.label mb = $e
|
||||
.label a = $12
|
||||
.label a = $16
|
||||
.label res = 8
|
||||
.label return = 8
|
||||
.label b = $c
|
||||
@ -488,16 +492,25 @@ mul16u: {
|
||||
sin16s: {
|
||||
.label __4 = $1e
|
||||
.label x = $e
|
||||
.label return = $16
|
||||
.label return = $1c
|
||||
// sinx = x - x^3/6 + x5/128;
|
||||
.label x1 = $22
|
||||
.label x2 = $1c
|
||||
.label x3 = $1c
|
||||
// u[1.15]
|
||||
.label x2 = $12
|
||||
// u[2.14] x^2
|
||||
.label x3 = $12
|
||||
// u[2.14] x^3
|
||||
.label x3_6 = $24
|
||||
.label usinx = $16
|
||||
.label x4 = $1c
|
||||
// u[1.15] x^3/6;
|
||||
.label usinx = $1c
|
||||
// u[1.15] x - x^3/6
|
||||
.label x4 = $12
|
||||
// u[3.13] x^4
|
||||
.label x5 = $24
|
||||
// u[4.12] x^5
|
||||
.label x5_128 = $24
|
||||
.label sinx = $16
|
||||
// u[1.15] (first bit is always zero)
|
||||
.label sinx = $1c
|
||||
// if(x >= PI_u4f28 )
|
||||
lda.z x+3
|
||||
cmp #>PI_u4f28>>$10
|
||||
@ -695,14 +708,14 @@ sin16s: {
|
||||
}
|
||||
// Calculate val*val for two unsigned int values - the result is 16 selected bits of the 32-bit result.
|
||||
// The select parameter indicates how many of the highest bits of the 32-bit result to skip
|
||||
// mulu16_sel(word zp($1c) v1, word zp($c) v2, byte register(X) select)
|
||||
// mulu16_sel(word zp($12) v1, word zp($c) v2, byte register(X) select)
|
||||
mulu16_sel: {
|
||||
.label __0 = 8
|
||||
.label __1 = 8
|
||||
.label v1 = $1c
|
||||
.label v1 = $12
|
||||
.label v2 = $c
|
||||
.label return = $24
|
||||
.label return_1 = $1c
|
||||
.label return_1 = $12
|
||||
// mul16u(v1, v2)
|
||||
lda.z v1
|
||||
sta.z mul16u.a
|
||||
@ -733,7 +746,7 @@ mulu16_sel: {
|
||||
// The 16-bit unsigned int remainder can be found in rem16u after the division
|
||||
div32u16u: {
|
||||
.label quotient_hi = $24
|
||||
.label quotient_lo = $1c
|
||||
.label quotient_lo = $12
|
||||
.label return = $18
|
||||
// divr16u(>dividend, divisor, 0)
|
||||
lda #<PI2_u4f28>>$10
|
||||
@ -774,12 +787,12 @@ div32u16u: {
|
||||
// Returns the quotient dividend/divisor.
|
||||
// The final remainder will be set into the global variable rem16u
|
||||
// Implemented using simple binary division
|
||||
// divr16u(word zp($16) dividend, word zp($12) rem)
|
||||
// divr16u(word zp($1c) dividend, word zp($16) rem)
|
||||
divr16u: {
|
||||
.label rem = $12
|
||||
.label dividend = $16
|
||||
.label quotient = $1c
|
||||
.label return = $1c
|
||||
.label rem = $16
|
||||
.label dividend = $1c
|
||||
.label quotient = $12
|
||||
.label return = $12
|
||||
ldx #0
|
||||
txa
|
||||
sta.z quotient
|
||||
|
@ -29,11 +29,11 @@
|
||||
.label sprites = $2000
|
||||
.label SCREEN = $400
|
||||
// Current index within the progress cursor (0-7)
|
||||
.label progress_idx = 4
|
||||
.label progress_idx = $a
|
||||
// Current position of the progress cursor
|
||||
.label progress_cursor = 5
|
||||
.label sin_idx_x = 2
|
||||
.label sin_idx_y = 3
|
||||
.label progress_cursor = 2
|
||||
.label sin_idx_x = 6
|
||||
.label sin_idx_y = 8
|
||||
main: {
|
||||
// init()
|
||||
jsr init
|
||||
@ -53,10 +53,10 @@ anim: {
|
||||
.label __7 = $a
|
||||
.label xidx = 9
|
||||
.label yidx = 4
|
||||
.label x = $10
|
||||
.label x = $f
|
||||
.label x_msb = $a
|
||||
.label j2 = $b
|
||||
.label j = 8
|
||||
.label j = 5
|
||||
// (VICII->BORDER_COLOR)++;
|
||||
inc VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR
|
||||
// xidx = sin_idx_x
|
||||
@ -214,7 +214,7 @@ init: {
|
||||
rts
|
||||
}
|
||||
clear_screen: {
|
||||
.label sc = $10
|
||||
.label sc = $f
|
||||
lda #<SCREEN
|
||||
sta.z sc
|
||||
lda #>SCREEN
|
||||
@ -248,15 +248,16 @@ clear_screen: {
|
||||
// - 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(byte* zp($10) sintab, byte zp($a) length, byte zp(9) min, byte register(X) max)
|
||||
// gen_sintab(byte* zp($f) sintab, byte zp(8) length, byte zp(6) min, byte register(X) max)
|
||||
gen_sintab: {
|
||||
// amplitude/2
|
||||
// amplitude/2
|
||||
.label f_2pi = $e2e5
|
||||
.label __20 = $13
|
||||
.label i = $b
|
||||
.label min = 9
|
||||
.label length = $a
|
||||
.label sintab = $10
|
||||
.label i = 9
|
||||
.label min = 6
|
||||
.label length = 8
|
||||
.label sintab = $f
|
||||
// setFAC((unsigned int)max)
|
||||
txa
|
||||
sta.z setFAC.w
|
||||
@ -574,14 +575,14 @@ setARGtoFAC: {
|
||||
rts
|
||||
}
|
||||
// Initialize the PETSCII progress bar
|
||||
// progress_init(byte* zp(5) line)
|
||||
// progress_init(byte* zp(2) line)
|
||||
progress_init: {
|
||||
.label line = 5
|
||||
.label line = 2
|
||||
rts
|
||||
}
|
||||
gen_sprites: {
|
||||
.label spr = $10
|
||||
.label i = 8
|
||||
.label spr = 2
|
||||
.label i = $b
|
||||
lda #<sprites
|
||||
sta.z spr
|
||||
lda #>sprites
|
||||
@ -617,19 +618,22 @@ gen_sprites: {
|
||||
// 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(byte register(X) ch, byte* zp($13) sprite)
|
||||
// gen_chargen_sprite(byte register(X) ch, byte* zp($f) sprite)
|
||||
gen_chargen_sprite: {
|
||||
.label __0 = $15
|
||||
.label __14 = $15
|
||||
.label sprite = $13
|
||||
.label chargen = $15
|
||||
.label bits = $a
|
||||
.label __0 = $13
|
||||
.label __14 = $13
|
||||
.label sprite = $f
|
||||
.label chargen = $13
|
||||
// current chargen line
|
||||
.label bits = 5
|
||||
// current sprite char
|
||||
.label s_gen = $f
|
||||
.label x = $b
|
||||
.label y = 9
|
||||
// current sprite char
|
||||
.label s_gen = 9
|
||||
.label x = 6
|
||||
.label y = 4
|
||||
// Find the current chargen pixel (c)
|
||||
.label c = $c
|
||||
// Find the current chargen pixel (c)
|
||||
.label c = 8
|
||||
// ((unsigned int)ch)*8
|
||||
txa
|
||||
sta.z __14
|
||||
@ -746,11 +750,11 @@ gen_chargen_sprite: {
|
||||
}
|
||||
place_sprites: {
|
||||
.label sprites_ptr = SCREEN+$3f8
|
||||
.label spr_id = 9
|
||||
.label spr_x = $b
|
||||
.label col = $f
|
||||
.label j2 = $c
|
||||
.label j = $a
|
||||
.label spr_id = 6
|
||||
.label spr_x = 9
|
||||
.label col = $b
|
||||
.label j2 = $a
|
||||
.label j = 8
|
||||
// VICII->SPRITES_ENABLE = %01111111
|
||||
lda #$7f
|
||||
sta VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE
|
||||
|
@ -14,8 +14,22 @@
|
||||
|
||||
.label RASTER = $d012
|
||||
.label BG_COLOR = $d020
|
||||
.segment ZpCode
|
||||
zpLoop: {
|
||||
ldx #0
|
||||
__b1:
|
||||
// (*BG_COLOR)++;
|
||||
inc BG_COLOR
|
||||
// for(char i:0..100)
|
||||
inx
|
||||
cpx #$65
|
||||
bne __b1
|
||||
// }
|
||||
rts
|
||||
}
|
||||
.segment Code
|
||||
main: {
|
||||
// Transfer ZP-code to zeropage
|
||||
// Transfer ZP-code to zeropage
|
||||
.label zpCode = zpLoop
|
||||
// asm
|
||||
@ -48,20 +62,6 @@ main: {
|
||||
inx
|
||||
jmp __b1
|
||||
}
|
||||
.segment ZpCode
|
||||
zpLoop: {
|
||||
ldx #0
|
||||
__b1:
|
||||
// (*BG_COLOR)++;
|
||||
inc BG_COLOR
|
||||
// for(char i:0..100)
|
||||
inx
|
||||
cpx #$65
|
||||
bne __b1
|
||||
// }
|
||||
rts
|
||||
}
|
||||
.segment Code
|
||||
// Code in "normal" memory
|
||||
loop: {
|
||||
ldx #0
|
||||
|
@ -6,15 +6,16 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.label print_line_cursor = 3
|
||||
.label print_char_cursor = 5
|
||||
.label print_screen = $400
|
||||
.label print_char_cursor = 8
|
||||
.label print_line_cursor = 6
|
||||
main: {
|
||||
// print_cls()
|
||||
jsr print_cls
|
||||
// print_str("unsigned")
|
||||
lda #<$400
|
||||
lda #<print_screen
|
||||
sta.z print_char_cursor
|
||||
lda #>$400
|
||||
lda #>print_screen
|
||||
sta.z print_char_cursor+1
|
||||
lda #<str
|
||||
sta.z print_str.str
|
||||
@ -22,9 +23,9 @@ main: {
|
||||
sta.z print_str.str+1
|
||||
jsr print_str
|
||||
// print_ln()
|
||||
lda #<$400
|
||||
lda #<print_screen
|
||||
sta.z print_line_cursor
|
||||
lda #>$400
|
||||
lda #>print_screen
|
||||
sta.z print_line_cursor+1
|
||||
jsr print_ln
|
||||
// print_mulf8u127(0,0)
|
||||
@ -141,10 +142,10 @@ main: {
|
||||
str1: .text "signed"
|
||||
.byte 0
|
||||
}
|
||||
// print_mulf8s127(signed byte zp(9) a, signed byte zp(2) b)
|
||||
// print_mulf8s127(signed byte zp(5) a, signed byte zp(2) b)
|
||||
print_mulf8s127: {
|
||||
.label c = 7
|
||||
.label a = 9
|
||||
.label c = 3
|
||||
.label a = 5
|
||||
.label b = 2
|
||||
// mulf8s127(a,b)
|
||||
ldy.z b
|
||||
@ -198,9 +199,9 @@ print_ln: {
|
||||
rts
|
||||
}
|
||||
// Print a signed int as HEX
|
||||
// print_sint(signed word zp(7) w)
|
||||
// print_sint(signed word zp(3) w)
|
||||
print_sint: {
|
||||
.label w = 7
|
||||
.label w = 3
|
||||
// if(w<0)
|
||||
lda.z w+1
|
||||
bmi __b1
|
||||
@ -241,9 +242,9 @@ print_char: {
|
||||
rts
|
||||
}
|
||||
// Print a unsigned int as HEX
|
||||
// print_uint(word zp(7) w)
|
||||
// print_uint(word zp(3) w)
|
||||
print_uint: {
|
||||
.label w = 7
|
||||
.label w = 3
|
||||
// print_uchar(>w)
|
||||
ldx.z w+1
|
||||
jsr print_uchar
|
||||
@ -302,15 +303,15 @@ print_schar: {
|
||||
tax
|
||||
jmp __b2
|
||||
}
|
||||
// mulf8s127(signed byte zp(9) a, signed byte register(Y) b)
|
||||
// mulf8s127(signed byte zp(5) a, signed byte register(Y) b)
|
||||
mulf8s127: {
|
||||
.label __9 = $a
|
||||
.label __10 = $c
|
||||
.label __11 = $a
|
||||
.label __12 = $c
|
||||
.label a = 9
|
||||
.label return = 7
|
||||
.label c = 7
|
||||
.label __9 = 8
|
||||
.label __10 = $a
|
||||
.label __11 = 8
|
||||
.label __12 = $a
|
||||
.label a = 5
|
||||
.label return = 3
|
||||
.label c = 3
|
||||
// mulf8u127((unsigned char)a, (unsigned char)b)
|
||||
ldx.z a
|
||||
tya
|
||||
@ -387,7 +388,7 @@ mulf8u127: {
|
||||
.label res = $fe
|
||||
.label resL = $fe
|
||||
.label resH = $ff
|
||||
.label return = 7
|
||||
.label return = 3
|
||||
// *memA = a
|
||||
stx memA
|
||||
// *memB = b
|
||||
@ -420,9 +421,9 @@ mulf8u127: {
|
||||
rts
|
||||
}
|
||||
// Print a zero-terminated string
|
||||
// print_str(byte* zp(7) str)
|
||||
// print_str(byte* zp(3) str)
|
||||
print_str: {
|
||||
.label str = 7
|
||||
.label str = 3
|
||||
__b1:
|
||||
// while(*str)
|
||||
ldy #0
|
||||
@ -443,10 +444,10 @@ print_str: {
|
||||
!:
|
||||
jmp __b1
|
||||
}
|
||||
// print_mulf8u127(byte register(Y) a, byte zp(9) b)
|
||||
// print_mulf8u127(byte register(Y) a, byte zp(5) b)
|
||||
print_mulf8u127: {
|
||||
.label c = 7
|
||||
.label b = 9
|
||||
.label c = 3
|
||||
.label b = 5
|
||||
// mulf8u127(a,b)
|
||||
tya
|
||||
tax
|
||||
@ -490,9 +491,9 @@ print_cls: {
|
||||
memset: {
|
||||
.const c = ' '
|
||||
.const num = $3e8
|
||||
.label str = $400
|
||||
.label str = print_screen
|
||||
.label end = str+num
|
||||
.label dst = $a
|
||||
.label dst = 6
|
||||
lda #<str
|
||||
sta.z dst
|
||||
lda #>str
|
||||
|
@ -2,10 +2,20 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// kickasm
|
||||
ff:
|
||||
jmp (main.f)
|
||||
|
||||
fn2: {
|
||||
.label BG_COLOR = $d021
|
||||
// (*BG_COLOR)++;
|
||||
inc BG_COLOR
|
||||
// }
|
||||
rts
|
||||
}
|
||||
fn1: {
|
||||
.label BORDER_COLOR = $d020
|
||||
// (*BORDER_COLOR)++;
|
||||
inc BORDER_COLOR
|
||||
// }
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.label f = 2
|
||||
ldx #0
|
||||
@ -34,17 +44,7 @@ main: {
|
||||
|
||||
jmp __b2
|
||||
}
|
||||
fn2: {
|
||||
.label BG_COLOR = $d021
|
||||
// (*BG_COLOR)++;
|
||||
inc BG_COLOR
|
||||
// }
|
||||
rts
|
||||
}
|
||||
fn1: {
|
||||
.label BORDER_COLOR = $d020
|
||||
// (*BORDER_COLOR)++;
|
||||
inc BORDER_COLOR
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// Inline KickAsm function
|
||||
ff:
|
||||
jmp (main.f)
|
||||
|
||||
|
@ -1,15 +1,16 @@
|
||||
// Tests calling into different function pointers which call a common sub-method
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
.label idx = 7
|
||||
__bbegin:
|
||||
// idx = 0
|
||||
lda #0
|
||||
sta.z idx
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// idx = 0
|
||||
lda #0
|
||||
sta.z idx
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// do10(&hello)
|
||||
lda #<hello
|
||||
|
@ -2,6 +2,20 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
fn2: {
|
||||
.label BG_COLOR = $d021
|
||||
// (*BG_COLOR)++;
|
||||
inc BG_COLOR
|
||||
// }
|
||||
rts
|
||||
}
|
||||
fn1: {
|
||||
.label BORDER_COLOR = $d020
|
||||
// (*BORDER_COLOR)++;
|
||||
inc BORDER_COLOR
|
||||
// }
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.label i = 2
|
||||
.label f = 3
|
||||
@ -33,17 +47,3 @@ main: {
|
||||
bi_f:
|
||||
jmp (f)
|
||||
}
|
||||
fn2: {
|
||||
.label BG_COLOR = $d021
|
||||
// (*BG_COLOR)++;
|
||||
inc BG_COLOR
|
||||
// }
|
||||
rts
|
||||
}
|
||||
fn1: {
|
||||
.label BORDER_COLOR = $d020
|
||||
// (*BORDER_COLOR)++;
|
||||
inc BORDER_COLOR
|
||||
// }
|
||||
rts
|
||||
}
|
||||
|
@ -2,6 +2,20 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
fn2: {
|
||||
.label BG_COLOR = $d021
|
||||
// (*BG_COLOR)++;
|
||||
inc BG_COLOR
|
||||
// }
|
||||
rts
|
||||
}
|
||||
fn1: {
|
||||
.label BORDER_COLOR = $d020
|
||||
// (*BORDER_COLOR)++;
|
||||
inc BORDER_COLOR
|
||||
// }
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.label __1 = 3
|
||||
.label i = 2
|
||||
@ -40,17 +54,3 @@ getfn: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
fn2: {
|
||||
.label BG_COLOR = $d021
|
||||
// (*BG_COLOR)++;
|
||||
inc BG_COLOR
|
||||
// }
|
||||
rts
|
||||
}
|
||||
fn1: {
|
||||
.label BORDER_COLOR = $d020
|
||||
// (*BORDER_COLOR)++;
|
||||
inc BORDER_COLOR
|
||||
// }
|
||||
rts
|
||||
}
|
||||
|
@ -2,17 +2,6 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
ldx #0
|
||||
__b2:
|
||||
// (*getfn(++i))();
|
||||
inx
|
||||
// getfn(++i)
|
||||
jsr getfn
|
||||
// (*getfn(++i))()
|
||||
jsr fn1
|
||||
jmp __b2
|
||||
}
|
||||
fn1: {
|
||||
.label BORDER_COLOR = $d020
|
||||
// (*BORDER_COLOR)++;
|
||||
@ -20,6 +9,12 @@ fn1: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
getfn: {
|
||||
rts
|
||||
main: {
|
||||
ldx #0
|
||||
__b2:
|
||||
// (*getfn(++i))();
|
||||
inx
|
||||
// (*getfn(++i))()
|
||||
jsr fn1
|
||||
jmp __b2
|
||||
}
|
||||
|
@ -1,15 +1,16 @@
|
||||
// Tests calling into a function pointer with local variables
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
.label idx = 3
|
||||
__bbegin:
|
||||
// idx = 0
|
||||
lda #0
|
||||
sta.z idx
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// idx = 0
|
||||
lda #0
|
||||
sta.z idx
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// do10(f)
|
||||
jsr do10
|
||||
|
@ -1,19 +1,20 @@
|
||||
// Tests calling into a function pointer with local variables
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
.label msg = 3
|
||||
.label idx = 5
|
||||
__bbegin:
|
||||
// msg
|
||||
lda #<0
|
||||
sta.z msg
|
||||
sta.z msg+1
|
||||
// idx = 0
|
||||
sta.z idx
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// msg
|
||||
lda #<0
|
||||
sta.z msg
|
||||
sta.z msg+1
|
||||
// idx = 0
|
||||
sta.z idx
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// msg = msg1
|
||||
lda #<msg1
|
||||
|
@ -1,15 +1,16 @@
|
||||
// Tests calling into a function pointer which modifies global volatile
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
:BasicUpstart(_start)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
.label idx = 2
|
||||
__bbegin:
|
||||
// idx = 0
|
||||
lda #0
|
||||
sta.z idx
|
||||
jsr main
|
||||
rts
|
||||
_start: {
|
||||
// idx = 0
|
||||
lda #0
|
||||
sta.z idx
|
||||
jsr main
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
// (*f)()
|
||||
jsr fn1
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user