1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-08-03 01:29:04 +00:00

Now comments on global variables are no longer destroyed. However some comments appear twice!

This commit is contained in:
jespergravgaard 2020-06-27 20:32:09 +02:00
parent e09a0718d0
commit aee57979ef
228 changed files with 10882 additions and 3735 deletions

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

@ -0,0 +1,11 @@
// Test removal of empty function
char * const SCREEN = 0x0400;
void main() {
empty();
SCREEN[0] = 'x';
}
void empty() {
}

View File

@ -0,0 +1,9 @@
// Test removal of empty function
// main() should not be removed!
void main() {
empty();
}
void empty() {
}

View File

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

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -700,11 +700,5 @@ f98: {
}
f99: {
.label return = 1
// f100(x)
jsr f100
// }
rts
}
f100: {
rts
}

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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