1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-02-17 10:30:43 +00:00

Added support for block comments.

This commit is contained in:
jespergravgaard 2019-02-18 00:12:29 +01:00
parent f0d77acb29
commit af54695232
291 changed files with 7705 additions and 6949 deletions

View File

@ -7,8 +7,11 @@ public class AsmComment implements AsmLine {
private int index;
public AsmComment(String comment) {
private boolean isBlock;
public AsmComment(String comment, boolean isBlock) {
this.comment = comment;
this.isBlock = isBlock;
}
public String getComment() {
@ -27,7 +30,12 @@ public class AsmComment implements AsmLine {
@Override
public String getAsm() {
return "// " + comment;
if(isBlock) {
return "/*" + comment + "*/";
} else {
return "//" + comment;
}
}
@Override
@ -47,6 +55,7 @@ public class AsmComment implements AsmLine {
/**
* Get the number of lines the comment has
*
* @return The number of lines
*/
public long getLineCount() {
@ -54,5 +63,4 @@ public class AsmComment implements AsmLine {
}
}

View File

@ -52,8 +52,8 @@ public class AsmProgram {
getCurrentSegment().addLine(line);
}
public void addComment(String comment) {
addLine(new AsmComment(comment));
public void addComment(String comment, boolean isBlock) {
addLine(new AsmComment(comment, isBlock));
}
public AsmLabel addLabel(String label) {

View File

@ -12,10 +12,12 @@ public class Comment {
/** Empty comments collection. */
public static final ArrayList<Comment> NO_COMMENTS = new ArrayList<>();
/** The comment. */
private String comment;
/** Specifies whether the comment is a block-comment. If false the comment is a single-line comment. */
private boolean isBlock;
/** The index of the hidden parser token containing the comment.
* Used to prevent comments from being included multiple times.
*/
@ -36,4 +38,12 @@ public class Comment {
public void setTokenIndex(int tokenIndex) {
this.tokenIndex = tokenIndex;
}
public boolean isBlock() {
return isBlock;
}
public void setBlock(boolean block) {
isBlock = block;
}
}

View File

@ -173,7 +173,7 @@ public class ControlFlowBlock {
for(Statement statement : statements) {
if(program.getLog().isVerboseComments()) {
for(Comment comment : statement.getComments()) {
out.append(" // " + comment.getComment() + "\n");
out.append(" //" + comment.getComment() + "\n");
}
}
out.append(" " + statement.toString(program, program.getLog().isVerboseLiveRanges()) + "\n");

View File

@ -34,7 +34,7 @@ public class StatementSequence {
}
if(program.getLog().isVerboseComments()) {
for(Comment comment : statement.getComments()) {
out.append(indent + "// " + comment + "\n");
out.append(indent + "//" + comment + "\n");
}
}
out.append(indent);

View File

@ -947,11 +947,17 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
comments = new ArrayList<>();
}
} else if(hiddenToken.getChannel() == CHANNEL_COMMENTS) {
boolean isBlock = false;
String text = hiddenToken.getText();
if(text.startsWith("//")) {
text = text.substring(2);
}
if(text.startsWith("/*")) {
text = text.substring(2, text.length()-2);
isBlock = true;
}
Comment comment = new Comment(text);
comment.setBlock(isBlock);
comment.setTokenIndex(hiddenToken.getTokenIndex());
comments.add( comment);
}

View File

@ -190,7 +190,7 @@ public class Pass4CodeGeneration {
*/
private void generateComments(AsmProgram asm, List<Comment> comments) {
for(Comment comment : comments) {
asm.addComment(comment.getComment());
asm.addComment(comment.getComment(), comment.isBlock());
}
}

View File

@ -44,6 +44,11 @@ public class TestPrograms {
AsmFragmentTemplateUsages.logUsages(log, false, false, false, false, false, false);
}
@Test
public void testCommentsBlock() throws IOException, URISyntaxException {
compileAndCompare("test-comments-block");
}
@Test
public void testCommentsLoop() throws IOException, URISyntaxException {
compileAndCompare("test-comments-loop");

View File

@ -0,0 +1,31 @@
/* Tests that block comments are compiled correctly
* Has a bunch of comments that will be moved into the generated ASM
*/
// The C64 screen
const byte* SCREEN = $400;
// One of the bytes used for addition
byte a = 'a';
/* The program entry point */
void main() {
byte i = 0;
// Do some sums
for(byte b: 0..10 ) {
// Output the result on the screen
SCREEN[i++] = sum(a, b);
}
}
/** Adds up two bytes and returns the result
* a - the first byte
* b - the second byte
* Returns the sum pf the two bytes
*/
byte sum( byte a, byte b) {
// calculate the sum
byte r = a+b;
// return the sum
return r;
}

View File

@ -1,9 +1,9 @@
// Illustrates symbolic array lengths
// Illustrates symbolic array lengths
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.const SZ = $f
// Fills the array item by item with $is, where i is the item# and s is the sub#
// Fills the array item by item with $is, where i is the item# and s is the sub#
main: {
ldx #0
b1:

View File

@ -137,7 +137,7 @@ Allocated zp ZP_BYTE:2 [ main::sub#2 main::sub#1 ]
INITIAL ASM
//SEG0 File Comments
// Illustrates symbolic array lengths
// Illustrates symbolic array lengths
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -161,7 +161,7 @@ bend_from_b1:
//SEG9 @end
bend:
//SEG10 main
// Fills the array item by item with $is, where i is the item# and s is the sub#
// Fills the array item by item with $is, where i is the item# and s is the sub#
main: {
.label sub = 2
//SEG11 [5] phi from main to main::@1 [phi:main->main::@1]
@ -206,7 +206,7 @@ Uplifting [] best 263 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Illustrates symbolic array lengths
// Illustrates symbolic array lengths
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -230,7 +230,7 @@ bend_from_b1:
//SEG9 @end
bend:
//SEG10 main
// Fills the array item by item with $is, where i is the item# and s is the sub#
// Fills the array item by item with $is, where i is the item# and s is the sub#
main: {
//SEG11 [5] phi from main to main::@1 [phi:main->main::@1]
b1_from_main:
@ -307,7 +307,7 @@ FINAL ASSEMBLER
Score: 161
//SEG0 File Comments
// Illustrates symbolic array lengths
// Illustrates symbolic array lengths
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
@ -322,7 +322,7 @@ Score: 161
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
//SEG9 @end
//SEG10 main
// Fills the array item by item with $is, where i is the item# and s is the sub#
// Fills the array item by item with $is, where i is the item# and s is the sub#
main: {
//SEG11 [5] phi from main to main::@1 [phi:main->main::@1]
//SEG12 [5] phi (byte) main::sub#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1

View File

@ -1,10 +1,10 @@
// Illustrates symbolic array lengths
// Illustrates symbolic array lengths
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.const ITEM_COUNT = 3
.const ITEM_SIZE = 5
// Fills the array item by item with $is, where i is the item# and s is the sub#
// Fills the array item by item with $is, where i is the item# and s is the sub#
main: {
.label cur_item = 2
lda #<items

View File

@ -244,7 +244,7 @@ Allocated zp ZP_BYTE:7 [ main::$3 ]
INITIAL ASM
//SEG0 File Comments
// Illustrates symbolic array lengths
// Illustrates symbolic array lengths
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -269,7 +269,7 @@ bend_from_b1:
//SEG9 @end
bend:
//SEG10 main
// Fills the array item by item with $is, where i is the item# and s is the sub#
// Fills the array item by item with $is, where i is the item# and s is the sub#
main: {
.label _2 = 6
.label _3 = 7
@ -376,7 +376,7 @@ Allocated (was zp ZP_WORD:3) zp ZP_WORD:2 [ main::cur_item#4 main::cur_item#1 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Illustrates symbolic array lengths
// Illustrates symbolic array lengths
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -401,7 +401,7 @@ bend_from_b1:
//SEG9 @end
bend:
//SEG10 main
// Fills the array item by item with $is, where i is the item# and s is the sub#
// Fills the array item by item with $is, where i is the item# and s is the sub#
main: {
.label cur_item = 2
//SEG11 [5] phi from main to main::@1 [phi:main->main::@1]
@ -542,7 +542,7 @@ FINAL ASSEMBLER
Score: 3416
//SEG0 File Comments
// Illustrates symbolic array lengths
// Illustrates symbolic array lengths
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
@ -558,7 +558,7 @@ Score: 3416
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
//SEG9 @end
//SEG10 main
// Fills the array item by item with $is, where i is the item# and s is the sub#
// Fills the array item by item with $is, where i is the item# and s is the sub#
main: {
.label cur_item = 2
//SEG11 [5] phi from main to main::@1 [phi:main->main::@1]

View File

@ -1,4 +1,4 @@
// Tests that inline ASM clobbering is taken into account when assigning registers
// Tests that inline ASM clobbering is taken into account when assigning registers
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
@ -6,7 +6,7 @@
main: {
.label l = 2
ldx #0
// First loop with no clobber
// First loop with no clobber
b1:
lda #0
b2:
@ -19,7 +19,7 @@ main: {
cpx #$65
bne b1
ldy #0
// Then loop with clobbering A&X
// Then loop with clobbering A&X
b3:
lda #0
sta l

View File

@ -274,7 +274,7 @@ Allocated zp ZP_BYTE:5 [ main::l#2 main::l#1 ]
INITIAL ASM
//SEG0 File Comments
// Tests that inline ASM clobbering is taken into account when assigning registers
// Tests that inline ASM clobbering is taken into account when assigning registers
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -309,7 +309,7 @@ main: {
lda #0
sta i
jmp b1
// First loop with no clobber
// First loop with no clobber
//SEG13 [5] phi from main::@5 to main::@1 [phi:main::@5->main::@1]
b1_from_b5:
//SEG14 [5] phi (byte) main::i#4 = (byte) main::i#1 [phi:main::@5->main::@1#0] -- register_copy
@ -353,7 +353,7 @@ main: {
lda #0
sta k
jmp b3
// Then loop with clobbering A&X
// Then loop with clobbering A&X
//SEG29 [12] phi from main::@7 to main::@3 [phi:main::@7->main::@3]
b3_from_b7:
//SEG30 [12] phi (byte) main::k#4 = (byte) main::k#1 [phi:main::@7->main::@3#0] -- register_copy
@ -427,7 +427,7 @@ Allocated (was zp ZP_BYTE:5) zp ZP_BYTE:2 [ main::l#2 main::l#1 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Tests that inline ASM clobbering is taken into account when assigning registers
// Tests that inline ASM clobbering is taken into account when assigning registers
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -458,7 +458,7 @@ main: {
//SEG12 [5] phi (byte) main::i#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #0
jmp b1
// First loop with no clobber
// First loop with no clobber
//SEG13 [5] phi from main::@5 to main::@1 [phi:main::@5->main::@1]
b1_from_b5:
//SEG14 [5] phi (byte) main::i#4 = (byte) main::i#1 [phi:main::@5->main::@1#0] -- register_copy
@ -497,7 +497,7 @@ main: {
//SEG28 [12] phi (byte) main::k#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@5->main::@3#0] -- vbuyy=vbuc1
ldy #0
jmp b3
// Then loop with clobbering A&X
// Then loop with clobbering A&X
//SEG29 [12] phi from main::@7 to main::@3 [phi:main::@7->main::@3]
b3_from_b7:
//SEG30 [12] phi (byte) main::k#4 = (byte) main::k#1 [phi:main::@7->main::@3#0] -- register_copy
@ -624,7 +624,7 @@ FINAL ASSEMBLER
Score: 4676
//SEG0 File Comments
// Tests that inline ASM clobbering is taken into account when assigning registers
// Tests that inline ASM clobbering is taken into account when assigning registers
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
@ -644,7 +644,7 @@ main: {
//SEG11 [5] phi from main to main::@1 [phi:main->main::@1]
//SEG12 [5] phi (byte) main::i#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #0
// First loop with no clobber
// First loop with no clobber
//SEG13 [5] phi from main::@5 to main::@1 [phi:main::@5->main::@1]
//SEG14 [5] phi (byte) main::i#4 = (byte) main::i#1 [phi:main::@5->main::@1#0] -- register_copy
//SEG15 main::@1
@ -673,7 +673,7 @@ main: {
//SEG27 [12] phi from main::@5 to main::@3 [phi:main::@5->main::@3]
//SEG28 [12] phi (byte) main::k#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@5->main::@3#0] -- vbuyy=vbuc1
ldy #0
// Then loop with clobbering A&X
// Then loop with clobbering A&X
//SEG29 [12] phi from main::@7 to main::@3 [phi:main::@7->main::@3]
//SEG30 [12] phi (byte) main::k#4 = (byte) main::k#1 [phi:main::@7->main::@3#0] -- register_copy
//SEG31 main::@3

View File

@ -1,4 +1,4 @@
// Tests that chained assignments work as intended
// Tests that chained assignments work as intended
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
@ -12,7 +12,7 @@ main: {
sta screen+$29
lda #1+'l'
sta screen+2
// Chained assignment with a modification of the result
// Chained assignment with a modification of the result
lda #'l'
sta screen+$2a
rts

View File

@ -113,7 +113,7 @@ Allocated zp ZP_BYTE:2 [ main::a#1 ]
INITIAL ASM
//SEG0 File Comments
// Tests that chained assignments work as intended
// Tests that chained assignments work as intended
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -156,7 +156,7 @@ main: {
lda #1+'l'
sta screen+2
//SEG16 [10] *((const byte*) main::screen#0+(byte/signed byte/word/signed word/dword/signed dword) 42) ← (byte) 'l' -- _deref_pbuc1=vbuc2
// Chained assignment with a modification of the result
// Chained assignment with a modification of the result
lda #'l'
sta screen+$2a
jmp breturn
@ -183,7 +183,7 @@ Uplifting [] best 59 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Tests that chained assignments work as intended
// Tests that chained assignments work as intended
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -223,7 +223,7 @@ main: {
lda #1+'l'
sta screen+2
//SEG16 [10] *((const byte*) main::screen#0+(byte/signed byte/word/signed word/dword/signed dword) 42) ← (byte) 'l' -- _deref_pbuc1=vbuc2
// Chained assignment with a modification of the result
// Chained assignment with a modification of the result
lda #'l'
sta screen+$2a
jmp breturn
@ -272,7 +272,7 @@ FINAL ASSEMBLER
Score: 38
//SEG0 File Comments
// Tests that chained assignments work as intended
// Tests that chained assignments work as intended
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
@ -302,7 +302,7 @@ main: {
lda #1+'l'
sta screen+2
//SEG16 [10] *((const byte*) main::screen#0+(byte/signed byte/word/signed word/dword/signed dword) 42) ← (byte) 'l' -- _deref_pbuc1=vbuc2
// Chained assignment with a modification of the result
// Chained assignment with a modification of the result
lda #'l'
sta screen+$2a
//SEG17 main::@return

View File

@ -1,4 +1,4 @@
// Test compound assignment operators
// Test compound assignment operators
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -753,7 +753,7 @@ Allocated zp ZP_BYTE:3 [ test::i#11 ]
INITIAL ASM
//SEG0 File Comments
// Test compound assignment operators
// Test compound assignment operators
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -1015,7 +1015,7 @@ Uplifting [test] best 250 combination zp ZP_BYTE:2 [ test::a#11 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Test compound assignment operators
// Test compound assignment operators
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -1342,7 +1342,7 @@ FINAL ASSEMBLER
Score: 199
//SEG0 File Comments
// Test compound assignment operators
// Test compound assignment operators
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -2,7 +2,7 @@
:BasicUpstart(main)
.pc = $80d "Program"
.label BGCOL = $d021
// The colors of the C64
// The colors of the C64
.const BLACK = 0
main: {
lda #BLACK

View File

@ -467,7 +467,7 @@ INITIAL ASM
.pc = $80d "Program"
//SEG2 Global Constants & labels
.label BGCOL = $d021
// The colors of the C64
// The colors of the C64
.const BLACK = 0
//SEG3 @begin
bbegin:
@ -513,7 +513,7 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
//SEG2 Global Constants & labels
.label BGCOL = $d021
// The colors of the C64
// The colors of the C64
.const BLACK = 0
//SEG3 @begin
bbegin:
@ -659,7 +659,7 @@ Score: 12
.pc = $80d "Program"
//SEG2 Global Constants & labels
.label BGCOL = $d021
// The colors of the C64
// The colors of the C64
.const BLACK = 0
//SEG3 @begin
//SEG4 [1] phi from @begin to @5 [phi:@begin->@5]

View File

@ -55,7 +55,7 @@ plot: {
sta plotter_x+1
lda #<0
sta plotter_x
// Needs word arrays arranged as two underlying byte arrays to allow byte* plotter_x = plot_x[x]; - and eventually - byte* plotter = plot_x[x] + plot_y[y];
// Needs word arrays arranged as two underlying byte arrays to allow byte* plotter_x = plot_x[x]; - and eventually - byte* plotter = plot_x[x] + plot_y[y];
lda plot_xlo,y
sta plotter_x
ldy y

View File

@ -1179,7 +1179,7 @@ plot: {
lda #<0
sta plotter_x
//SEG45 [25] (byte~) plot::$1 ← < (byte*) plot::plotter_x#1 -- vbuz1=_lo_pbuz2
// Needs word arrays arranged as two underlying byte arrays to allow byte* plotter_x = plot_x[x]; - and eventually - byte* plotter = plot_x[x] + plot_y[y];
// Needs word arrays arranged as two underlying byte arrays to allow byte* plotter_x = plot_x[x]; - and eventually - byte* plotter = plot_x[x] + plot_y[y];
lda plotter_x
sta _1
//SEG46 [26] (byte~) plot::$7 ← *((const byte[256]) plot_xlo#0 + (byte) plot::x#0) -- vbuz1=pbuc1_derefidx_vbuz2
@ -1728,7 +1728,7 @@ plot: {
lda #<0
sta plotter_x
//SEG45 [25] (byte~) plot::$1 ← < (byte*) plot::plotter_x#1 -- vbuaa=_lo_pbuz1
// Needs word arrays arranged as two underlying byte arrays to allow byte* plotter_x = plot_x[x]; - and eventually - byte* plotter = plot_x[x] + plot_y[y];
// Needs word arrays arranged as two underlying byte arrays to allow byte* plotter_x = plot_x[x]; - and eventually - byte* plotter = plot_x[x] + plot_y[y];
lda plotter_x
//SEG46 [26] (byte~) plot::$7 ← *((const byte[256]) plot_xlo#0 + (byte) plot::x#0) -- vbuaa=pbuc1_derefidx_vbuz1
ldy x
@ -2309,7 +2309,7 @@ plot: {
lda #<0
sta plotter_x
//SEG45 [25] (byte~) plot::$1 ← < (byte*) plot::plotter_x#1 -- vbuaa=_lo_pbuz1
// Needs word arrays arranged as two underlying byte arrays to allow byte* plotter_x = plot_x[x]; - and eventually - byte* plotter = plot_x[x] + plot_y[y];
// Needs word arrays arranged as two underlying byte arrays to allow byte* plotter_x = plot_x[x]; - and eventually - byte* plotter = plot_x[x] + plot_y[y];
//SEG46 [26] (byte~) plot::$7 ← *((const byte[256]) plot_xlo#0 + (byte) plot::x#0) -- vbuaa=pbuc1_derefidx_vbuz1
lda plot_xlo,y
//SEG47 [27] (byte*) plot::plotter_x#2 ← (byte*) plot::plotter_x#1 lo= (byte~) plot::$7 -- pbuz1=pbuz1_setlo_vbuaa

View File

@ -1,4 +1,4 @@
// A Minimal test of boolean constants.
// A Minimal test of boolean constants.
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
@ -9,19 +9,19 @@ main: {
jsr bool_const_inline
rts
}
// A constant boolean inside an if()
// A constant boolean inside an if()
bool_const_inline: {
lda #'t'
sta SCREEN+2
rts
}
// A bunch of constant boolean vars (used in an if)
// A bunch of constant boolean vars (used in an if)
bool_const_vars: {
lda #'f'
sta SCREEN+1
rts
}
// A constant boolean inside an if()
// A constant boolean inside an if()
bool_const_if: {
lda #'t'
sta SCREEN

View File

@ -315,7 +315,7 @@ Complete equivalence classes
INITIAL ASM
//SEG0 File Comments
// A Minimal test of boolean constants.
// A Minimal test of boolean constants.
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -369,7 +369,7 @@ main: {
rts
}
//SEG23 bool_const_inline
// A constant boolean inside an if()
// A constant boolean inside an if()
bool_const_inline: {
jmp b1
//SEG24 bool_const_inline::@1
@ -384,7 +384,7 @@ bool_const_inline: {
rts
}
//SEG28 bool_const_vars
// A bunch of constant boolean vars (used in an if)
// A bunch of constant boolean vars (used in an if)
bool_const_vars: {
jmp b3
//SEG29 bool_const_vars::@3
@ -399,7 +399,7 @@ bool_const_vars: {
rts
}
//SEG33 bool_const_if
// A constant boolean inside an if()
// A constant boolean inside an if()
bool_const_if: {
jmp b1
//SEG34 bool_const_if::@1
@ -434,7 +434,7 @@ Uplifting [] best 180 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// A Minimal test of boolean constants.
// A Minimal test of boolean constants.
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -488,7 +488,7 @@ main: {
rts
}
//SEG23 bool_const_inline
// A constant boolean inside an if()
// A constant boolean inside an if()
bool_const_inline: {
jmp b1
//SEG24 bool_const_inline::@1
@ -503,7 +503,7 @@ bool_const_inline: {
rts
}
//SEG28 bool_const_vars
// A bunch of constant boolean vars (used in an if)
// A bunch of constant boolean vars (used in an if)
bool_const_vars: {
jmp b3
//SEG29 bool_const_vars::@3
@ -518,7 +518,7 @@ bool_const_vars: {
rts
}
//SEG33 bool_const_if
// A constant boolean inside an if()
// A constant boolean inside an if()
bool_const_if: {
jmp b1
//SEG34 bool_const_if::@1
@ -605,7 +605,7 @@ FINAL ASSEMBLER
Score: 60
//SEG0 File Comments
// A Minimal test of boolean constants.
// A Minimal test of boolean constants.
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
@ -639,7 +639,7 @@ main: {
rts
}
//SEG23 bool_const_inline
// A constant boolean inside an if()
// A constant boolean inside an if()
bool_const_inline: {
//SEG24 bool_const_inline::@1
//SEG25 [12] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2) ← (byte) 't' -- _deref_pbuc1=vbuc2
@ -650,7 +650,7 @@ bool_const_inline: {
rts
}
//SEG28 bool_const_vars
// A bunch of constant boolean vars (used in an if)
// A bunch of constant boolean vars (used in an if)
bool_const_vars: {
//SEG29 bool_const_vars::@3
//SEG30 [15] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) 'f' -- _deref_pbuc1=vbuc2
@ -661,7 +661,7 @@ bool_const_vars: {
rts
}
//SEG33 bool_const_if
// A constant boolean inside an if()
// A constant boolean inside an if()
bool_const_if: {
//SEG34 bool_const_if::@1
//SEG35 [18] *((const byte*) SCREEN#0) ← (byte) 't' -- _deref_pbuc1=vbuc2

View File

@ -1,4 +1,4 @@
// Test a function taking boolean parameter and returning boolean result
// Test a function taking boolean parameter and returning boolean result
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
@ -29,8 +29,8 @@ main: {
sta screen,x
jmp b3
}
// Determine whether to set a char to '*.
// Returns true if i&8!=0 or b=true
// Determine whether to set a char to '*.
// Returns true if i&8!=0 or b=true
isSet: {
.label b = 2
txa

View File

@ -256,7 +256,7 @@ Allocated zp ZP_BOOL:10 [ isSet::return#1 ]
INITIAL ASM
//SEG0 File Comments
// Test a function taking boolean parameter and returning boolean result
// Test a function taking boolean parameter and returning boolean result
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -356,8 +356,8 @@ main: {
jmp b3
}
//SEG33 isSet
// Determine whether to set a char to '*.
// Returns true if i&8!=0 or b=true
// Determine whether to set a char to '*.
// Returns true if i&8!=0 or b=true
isSet: {
.label _0 = 8
.label _1 = 9
@ -427,7 +427,7 @@ Allocated (was zp ZP_BOOL:4) zp ZP_BOOL:2 [ isSet::b#0 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Test a function taking boolean parameter and returning boolean result
// Test a function taking boolean parameter and returning boolean result
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -511,8 +511,8 @@ main: {
jmp b3
}
//SEG33 isSet
// Determine whether to set a char to '*.
// Returns true if i&8!=0 or b=true
// Determine whether to set a char to '*.
// Returns true if i&8!=0 or b=true
isSet: {
.label b = 2
//SEG34 [18] (byte~) isSet::$0 ← (byte) isSet::i#0 & (byte/signed byte/word/signed word/dword/signed dword) 8 -- vbuaa=vbuxx_band_vbuc1
@ -609,7 +609,7 @@ FINAL ASSEMBLER
Score: 540
//SEG0 File Comments
// Test a function taking boolean parameter and returning boolean result
// Test a function taking boolean parameter and returning boolean result
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
@ -673,8 +673,8 @@ main: {
jmp b3
}
//SEG33 isSet
// Determine whether to set a char to '*.
// Returns true if i&8!=0 or b=true
// Determine whether to set a char to '*.
// Returns true if i&8!=0 or b=true
isSet: {
.label b = 2
//SEG34 [18] (byte~) isSet::$0 ← (byte) isSet::i#0 & (byte/signed byte/word/signed word/dword/signed dword) 8 -- vbuaa=vbuxx_band_vbuc1

View File

@ -1,4 +1,4 @@
// A test of boolean conditions using && || and !
// A test of boolean conditions using && || and !
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -554,7 +554,7 @@ Allocated zp ZP_BYTE:10 [ bool_and::$1 ]
INITIAL ASM
//SEG0 File Comments
// A test of boolean conditions using && || and !
// A test of boolean conditions using && || and !
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -938,7 +938,7 @@ Uplifting [] best 2548 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// A test of boolean conditions using && || and !
// A test of boolean conditions using && || and !
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -1382,7 +1382,7 @@ FINAL ASSEMBLER
Score: 1804
//SEG0 File Comments
// A test of boolean conditions using && || and !
// A test of boolean conditions using && || and !
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -1,4 +1,4 @@
// Tests a pointer to a boolean
// Tests a pointer to a boolean
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -115,7 +115,7 @@ Complete equivalence classes
INITIAL ASM
//SEG0 File Comments
// Tests a pointer to a boolean
// Tests a pointer to a boolean
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -179,7 +179,7 @@ Uplifting [] best 56 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Tests a pointer to a boolean
// Tests a pointer to a boolean
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -261,7 +261,7 @@ FINAL ASSEMBLER
Score: 37
//SEG0 File Comments
// Tests a pointer to a boolean
// Tests a pointer to a boolean
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -1,4 +1,4 @@
// A test of boolean conditions using && || and !
// A test of boolean conditions using && || and !
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -619,7 +619,7 @@ Allocated zp ZP_BYTE:11 [ bool_and::$1 ]
INITIAL ASM
//SEG0 File Comments
// A test of boolean conditions using && || and !
// A test of boolean conditions using && || and !
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -1029,7 +1029,7 @@ Allocated (was zp ZP_BOOL:8) zp ZP_BOOL:3 [ bool_complex::o2#0 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// A test of boolean conditions using && || and !
// A test of boolean conditions using && || and !
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -1504,7 +1504,7 @@ FINAL ASSEMBLER
Score: 2089
//SEG0 File Comments
// A test of boolean conditions using && || and !
// A test of boolean conditions using && || and !
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -1,18 +1,18 @@
// C64DTV 8bpp charmode stretcher
// C64DTV 8bpp charmode stretcher
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Processor port data direction register
// Processor port data direction register
.label PROCPORT_DDR = 0
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
.const PROCPORT_DDR_MEMORY_MASK = 7
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// RAM in $A000, $E000 I/O in $D000
// RAM in $A000, $E000 I/O in $D000
.const PROCPORT_RAM_IO = $35
// RAM in $A000, $E000 CHAR ROM in $D000
// RAM in $A000, $E000 CHAR ROM in $D000
.const PROCPORT_RAM_CHARROM = $31
// The address of the CHARGEN character set
// The address of the CHARGEN character set
.label CHARGEN = $d000
.label RASTER = $d012
.label BORDERCOL = $d020
@ -24,59 +24,59 @@
.const VIC_MCM = $10
.const VIC_CSEL = 8
.label VIC_MEMORY = $d018
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
.label CIA2_PORT_A = $dd00
// CIA #2 Port A data direction register.
// CIA #2 Port A data direction register.
.label CIA2_PORT_A_DDR = $dd02
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Controls the graphics modes of the C64 DTV
// Controls the graphics modes of the C64 DTV
.label DTV_CONTROL = $d03c
.const DTV_LINEAR = 1
.const DTV_HIGHCOLOR = 4
.const DTV_BADLINE_OFF = $20
.const DTV_CHUNKY = $40
// Defines colors for the 16 first colors ($00-$0f)
// Defines colors for the 16 first colors ($00-$0f)
.label DTV_PALETTE = $d200
// Linear Graphics Plane A Counter Control
// Linear Graphics Plane A Counter Control
.label DTV_PLANEA_START_LO = $d03a
.label DTV_PLANEA_START_MI = $d03b
.label DTV_PLANEA_START_HI = $d045
.label DTV_PLANEA_STEP = $d046
.label DTV_PLANEA_MODULO_LO = $d038
.label DTV_PLANEA_MODULO_HI = $d039
// Linear Graphics Plane B Counter Control
// Linear Graphics Plane B Counter Control
.label DTV_PLANEB_START_LO = $d049
.label DTV_PLANEB_START_MI = $d04a
.label DTV_PLANEB_START_HI = $d04b
.label DTV_PLANEB_STEP = $d04c
.label DTV_PLANEB_MODULO_LO = $d047
.label DTV_PLANEB_MODULO_HI = $d048
// Plane with the screen
// Plane with the screen
.label SCREEN = $7c00
// Plane with all pixels
// Plane with all pixels
.label CHARSET8 = $8000
main: {
sei
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
lda #PROCPORT_RAM_IO
sta PROCPORT
jsr gfx_init
// Enable DTV extended modes
// Enable DTV extended modes
lda #DTV_FEATURE_ENABLE
sta DTV_FEATURE
// 8BPP Pixel Cell Mode
// 8BPP Pixel Cell Mode
lda #DTV_HIGHCOLOR|DTV_LINEAR|DTV_CHUNKY|DTV_BADLINE_OFF
sta DTV_CONTROL
lda #VIC_DEN|VIC_ECM|VIC_RSEL|3
sta VIC_CONTROL
lda #VIC_MCM|VIC_CSEL
sta VIC_CONTROL2
// Plane A: SCREEN
// Plane A: SCREEN
lda #<SCREEN
sta DTV_PLANEA_START_LO
lda #>SCREEN
@ -88,7 +88,7 @@ main: {
lda #0
sta DTV_PLANEA_MODULO_LO
sta DTV_PLANEA_MODULO_HI
// Plane B: CHARSET8
// Plane B: CHARSET8
lda #<CHARSET8
sta DTV_PLANEB_START_LO
lda #>CHARSET8
@ -98,18 +98,18 @@ main: {
sta DTV_PLANEB_STEP
sta DTV_PLANEB_MODULO_LO
sta DTV_PLANEB_MODULO_HI
// VIC Graphics Bank
// VIC Graphics Bank
lda #3
sta CIA2_PORT_A_DDR
// Set VIC Bank bits to output - all others to input
// Set VIC Bank bits to output - all others to input
lda #3^SCREEN/$4000
sta CIA2_PORT_A
// Set VIC Bank
// VIC memory
// Set VIC Bank
// VIC memory
lda #(SCREEN&$3fff)>>6|(>(SCREEN&$3fff))>>2
sta VIC_MEMORY
ldx #0
// DTV Palette - Grey Tones
// DTV Palette - Grey Tones
b1:
txa
sta DTV_PALETTE,x
@ -117,7 +117,7 @@ main: {
cpx #$10
bne b1
b3:
// Stabilize Raster
// Stabilize Raster
ldx #$ff
rff:
cpx RASTER
@ -211,13 +211,13 @@ main: {
bne b8
jmp b3
}
// Initialize the different graphics in the memory
// Initialize the different graphics in the memory
gfx_init: {
jsr gfx_init_screen0
jsr gfx_init_plane_charset8
rts
}
// Initialize Plane with 8bpp charset
// Initialize Plane with 8bpp charset
gfx_init_plane_charset8: {
.const gfxbCpuBank = $ff&CHARSET8/$4000
.label bits = 6
@ -288,11 +288,11 @@ gfx_init_plane_charset8: {
jsr dtvSetCpuBankSegment1
rts
}
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
dtvSetCpuBankSegment1: {
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
.label cpuBank = $ff
sta cpuBank
.byte $32, $dd
@ -300,7 +300,7 @@ dtvSetCpuBankSegment1: {
.byte $32, $00
rts
}
// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos)
// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos)
gfx_init_screen0: {
.label _1 = 5
.label ch = 3

View File

@ -1915,23 +1915,23 @@ Allocated zp ZP_BYTE:26 [ gfx_init_screen0::$3 ]
INITIAL ASM
//SEG0 File Comments
// C64DTV 8bpp charmode stretcher
// C64DTV 8bpp charmode stretcher
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// Processor port data direction register
// Processor port data direction register
.label PROCPORT_DDR = 0
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
.const PROCPORT_DDR_MEMORY_MASK = 7
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// RAM in $A000, $E000 I/O in $D000
// RAM in $A000, $E000 I/O in $D000
.const PROCPORT_RAM_IO = $35
// RAM in $A000, $E000 CHAR ROM in $D000
// RAM in $A000, $E000 CHAR ROM in $D000
.const PROCPORT_RAM_CHARROM = $31
// The address of the CHARGEN character set
// The address of the CHARGEN character set
.label CHARGEN = $d000
.label RASTER = $d012
.label BORDERCOL = $d020
@ -1943,38 +1943,38 @@ INITIAL ASM
.const VIC_MCM = $10
.const VIC_CSEL = 8
.label VIC_MEMORY = $d018
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
.label CIA2_PORT_A = $dd00
// CIA #2 Port A data direction register.
// CIA #2 Port A data direction register.
.label CIA2_PORT_A_DDR = $dd02
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Controls the graphics modes of the C64 DTV
// Controls the graphics modes of the C64 DTV
.label DTV_CONTROL = $d03c
.const DTV_LINEAR = 1
.const DTV_HIGHCOLOR = 4
.const DTV_BADLINE_OFF = $20
.const DTV_CHUNKY = $40
// Defines colors for the 16 first colors ($00-$0f)
// Defines colors for the 16 first colors ($00-$0f)
.label DTV_PALETTE = $d200
// Linear Graphics Plane A Counter Control
// Linear Graphics Plane A Counter Control
.label DTV_PLANEA_START_LO = $d03a
.label DTV_PLANEA_START_MI = $d03b
.label DTV_PLANEA_START_HI = $d045
.label DTV_PLANEA_STEP = $d046
.label DTV_PLANEA_MODULO_LO = $d038
.label DTV_PLANEA_MODULO_HI = $d039
// Linear Graphics Plane B Counter Control
// Linear Graphics Plane B Counter Control
.label DTV_PLANEB_START_LO = $d049
.label DTV_PLANEB_START_MI = $d04a
.label DTV_PLANEB_START_HI = $d04b
.label DTV_PLANEB_STEP = $d04c
.label DTV_PLANEB_MODULO_LO = $d047
.label DTV_PLANEB_MODULO_HI = $d048
// Plane with the screen
// Plane with the screen
.label SCREEN = $7c00
// Plane with all pixels
// Plane with all pixels
.label CHARSET8 = $8000
//SEG3 @begin
bbegin:
@ -2000,8 +2000,8 @@ main: {
//SEG10 asm { sei }
sei
//SEG11 [5] *((const byte*) PROCPORT_DDR#0) ← (const byte) PROCPORT_DDR_MEMORY_MASK#0 -- _deref_pbuc1=vbuc2
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
//SEG12 [6] *((const byte*) PROCPORT#0) ← (const byte) PROCPORT_RAM_IO#0 -- _deref_pbuc1=vbuc2
@ -2015,11 +2015,11 @@ main: {
//SEG15 main::@17
b17:
//SEG16 [8] *((const byte*) DTV_FEATURE#0) ← (const byte) DTV_FEATURE_ENABLE#0 -- _deref_pbuc1=vbuc2
// Enable DTV extended modes
// Enable DTV extended modes
lda #DTV_FEATURE_ENABLE
sta DTV_FEATURE
//SEG17 [9] *((const byte*) DTV_CONTROL#0) ← (const byte) DTV_HIGHCOLOR#0|(const byte) DTV_LINEAR#0|(const byte) DTV_CHUNKY#0|(const byte) DTV_BADLINE_OFF#0 -- _deref_pbuc1=vbuc2
// 8BPP Pixel Cell Mode
// 8BPP Pixel Cell Mode
lda #DTV_HIGHCOLOR|DTV_LINEAR|DTV_CHUNKY|DTV_BADLINE_OFF
sta DTV_CONTROL
//SEG18 [10] *((const byte*) VIC_CONTROL#0) ← (const byte) VIC_DEN#0|(const byte) VIC_ECM#0|(const byte) VIC_RSEL#0|(byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2
@ -2029,7 +2029,7 @@ main: {
lda #VIC_MCM|VIC_CSEL
sta VIC_CONTROL2
//SEG20 [12] *((const byte*) DTV_PLANEA_START_LO#0) ← <(const byte*) SCREEN#0 -- _deref_pbuc1=vbuc2
// Plane A: SCREEN
// Plane A: SCREEN
lda #<SCREEN
sta DTV_PLANEA_START_LO
//SEG21 [13] *((const byte*) DTV_PLANEA_START_MI#0) ← >(const byte*) SCREEN#0 -- _deref_pbuc1=vbuc2
@ -2048,7 +2048,7 @@ main: {
lda #0
sta DTV_PLANEA_MODULO_HI
//SEG26 [18] *((const byte*) DTV_PLANEB_START_LO#0) ← <(const byte*) CHARSET8#0 -- _deref_pbuc1=vbuc2
// Plane B: CHARSET8
// Plane B: CHARSET8
lda #<CHARSET8
sta DTV_PLANEB_START_LO
//SEG27 [19] *((const byte*) DTV_PLANEB_START_MI#0) ← >(const byte*) CHARSET8#0 -- _deref_pbuc1=vbuc2
@ -2067,16 +2067,16 @@ main: {
lda #0
sta DTV_PLANEB_MODULO_HI
//SEG32 [24] *((const byte*) CIA2_PORT_A_DDR#0) ← (byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2
// VIC Graphics Bank
// VIC Graphics Bank
lda #3
sta CIA2_PORT_A_DDR
//SEG33 [25] *((const byte*) CIA2_PORT_A#0) ← (byte/signed byte/word/signed word/dword/signed dword) 3^((byte))((word))(const byte*) SCREEN#0/(word/signed word/dword/signed dword) 16384 -- _deref_pbuc1=vbuc2
// Set VIC Bank bits to output - all others to input
// Set VIC Bank bits to output - all others to input
lda #3^SCREEN/$4000
sta CIA2_PORT_A
//SEG34 [26] *((const byte*) VIC_MEMORY#0) ← ((byte))((word))(const byte*) SCREEN#0&(word/signed word/dword/signed dword) 16383>>(byte/signed byte/word/signed word/dword/signed dword) 6|>((word))(const byte*) SCREEN#0&(word/signed word/dword/signed dword) 16383>>(byte/signed byte/word/signed word/dword/signed dword) 2 -- _deref_pbuc1=vbuc2
// Set VIC Bank
// VIC memory
// Set VIC Bank
// VIC memory
lda #(SCREEN&$3fff)>>6|(>(SCREEN&$3fff))>>2
sta VIC_MEMORY
//SEG35 [27] phi from main::@17 to main::@1 [phi:main::@17->main::@1]
@ -2085,7 +2085,7 @@ main: {
lda #0
sta j
jmp b1
// DTV Palette - Grey Tones
// DTV Palette - Grey Tones
//SEG37 [27] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
b1_from_b1:
//SEG38 [27] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@1->main::@1#0] -- register_copy
@ -2106,7 +2106,7 @@ main: {
//SEG43 main::@3
b3:
//SEG44 asm { ldx#$ff rff: cpxRASTER bnerff stabilize: nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop cpxRASTER beqeat+0 eat: inx cpx#$08 bnestabilize }
// Stabilize Raster
// Stabilize Raster
ldx #$ff
rff:
cpx RASTER
@ -2228,7 +2228,7 @@ main: {
jmp b3
}
//SEG60 gfx_init
// Initialize the different graphics in the memory
// Initialize the different graphics in the memory
gfx_init: {
//SEG61 [45] call gfx_init_screen0
//SEG62 [78] phi from gfx_init to gfx_init_screen0 [phi:gfx_init->gfx_init_screen0]
@ -2250,7 +2250,7 @@ gfx_init: {
rts
}
//SEG69 gfx_init_plane_charset8
// Initialize Plane with 8bpp charset
// Initialize Plane with 8bpp charset
gfx_init_plane_charset8: {
.const gfxbCpuBank = $ff&CHARSET8/$4000
.label _7 = $16
@ -2431,11 +2431,11 @@ gfx_init_plane_charset8: {
rts
}
//SEG138 dtvSetCpuBankSegment1
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
dtvSetCpuBankSegment1: {
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
.label cpuBank = $ff
.label cpuBankIdx = $d
//SEG139 [75] *((const byte*) dtvSetCpuBankSegment1::cpuBank#0) ← (byte) dtvSetCpuBankSegment1::cpuBankIdx#2 -- _deref_pbuc1=vbuz1
@ -2452,7 +2452,7 @@ dtvSetCpuBankSegment1: {
rts
}
//SEG143 gfx_init_screen0
// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos)
// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos)
gfx_init_screen0: {
.label _0 = $17
.label _1 = $18
@ -2702,23 +2702,23 @@ Allocated (was zp ZP_BYTE:10) zp ZP_BYTE:9 [ gfx_init_plane_charset8::col#2 gfx_
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// C64DTV 8bpp charmode stretcher
// C64DTV 8bpp charmode stretcher
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// Processor port data direction register
// Processor port data direction register
.label PROCPORT_DDR = 0
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
.const PROCPORT_DDR_MEMORY_MASK = 7
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// RAM in $A000, $E000 I/O in $D000
// RAM in $A000, $E000 I/O in $D000
.const PROCPORT_RAM_IO = $35
// RAM in $A000, $E000 CHAR ROM in $D000
// RAM in $A000, $E000 CHAR ROM in $D000
.const PROCPORT_RAM_CHARROM = $31
// The address of the CHARGEN character set
// The address of the CHARGEN character set
.label CHARGEN = $d000
.label RASTER = $d012
.label BORDERCOL = $d020
@ -2730,38 +2730,38 @@ ASSEMBLER BEFORE OPTIMIZATION
.const VIC_MCM = $10
.const VIC_CSEL = 8
.label VIC_MEMORY = $d018
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
.label CIA2_PORT_A = $dd00
// CIA #2 Port A data direction register.
// CIA #2 Port A data direction register.
.label CIA2_PORT_A_DDR = $dd02
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Controls the graphics modes of the C64 DTV
// Controls the graphics modes of the C64 DTV
.label DTV_CONTROL = $d03c
.const DTV_LINEAR = 1
.const DTV_HIGHCOLOR = 4
.const DTV_BADLINE_OFF = $20
.const DTV_CHUNKY = $40
// Defines colors for the 16 first colors ($00-$0f)
// Defines colors for the 16 first colors ($00-$0f)
.label DTV_PALETTE = $d200
// Linear Graphics Plane A Counter Control
// Linear Graphics Plane A Counter Control
.label DTV_PLANEA_START_LO = $d03a
.label DTV_PLANEA_START_MI = $d03b
.label DTV_PLANEA_START_HI = $d045
.label DTV_PLANEA_STEP = $d046
.label DTV_PLANEA_MODULO_LO = $d038
.label DTV_PLANEA_MODULO_HI = $d039
// Linear Graphics Plane B Counter Control
// Linear Graphics Plane B Counter Control
.label DTV_PLANEB_START_LO = $d049
.label DTV_PLANEB_START_MI = $d04a
.label DTV_PLANEB_START_HI = $d04b
.label DTV_PLANEB_STEP = $d04c
.label DTV_PLANEB_MODULO_LO = $d047
.label DTV_PLANEB_MODULO_HI = $d048
// Plane with the screen
// Plane with the screen
.label SCREEN = $7c00
// Plane with all pixels
// Plane with all pixels
.label CHARSET8 = $8000
//SEG3 @begin
bbegin:
@ -2782,8 +2782,8 @@ main: {
//SEG10 asm { sei }
sei
//SEG11 [5] *((const byte*) PROCPORT_DDR#0) ← (const byte) PROCPORT_DDR_MEMORY_MASK#0 -- _deref_pbuc1=vbuc2
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
//SEG12 [6] *((const byte*) PROCPORT#0) ← (const byte) PROCPORT_RAM_IO#0 -- _deref_pbuc1=vbuc2
@ -2797,11 +2797,11 @@ main: {
//SEG15 main::@17
b17:
//SEG16 [8] *((const byte*) DTV_FEATURE#0) ← (const byte) DTV_FEATURE_ENABLE#0 -- _deref_pbuc1=vbuc2
// Enable DTV extended modes
// Enable DTV extended modes
lda #DTV_FEATURE_ENABLE
sta DTV_FEATURE
//SEG17 [9] *((const byte*) DTV_CONTROL#0) ← (const byte) DTV_HIGHCOLOR#0|(const byte) DTV_LINEAR#0|(const byte) DTV_CHUNKY#0|(const byte) DTV_BADLINE_OFF#0 -- _deref_pbuc1=vbuc2
// 8BPP Pixel Cell Mode
// 8BPP Pixel Cell Mode
lda #DTV_HIGHCOLOR|DTV_LINEAR|DTV_CHUNKY|DTV_BADLINE_OFF
sta DTV_CONTROL
//SEG18 [10] *((const byte*) VIC_CONTROL#0) ← (const byte) VIC_DEN#0|(const byte) VIC_ECM#0|(const byte) VIC_RSEL#0|(byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2
@ -2811,7 +2811,7 @@ main: {
lda #VIC_MCM|VIC_CSEL
sta VIC_CONTROL2
//SEG20 [12] *((const byte*) DTV_PLANEA_START_LO#0) ← <(const byte*) SCREEN#0 -- _deref_pbuc1=vbuc2
// Plane A: SCREEN
// Plane A: SCREEN
lda #<SCREEN
sta DTV_PLANEA_START_LO
//SEG21 [13] *((const byte*) DTV_PLANEA_START_MI#0) ← >(const byte*) SCREEN#0 -- _deref_pbuc1=vbuc2
@ -2830,7 +2830,7 @@ main: {
lda #0
sta DTV_PLANEA_MODULO_HI
//SEG26 [18] *((const byte*) DTV_PLANEB_START_LO#0) ← <(const byte*) CHARSET8#0 -- _deref_pbuc1=vbuc2
// Plane B: CHARSET8
// Plane B: CHARSET8
lda #<CHARSET8
sta DTV_PLANEB_START_LO
//SEG27 [19] *((const byte*) DTV_PLANEB_START_MI#0) ← >(const byte*) CHARSET8#0 -- _deref_pbuc1=vbuc2
@ -2849,16 +2849,16 @@ main: {
lda #0
sta DTV_PLANEB_MODULO_HI
//SEG32 [24] *((const byte*) CIA2_PORT_A_DDR#0) ← (byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2
// VIC Graphics Bank
// VIC Graphics Bank
lda #3
sta CIA2_PORT_A_DDR
//SEG33 [25] *((const byte*) CIA2_PORT_A#0) ← (byte/signed byte/word/signed word/dword/signed dword) 3^((byte))((word))(const byte*) SCREEN#0/(word/signed word/dword/signed dword) 16384 -- _deref_pbuc1=vbuc2
// Set VIC Bank bits to output - all others to input
// Set VIC Bank bits to output - all others to input
lda #3^SCREEN/$4000
sta CIA2_PORT_A
//SEG34 [26] *((const byte*) VIC_MEMORY#0) ← ((byte))((word))(const byte*) SCREEN#0&(word/signed word/dword/signed dword) 16383>>(byte/signed byte/word/signed word/dword/signed dword) 6|>((word))(const byte*) SCREEN#0&(word/signed word/dword/signed dword) 16383>>(byte/signed byte/word/signed word/dword/signed dword) 2 -- _deref_pbuc1=vbuc2
// Set VIC Bank
// VIC memory
// Set VIC Bank
// VIC memory
lda #(SCREEN&$3fff)>>6|(>(SCREEN&$3fff))>>2
sta VIC_MEMORY
//SEG35 [27] phi from main::@17 to main::@1 [phi:main::@17->main::@1]
@ -2866,7 +2866,7 @@ main: {
//SEG36 [27] phi (byte) main::j#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@17->main::@1#0] -- vbuxx=vbuc1
ldx #0
jmp b1
// DTV Palette - Grey Tones
// DTV Palette - Grey Tones
//SEG37 [27] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
b1_from_b1:
//SEG38 [27] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@1->main::@1#0] -- register_copy
@ -2885,7 +2885,7 @@ main: {
//SEG43 main::@3
b3:
//SEG44 asm { ldx#$ff rff: cpxRASTER bnerff stabilize: nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop cpxRASTER beqeat+0 eat: inx cpx#$08 bnestabilize }
// Stabilize Raster
// Stabilize Raster
ldx #$ff
rff:
cpx RASTER
@ -2999,7 +2999,7 @@ main: {
jmp b3
}
//SEG60 gfx_init
// Initialize the different graphics in the memory
// Initialize the different graphics in the memory
gfx_init: {
//SEG61 [45] call gfx_init_screen0
//SEG62 [78] phi from gfx_init to gfx_init_screen0 [phi:gfx_init->gfx_init_screen0]
@ -3021,7 +3021,7 @@ gfx_init: {
rts
}
//SEG69 gfx_init_plane_charset8
// Initialize Plane with 8bpp charset
// Initialize Plane with 8bpp charset
gfx_init_plane_charset8: {
.const gfxbCpuBank = $ff&CHARSET8/$4000
.label bits = 6
@ -3190,11 +3190,11 @@ gfx_init_plane_charset8: {
rts
}
//SEG138 dtvSetCpuBankSegment1
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
dtvSetCpuBankSegment1: {
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
.label cpuBank = $ff
//SEG139 [75] *((const byte*) dtvSetCpuBankSegment1::cpuBank#0) ← (byte) dtvSetCpuBankSegment1::cpuBankIdx#2 -- _deref_pbuc1=vbuaa
sta cpuBank
@ -3209,7 +3209,7 @@ dtvSetCpuBankSegment1: {
rts
}
//SEG143 gfx_init_screen0
// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos)
// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos)
gfx_init_screen0: {
.label _1 = 5
.label ch = 3
@ -3713,23 +3713,23 @@ FINAL ASSEMBLER
Score: 75377
//SEG0 File Comments
// C64DTV 8bpp charmode stretcher
// C64DTV 8bpp charmode stretcher
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// Processor port data direction register
// Processor port data direction register
.label PROCPORT_DDR = 0
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
.const PROCPORT_DDR_MEMORY_MASK = 7
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// RAM in $A000, $E000 I/O in $D000
// RAM in $A000, $E000 I/O in $D000
.const PROCPORT_RAM_IO = $35
// RAM in $A000, $E000 CHAR ROM in $D000
// RAM in $A000, $E000 CHAR ROM in $D000
.const PROCPORT_RAM_CHARROM = $31
// The address of the CHARGEN character set
// The address of the CHARGEN character set
.label CHARGEN = $d000
.label RASTER = $d012
.label BORDERCOL = $d020
@ -3741,38 +3741,38 @@ Score: 75377
.const VIC_MCM = $10
.const VIC_CSEL = 8
.label VIC_MEMORY = $d018
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
.label CIA2_PORT_A = $dd00
// CIA #2 Port A data direction register.
// CIA #2 Port A data direction register.
.label CIA2_PORT_A_DDR = $dd02
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Controls the graphics modes of the C64 DTV
// Controls the graphics modes of the C64 DTV
.label DTV_CONTROL = $d03c
.const DTV_LINEAR = 1
.const DTV_HIGHCOLOR = 4
.const DTV_BADLINE_OFF = $20
.const DTV_CHUNKY = $40
// Defines colors for the 16 first colors ($00-$0f)
// Defines colors for the 16 first colors ($00-$0f)
.label DTV_PALETTE = $d200
// Linear Graphics Plane A Counter Control
// Linear Graphics Plane A Counter Control
.label DTV_PLANEA_START_LO = $d03a
.label DTV_PLANEA_START_MI = $d03b
.label DTV_PLANEA_START_HI = $d045
.label DTV_PLANEA_STEP = $d046
.label DTV_PLANEA_MODULO_LO = $d038
.label DTV_PLANEA_MODULO_HI = $d039
// Linear Graphics Plane B Counter Control
// Linear Graphics Plane B Counter Control
.label DTV_PLANEB_START_LO = $d049
.label DTV_PLANEB_START_MI = $d04a
.label DTV_PLANEB_START_HI = $d04b
.label DTV_PLANEB_STEP = $d04c
.label DTV_PLANEB_MODULO_LO = $d047
.label DTV_PLANEB_MODULO_HI = $d048
// Plane with the screen
// Plane with the screen
.label SCREEN = $7c00
// Plane with all pixels
// Plane with all pixels
.label CHARSET8 = $8000
//SEG3 @begin
//SEG4 [1] phi from @begin to @9 [phi:@begin->@9]
@ -3785,8 +3785,8 @@ main: {
//SEG10 asm { sei }
sei
//SEG11 [5] *((const byte*) PROCPORT_DDR#0) ← (const byte) PROCPORT_DDR_MEMORY_MASK#0 -- _deref_pbuc1=vbuc2
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
//SEG12 [6] *((const byte*) PROCPORT#0) ← (const byte) PROCPORT_RAM_IO#0 -- _deref_pbuc1=vbuc2
@ -3797,11 +3797,11 @@ main: {
jsr gfx_init
//SEG15 main::@17
//SEG16 [8] *((const byte*) DTV_FEATURE#0) ← (const byte) DTV_FEATURE_ENABLE#0 -- _deref_pbuc1=vbuc2
// Enable DTV extended modes
// Enable DTV extended modes
lda #DTV_FEATURE_ENABLE
sta DTV_FEATURE
//SEG17 [9] *((const byte*) DTV_CONTROL#0) ← (const byte) DTV_HIGHCOLOR#0|(const byte) DTV_LINEAR#0|(const byte) DTV_CHUNKY#0|(const byte) DTV_BADLINE_OFF#0 -- _deref_pbuc1=vbuc2
// 8BPP Pixel Cell Mode
// 8BPP Pixel Cell Mode
lda #DTV_HIGHCOLOR|DTV_LINEAR|DTV_CHUNKY|DTV_BADLINE_OFF
sta DTV_CONTROL
//SEG18 [10] *((const byte*) VIC_CONTROL#0) ← (const byte) VIC_DEN#0|(const byte) VIC_ECM#0|(const byte) VIC_RSEL#0|(byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2
@ -3811,7 +3811,7 @@ main: {
lda #VIC_MCM|VIC_CSEL
sta VIC_CONTROL2
//SEG20 [12] *((const byte*) DTV_PLANEA_START_LO#0) ← <(const byte*) SCREEN#0 -- _deref_pbuc1=vbuc2
// Plane A: SCREEN
// Plane A: SCREEN
lda #<SCREEN
sta DTV_PLANEA_START_LO
//SEG21 [13] *((const byte*) DTV_PLANEA_START_MI#0) ← >(const byte*) SCREEN#0 -- _deref_pbuc1=vbuc2
@ -3829,7 +3829,7 @@ main: {
//SEG25 [17] *((const byte*) DTV_PLANEA_MODULO_HI#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2
sta DTV_PLANEA_MODULO_HI
//SEG26 [18] *((const byte*) DTV_PLANEB_START_LO#0) ← <(const byte*) CHARSET8#0 -- _deref_pbuc1=vbuc2
// Plane B: CHARSET8
// Plane B: CHARSET8
lda #<CHARSET8
sta DTV_PLANEB_START_LO
//SEG27 [19] *((const byte*) DTV_PLANEB_START_MI#0) ← >(const byte*) CHARSET8#0 -- _deref_pbuc1=vbuc2
@ -3845,22 +3845,22 @@ main: {
//SEG31 [23] *((const byte*) DTV_PLANEB_MODULO_HI#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2
sta DTV_PLANEB_MODULO_HI
//SEG32 [24] *((const byte*) CIA2_PORT_A_DDR#0) ← (byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2
// VIC Graphics Bank
// VIC Graphics Bank
lda #3
sta CIA2_PORT_A_DDR
//SEG33 [25] *((const byte*) CIA2_PORT_A#0) ← (byte/signed byte/word/signed word/dword/signed dword) 3^((byte))((word))(const byte*) SCREEN#0/(word/signed word/dword/signed dword) 16384 -- _deref_pbuc1=vbuc2
// Set VIC Bank bits to output - all others to input
// Set VIC Bank bits to output - all others to input
lda #3^SCREEN/$4000
sta CIA2_PORT_A
//SEG34 [26] *((const byte*) VIC_MEMORY#0) ← ((byte))((word))(const byte*) SCREEN#0&(word/signed word/dword/signed dword) 16383>>(byte/signed byte/word/signed word/dword/signed dword) 6|>((word))(const byte*) SCREEN#0&(word/signed word/dword/signed dword) 16383>>(byte/signed byte/word/signed word/dword/signed dword) 2 -- _deref_pbuc1=vbuc2
// Set VIC Bank
// VIC memory
// Set VIC Bank
// VIC memory
lda #(SCREEN&$3fff)>>6|(>(SCREEN&$3fff))>>2
sta VIC_MEMORY
//SEG35 [27] phi from main::@17 to main::@1 [phi:main::@17->main::@1]
//SEG36 [27] phi (byte) main::j#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@17->main::@1#0] -- vbuxx=vbuc1
ldx #0
// DTV Palette - Grey Tones
// DTV Palette - Grey Tones
//SEG37 [27] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
//SEG38 [27] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@1->main::@1#0] -- register_copy
//SEG39 main::@1
@ -3876,7 +3876,7 @@ main: {
//SEG43 main::@3
b3:
//SEG44 asm { ldx#$ff rff: cpxRASTER bnerff stabilize: nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop cpxRASTER beqeat+0 eat: inx cpx#$08 bnestabilize }
// Stabilize Raster
// Stabilize Raster
ldx #$ff
rff:
cpx RASTER
@ -3986,7 +3986,7 @@ main: {
jmp b3
}
//SEG60 gfx_init
// Initialize the different graphics in the memory
// Initialize the different graphics in the memory
gfx_init: {
//SEG61 [45] call gfx_init_screen0
//SEG62 [78] phi from gfx_init to gfx_init_screen0 [phi:gfx_init->gfx_init_screen0]
@ -4001,7 +4001,7 @@ gfx_init: {
rts
}
//SEG69 gfx_init_plane_charset8
// Initialize Plane with 8bpp charset
// Initialize Plane with 8bpp charset
gfx_init_plane_charset8: {
.const gfxbCpuBank = $ff&CHARSET8/$4000
.label bits = 6
@ -4141,11 +4141,11 @@ gfx_init_plane_charset8: {
rts
}
//SEG138 dtvSetCpuBankSegment1
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
dtvSetCpuBankSegment1: {
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
.label cpuBank = $ff
//SEG139 [75] *((const byte*) dtvSetCpuBankSegment1::cpuBank#0) ← (byte) dtvSetCpuBankSegment1::cpuBankIdx#2 -- _deref_pbuc1=vbuaa
sta cpuBank
@ -4158,7 +4158,7 @@ dtvSetCpuBankSegment1: {
rts
}
//SEG143 gfx_init_screen0
// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos)
// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos)
gfx_init_screen0: {
.label _1 = 5
.label ch = 3

View File

@ -1,14 +1,14 @@
// C64DTV 8bpp charmode stretcher
// C64DTV 8bpp charmode stretcher
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Processor port data direction register
// Processor port data direction register
.label PROCPORT_DDR = 0
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
.const PROCPORT_DDR_MEMORY_MASK = 7
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// RAM in $A000, $E000 I/O in $D000
// RAM in $A000, $E000 I/O in $D000
.const PROCPORT_RAM_IO = $35
.label RASTER = $d012
.label BORDERCOL = $d020
@ -20,51 +20,51 @@
.const VIC_MCM = $10
.const VIC_CSEL = 8
.label VIC_MEMORY = $d018
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
.label CIA2_PORT_A = $dd00
// CIA #2 Port A data direction register.
// CIA #2 Port A data direction register.
.label CIA2_PORT_A_DDR = $dd02
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Controls the graphics modes of the C64 DTV
// Controls the graphics modes of the C64 DTV
.label DTV_CONTROL = $d03c
.const DTV_LINEAR = 1
.const DTV_HIGHCOLOR = 4
.const DTV_COLORRAM_OFF = $10
.const DTV_BADLINE_OFF = $20
.const DTV_CHUNKY = $40
// Defines colors for the 16 first colors ($00-$0f)
// Defines colors for the 16 first colors ($00-$0f)
.label DTV_PALETTE = $d200
// Linear Graphics Plane B Counter Control
// Linear Graphics Plane B Counter Control
.label DTV_PLANEB_START_LO = $d049
.label DTV_PLANEB_START_MI = $d04a
.label DTV_PLANEB_START_HI = $d04b
.label DTV_PLANEB_STEP = $d04c
.label DTV_PLANEB_MODULO_LO = $d047
.label DTV_PLANEB_MODULO_HI = $d048
// Plane with all pixels
// Plane with all pixels
.label CHUNKY = $8000
main: {
sei
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
lda #PROCPORT_RAM_IO
sta PROCPORT
jsr gfx_init_chunky
// Enable DTV extended modes
// Enable DTV extended modes
lda #DTV_FEATURE_ENABLE
sta DTV_FEATURE
// 8BPP Pixel Cell Mode
// 8BPP Pixel Cell Mode
lda #DTV_HIGHCOLOR|DTV_LINEAR|DTV_COLORRAM_OFF|DTV_CHUNKY|DTV_BADLINE_OFF
sta DTV_CONTROL
lda #VIC_DEN|VIC_ECM|VIC_RSEL|3
sta VIC_CONTROL
lda #VIC_MCM|VIC_CSEL
sta VIC_CONTROL2
// Plane B: CHUNKY
// Plane B: CHUNKY
lda #<CHUNKY
sta DTV_PLANEB_START_LO
lda #>CHUNKY
@ -76,18 +76,18 @@ main: {
lda #0
sta DTV_PLANEB_MODULO_LO
sta DTV_PLANEB_MODULO_HI
// VIC Graphics Bank
// VIC Graphics Bank
lda #3
sta CIA2_PORT_A_DDR
// Set VIC Bank bits to output - all others to input
// Set VIC Bank bits to output - all others to input
lda #3^CHUNKY/$4000
sta CIA2_PORT_A
// Set VIC Bank
// VIC memory
// Set VIC Bank
// VIC memory
lda #(CHUNKY&$3fff)>>6|(0)>>2
sta VIC_MEMORY
ldx #0
// DTV Palette - Grey Tones
// DTV Palette - Grey Tones
b1:
txa
sta DTV_PALETTE,x
@ -95,7 +95,7 @@ main: {
cpx #$10
bne b1
b3:
// Stabilize Raster
// Stabilize Raster
ldx #$ff
rff:
cpx RASTER
@ -189,7 +189,7 @@ main: {
bne b8
jmp b3
}
// Initialize Plane with 8bpp chunky
// Initialize Plane with 8bpp chunky
gfx_init_chunky: {
.label _6 = 7
.label gfxb = 5
@ -255,11 +255,11 @@ gfx_init_chunky: {
jsr dtvSetCpuBankSegment1
rts
}
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
dtvSetCpuBankSegment1: {
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
.label cpuBank = $ff
sta cpuBank
.byte $32, $dd

View File

@ -1566,19 +1566,19 @@ Allocated zp ZP_BYTE:16 [ gfx_init_chunky::c#0 ]
INITIAL ASM
//SEG0 File Comments
// C64DTV 8bpp charmode stretcher
// C64DTV 8bpp charmode stretcher
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// Processor port data direction register
// Processor port data direction register
.label PROCPORT_DDR = 0
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
.const PROCPORT_DDR_MEMORY_MASK = 7
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// RAM in $A000, $E000 I/O in $D000
// RAM in $A000, $E000 I/O in $D000
.const PROCPORT_RAM_IO = $35
.label RASTER = $d012
.label BORDERCOL = $d020
@ -1590,30 +1590,30 @@ INITIAL ASM
.const VIC_MCM = $10
.const VIC_CSEL = 8
.label VIC_MEMORY = $d018
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
.label CIA2_PORT_A = $dd00
// CIA #2 Port A data direction register.
// CIA #2 Port A data direction register.
.label CIA2_PORT_A_DDR = $dd02
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Controls the graphics modes of the C64 DTV
// Controls the graphics modes of the C64 DTV
.label DTV_CONTROL = $d03c
.const DTV_LINEAR = 1
.const DTV_HIGHCOLOR = 4
.const DTV_COLORRAM_OFF = $10
.const DTV_BADLINE_OFF = $20
.const DTV_CHUNKY = $40
// Defines colors for the 16 first colors ($00-$0f)
// Defines colors for the 16 first colors ($00-$0f)
.label DTV_PALETTE = $d200
// Linear Graphics Plane B Counter Control
// Linear Graphics Plane B Counter Control
.label DTV_PLANEB_START_LO = $d049
.label DTV_PLANEB_START_MI = $d04a
.label DTV_PLANEB_START_HI = $d04b
.label DTV_PLANEB_STEP = $d04c
.label DTV_PLANEB_MODULO_LO = $d047
.label DTV_PLANEB_MODULO_HI = $d048
// Plane with all pixels
// Plane with all pixels
.label CHUNKY = $8000
//SEG3 @begin
bbegin:
@ -1639,8 +1639,8 @@ main: {
//SEG10 asm { sei }
sei
//SEG11 [5] *((const byte*) PROCPORT_DDR#0) ← (const byte) PROCPORT_DDR_MEMORY_MASK#0 -- _deref_pbuc1=vbuc2
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
//SEG12 [6] *((const byte*) PROCPORT#0) ← (const byte) PROCPORT_RAM_IO#0 -- _deref_pbuc1=vbuc2
@ -1654,11 +1654,11 @@ main: {
//SEG15 main::@17
b17:
//SEG16 [8] *((const byte*) DTV_FEATURE#0) ← (const byte) DTV_FEATURE_ENABLE#0 -- _deref_pbuc1=vbuc2
// Enable DTV extended modes
// Enable DTV extended modes
lda #DTV_FEATURE_ENABLE
sta DTV_FEATURE
//SEG17 [9] *((const byte*) DTV_CONTROL#0) ← (const byte) DTV_HIGHCOLOR#0|(const byte) DTV_LINEAR#0|(const byte) DTV_COLORRAM_OFF#0|(const byte) DTV_CHUNKY#0|(const byte) DTV_BADLINE_OFF#0 -- _deref_pbuc1=vbuc2
// 8BPP Pixel Cell Mode
// 8BPP Pixel Cell Mode
lda #DTV_HIGHCOLOR|DTV_LINEAR|DTV_COLORRAM_OFF|DTV_CHUNKY|DTV_BADLINE_OFF
sta DTV_CONTROL
//SEG18 [10] *((const byte*) VIC_CONTROL#0) ← (const byte) VIC_DEN#0|(const byte) VIC_ECM#0|(const byte) VIC_RSEL#0|(byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2
@ -1668,7 +1668,7 @@ main: {
lda #VIC_MCM|VIC_CSEL
sta VIC_CONTROL2
//SEG20 [12] *((const byte*) DTV_PLANEB_START_LO#0) ← <(const byte*) CHUNKY#0 -- _deref_pbuc1=vbuc2
// Plane B: CHUNKY
// Plane B: CHUNKY
lda #<CHUNKY
sta DTV_PLANEB_START_LO
//SEG21 [13] *((const byte*) DTV_PLANEB_START_MI#0) ← >(const byte*) CHUNKY#0 -- _deref_pbuc1=vbuc2
@ -1687,16 +1687,16 @@ main: {
lda #0
sta DTV_PLANEB_MODULO_HI
//SEG26 [18] *((const byte*) CIA2_PORT_A_DDR#0) ← (byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2
// VIC Graphics Bank
// VIC Graphics Bank
lda #3
sta CIA2_PORT_A_DDR
//SEG27 [19] *((const byte*) CIA2_PORT_A#0) ← (byte/signed byte/word/signed word/dword/signed dword) 3^((byte))((word))(const byte*) CHUNKY#0/(word/signed word/dword/signed dword) 16384 -- _deref_pbuc1=vbuc2
// Set VIC Bank bits to output - all others to input
// Set VIC Bank bits to output - all others to input
lda #3^CHUNKY/$4000
sta CIA2_PORT_A
//SEG28 [20] *((const byte*) VIC_MEMORY#0) ← ((byte))((word))(const byte*) CHUNKY#0&(word/signed word/dword/signed dword) 16383>>(byte/signed byte/word/signed word/dword/signed dword) 6|>((word))(const byte*) CHUNKY#0&(word/signed word/dword/signed dword) 16383>>(byte/signed byte/word/signed word/dword/signed dword) 2 -- _deref_pbuc1=vbuc2
// Set VIC Bank
// VIC memory
// Set VIC Bank
// VIC memory
lda #(CHUNKY&$3fff)>>6|(0)>>2
sta VIC_MEMORY
//SEG29 [21] phi from main::@17 to main::@1 [phi:main::@17->main::@1]
@ -1705,7 +1705,7 @@ main: {
lda #0
sta j
jmp b1
// DTV Palette - Grey Tones
// DTV Palette - Grey Tones
//SEG31 [21] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
b1_from_b1:
//SEG32 [21] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@1->main::@1#0] -- register_copy
@ -1726,7 +1726,7 @@ main: {
//SEG37 main::@3
b3:
//SEG38 asm { ldx#$ff rff: cpxRASTER bnerff stabilize: nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop cpxRASTER beqeat+0 eat: inx cpx#$08 bnestabilize }
// Stabilize Raster
// Stabilize Raster
ldx #$ff
rff:
cpx RASTER
@ -1848,7 +1848,7 @@ main: {
jmp b3
}
//SEG54 gfx_init_chunky
// Initialize Plane with 8bpp chunky
// Initialize Plane with 8bpp chunky
gfx_init_chunky: {
.label _6 = $e
.label c = $10
@ -2002,11 +2002,11 @@ gfx_init_chunky: {
rts
}
//SEG107 dtvSetCpuBankSegment1
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
dtvSetCpuBankSegment1: {
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
.label cpuBank = $ff
.label cpuBankIdx = 9
//SEG108 [59] *((const byte*) dtvSetCpuBankSegment1::cpuBank#0) ← (byte) dtvSetCpuBankSegment1::cpuBankIdx#3 -- _deref_pbuc1=vbuz1
@ -2120,19 +2120,19 @@ Allocated (was zp ZP_WORD:14) zp ZP_WORD:7 [ gfx_init_chunky::$6 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// C64DTV 8bpp charmode stretcher
// C64DTV 8bpp charmode stretcher
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// Processor port data direction register
// Processor port data direction register
.label PROCPORT_DDR = 0
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
.const PROCPORT_DDR_MEMORY_MASK = 7
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// RAM in $A000, $E000 I/O in $D000
// RAM in $A000, $E000 I/O in $D000
.const PROCPORT_RAM_IO = $35
.label RASTER = $d012
.label BORDERCOL = $d020
@ -2144,30 +2144,30 @@ ASSEMBLER BEFORE OPTIMIZATION
.const VIC_MCM = $10
.const VIC_CSEL = 8
.label VIC_MEMORY = $d018
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
.label CIA2_PORT_A = $dd00
// CIA #2 Port A data direction register.
// CIA #2 Port A data direction register.
.label CIA2_PORT_A_DDR = $dd02
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Controls the graphics modes of the C64 DTV
// Controls the graphics modes of the C64 DTV
.label DTV_CONTROL = $d03c
.const DTV_LINEAR = 1
.const DTV_HIGHCOLOR = 4
.const DTV_COLORRAM_OFF = $10
.const DTV_BADLINE_OFF = $20
.const DTV_CHUNKY = $40
// Defines colors for the 16 first colors ($00-$0f)
// Defines colors for the 16 first colors ($00-$0f)
.label DTV_PALETTE = $d200
// Linear Graphics Plane B Counter Control
// Linear Graphics Plane B Counter Control
.label DTV_PLANEB_START_LO = $d049
.label DTV_PLANEB_START_MI = $d04a
.label DTV_PLANEB_START_HI = $d04b
.label DTV_PLANEB_STEP = $d04c
.label DTV_PLANEB_MODULO_LO = $d047
.label DTV_PLANEB_MODULO_HI = $d048
// Plane with all pixels
// Plane with all pixels
.label CHUNKY = $8000
//SEG3 @begin
bbegin:
@ -2188,8 +2188,8 @@ main: {
//SEG10 asm { sei }
sei
//SEG11 [5] *((const byte*) PROCPORT_DDR#0) ← (const byte) PROCPORT_DDR_MEMORY_MASK#0 -- _deref_pbuc1=vbuc2
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
//SEG12 [6] *((const byte*) PROCPORT#0) ← (const byte) PROCPORT_RAM_IO#0 -- _deref_pbuc1=vbuc2
@ -2203,11 +2203,11 @@ main: {
//SEG15 main::@17
b17:
//SEG16 [8] *((const byte*) DTV_FEATURE#0) ← (const byte) DTV_FEATURE_ENABLE#0 -- _deref_pbuc1=vbuc2
// Enable DTV extended modes
// Enable DTV extended modes
lda #DTV_FEATURE_ENABLE
sta DTV_FEATURE
//SEG17 [9] *((const byte*) DTV_CONTROL#0) ← (const byte) DTV_HIGHCOLOR#0|(const byte) DTV_LINEAR#0|(const byte) DTV_COLORRAM_OFF#0|(const byte) DTV_CHUNKY#0|(const byte) DTV_BADLINE_OFF#0 -- _deref_pbuc1=vbuc2
// 8BPP Pixel Cell Mode
// 8BPP Pixel Cell Mode
lda #DTV_HIGHCOLOR|DTV_LINEAR|DTV_COLORRAM_OFF|DTV_CHUNKY|DTV_BADLINE_OFF
sta DTV_CONTROL
//SEG18 [10] *((const byte*) VIC_CONTROL#0) ← (const byte) VIC_DEN#0|(const byte) VIC_ECM#0|(const byte) VIC_RSEL#0|(byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2
@ -2217,7 +2217,7 @@ main: {
lda #VIC_MCM|VIC_CSEL
sta VIC_CONTROL2
//SEG20 [12] *((const byte*) DTV_PLANEB_START_LO#0) ← <(const byte*) CHUNKY#0 -- _deref_pbuc1=vbuc2
// Plane B: CHUNKY
// Plane B: CHUNKY
lda #<CHUNKY
sta DTV_PLANEB_START_LO
//SEG21 [13] *((const byte*) DTV_PLANEB_START_MI#0) ← >(const byte*) CHUNKY#0 -- _deref_pbuc1=vbuc2
@ -2236,16 +2236,16 @@ main: {
lda #0
sta DTV_PLANEB_MODULO_HI
//SEG26 [18] *((const byte*) CIA2_PORT_A_DDR#0) ← (byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2
// VIC Graphics Bank
// VIC Graphics Bank
lda #3
sta CIA2_PORT_A_DDR
//SEG27 [19] *((const byte*) CIA2_PORT_A#0) ← (byte/signed byte/word/signed word/dword/signed dword) 3^((byte))((word))(const byte*) CHUNKY#0/(word/signed word/dword/signed dword) 16384 -- _deref_pbuc1=vbuc2
// Set VIC Bank bits to output - all others to input
// Set VIC Bank bits to output - all others to input
lda #3^CHUNKY/$4000
sta CIA2_PORT_A
//SEG28 [20] *((const byte*) VIC_MEMORY#0) ← ((byte))((word))(const byte*) CHUNKY#0&(word/signed word/dword/signed dword) 16383>>(byte/signed byte/word/signed word/dword/signed dword) 6|>((word))(const byte*) CHUNKY#0&(word/signed word/dword/signed dword) 16383>>(byte/signed byte/word/signed word/dword/signed dword) 2 -- _deref_pbuc1=vbuc2
// Set VIC Bank
// VIC memory
// Set VIC Bank
// VIC memory
lda #(CHUNKY&$3fff)>>6|(0)>>2
sta VIC_MEMORY
//SEG29 [21] phi from main::@17 to main::@1 [phi:main::@17->main::@1]
@ -2253,7 +2253,7 @@ main: {
//SEG30 [21] phi (byte) main::j#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@17->main::@1#0] -- vbuxx=vbuc1
ldx #0
jmp b1
// DTV Palette - Grey Tones
// DTV Palette - Grey Tones
//SEG31 [21] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
b1_from_b1:
//SEG32 [21] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@1->main::@1#0] -- register_copy
@ -2272,7 +2272,7 @@ main: {
//SEG37 main::@3
b3:
//SEG38 asm { ldx#$ff rff: cpxRASTER bnerff stabilize: nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop cpxRASTER beqeat+0 eat: inx cpx#$08 bnestabilize }
// Stabilize Raster
// Stabilize Raster
ldx #$ff
rff:
cpx RASTER
@ -2386,7 +2386,7 @@ main: {
jmp b3
}
//SEG54 gfx_init_chunky
// Initialize Plane with 8bpp chunky
// Initialize Plane with 8bpp chunky
gfx_init_chunky: {
.label _6 = 7
.label gfxb = 5
@ -2532,11 +2532,11 @@ gfx_init_chunky: {
rts
}
//SEG107 dtvSetCpuBankSegment1
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
dtvSetCpuBankSegment1: {
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
.label cpuBank = $ff
//SEG108 [59] *((const byte*) dtvSetCpuBankSegment1::cpuBank#0) ← (byte) dtvSetCpuBankSegment1::cpuBankIdx#3 -- _deref_pbuc1=vbuaa
sta cpuBank
@ -2897,19 +2897,19 @@ FINAL ASSEMBLER
Score: 19882
//SEG0 File Comments
// C64DTV 8bpp charmode stretcher
// C64DTV 8bpp charmode stretcher
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// Processor port data direction register
// Processor port data direction register
.label PROCPORT_DDR = 0
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
.const PROCPORT_DDR_MEMORY_MASK = 7
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// RAM in $A000, $E000 I/O in $D000
// RAM in $A000, $E000 I/O in $D000
.const PROCPORT_RAM_IO = $35
.label RASTER = $d012
.label BORDERCOL = $d020
@ -2921,30 +2921,30 @@ Score: 19882
.const VIC_MCM = $10
.const VIC_CSEL = 8
.label VIC_MEMORY = $d018
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
.label CIA2_PORT_A = $dd00
// CIA #2 Port A data direction register.
// CIA #2 Port A data direction register.
.label CIA2_PORT_A_DDR = $dd02
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Controls the graphics modes of the C64 DTV
// Controls the graphics modes of the C64 DTV
.label DTV_CONTROL = $d03c
.const DTV_LINEAR = 1
.const DTV_HIGHCOLOR = 4
.const DTV_COLORRAM_OFF = $10
.const DTV_BADLINE_OFF = $20
.const DTV_CHUNKY = $40
// Defines colors for the 16 first colors ($00-$0f)
// Defines colors for the 16 first colors ($00-$0f)
.label DTV_PALETTE = $d200
// Linear Graphics Plane B Counter Control
// Linear Graphics Plane B Counter Control
.label DTV_PLANEB_START_LO = $d049
.label DTV_PLANEB_START_MI = $d04a
.label DTV_PLANEB_START_HI = $d04b
.label DTV_PLANEB_STEP = $d04c
.label DTV_PLANEB_MODULO_LO = $d047
.label DTV_PLANEB_MODULO_HI = $d048
// Plane with all pixels
// Plane with all pixels
.label CHUNKY = $8000
//SEG3 @begin
//SEG4 [1] phi from @begin to @7 [phi:@begin->@7]
@ -2957,8 +2957,8 @@ main: {
//SEG10 asm { sei }
sei
//SEG11 [5] *((const byte*) PROCPORT_DDR#0) ← (const byte) PROCPORT_DDR_MEMORY_MASK#0 -- _deref_pbuc1=vbuc2
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
//SEG12 [6] *((const byte*) PROCPORT#0) ← (const byte) PROCPORT_RAM_IO#0 -- _deref_pbuc1=vbuc2
@ -2969,11 +2969,11 @@ main: {
jsr gfx_init_chunky
//SEG15 main::@17
//SEG16 [8] *((const byte*) DTV_FEATURE#0) ← (const byte) DTV_FEATURE_ENABLE#0 -- _deref_pbuc1=vbuc2
// Enable DTV extended modes
// Enable DTV extended modes
lda #DTV_FEATURE_ENABLE
sta DTV_FEATURE
//SEG17 [9] *((const byte*) DTV_CONTROL#0) ← (const byte) DTV_HIGHCOLOR#0|(const byte) DTV_LINEAR#0|(const byte) DTV_COLORRAM_OFF#0|(const byte) DTV_CHUNKY#0|(const byte) DTV_BADLINE_OFF#0 -- _deref_pbuc1=vbuc2
// 8BPP Pixel Cell Mode
// 8BPP Pixel Cell Mode
lda #DTV_HIGHCOLOR|DTV_LINEAR|DTV_COLORRAM_OFF|DTV_CHUNKY|DTV_BADLINE_OFF
sta DTV_CONTROL
//SEG18 [10] *((const byte*) VIC_CONTROL#0) ← (const byte) VIC_DEN#0|(const byte) VIC_ECM#0|(const byte) VIC_RSEL#0|(byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2
@ -2983,7 +2983,7 @@ main: {
lda #VIC_MCM|VIC_CSEL
sta VIC_CONTROL2
//SEG20 [12] *((const byte*) DTV_PLANEB_START_LO#0) ← <(const byte*) CHUNKY#0 -- _deref_pbuc1=vbuc2
// Plane B: CHUNKY
// Plane B: CHUNKY
lda #<CHUNKY
sta DTV_PLANEB_START_LO
//SEG21 [13] *((const byte*) DTV_PLANEB_START_MI#0) ← >(const byte*) CHUNKY#0 -- _deref_pbuc1=vbuc2
@ -3001,22 +3001,22 @@ main: {
//SEG25 [17] *((const byte*) DTV_PLANEB_MODULO_HI#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2
sta DTV_PLANEB_MODULO_HI
//SEG26 [18] *((const byte*) CIA2_PORT_A_DDR#0) ← (byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2
// VIC Graphics Bank
// VIC Graphics Bank
lda #3
sta CIA2_PORT_A_DDR
//SEG27 [19] *((const byte*) CIA2_PORT_A#0) ← (byte/signed byte/word/signed word/dword/signed dword) 3^((byte))((word))(const byte*) CHUNKY#0/(word/signed word/dword/signed dword) 16384 -- _deref_pbuc1=vbuc2
// Set VIC Bank bits to output - all others to input
// Set VIC Bank bits to output - all others to input
lda #3^CHUNKY/$4000
sta CIA2_PORT_A
//SEG28 [20] *((const byte*) VIC_MEMORY#0) ← ((byte))((word))(const byte*) CHUNKY#0&(word/signed word/dword/signed dword) 16383>>(byte/signed byte/word/signed word/dword/signed dword) 6|>((word))(const byte*) CHUNKY#0&(word/signed word/dword/signed dword) 16383>>(byte/signed byte/word/signed word/dword/signed dword) 2 -- _deref_pbuc1=vbuc2
// Set VIC Bank
// VIC memory
// Set VIC Bank
// VIC memory
lda #(CHUNKY&$3fff)>>6|(0)>>2
sta VIC_MEMORY
//SEG29 [21] phi from main::@17 to main::@1 [phi:main::@17->main::@1]
//SEG30 [21] phi (byte) main::j#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@17->main::@1#0] -- vbuxx=vbuc1
ldx #0
// DTV Palette - Grey Tones
// DTV Palette - Grey Tones
//SEG31 [21] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
//SEG32 [21] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@1->main::@1#0] -- register_copy
//SEG33 main::@1
@ -3032,7 +3032,7 @@ main: {
//SEG37 main::@3
b3:
//SEG38 asm { ldx#$ff rff: cpxRASTER bnerff stabilize: nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop cpxRASTER beqeat+0 eat: inx cpx#$08 bnestabilize }
// Stabilize Raster
// Stabilize Raster
ldx #$ff
rff:
cpx RASTER
@ -3142,7 +3142,7 @@ main: {
jmp b3
}
//SEG54 gfx_init_chunky
// Initialize Plane with 8bpp chunky
// Initialize Plane with 8bpp chunky
gfx_init_chunky: {
.label _6 = 7
.label gfxb = 5
@ -3261,11 +3261,11 @@ gfx_init_chunky: {
rts
}
//SEG107 dtvSetCpuBankSegment1
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
dtvSetCpuBankSegment1: {
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
.label cpuBank = $ff
//SEG108 [59] *((const byte*) dtvSetCpuBankSegment1::cpuBank#0) ← (byte) dtvSetCpuBankSegment1::cpuBankIdx#3 -- _deref_pbuc1=vbuaa
sta cpuBank

View File

@ -1,80 +1,80 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Blitter Source A Start
// Blitter Source A Start
.label DTV_BLITTER_SRCA_LO = $d320
.label DTV_BLITTER_SRCA_MI = $d321
.label DTV_BLITTER_SRCA_HI = $d322
// Blitter Source A Modulo
// Blitter Source A Modulo
.label DTV_BLITTER_SRCA_MOD_LO = $d323
.label DTV_BLITTER_SRCA_MOD_HI = $d324
// Blitter Source A Line Length
// Blitter Source A Line Length
.label DTV_BLITTER_SRCA_LIN_LO = $d325
.label DTV_BLITTER_SRCA_LIN_HI = $d326
// Blitter Source A Step ([7:4] integral part, [3:0] fractional part)
// Blitter Source A Step ([7:4] integral part, [3:0] fractional part)
.label DTV_BLITTER_SRCA_STEP = $d327
// Blitter Source B Start
// Blitter Source B Start
.label DTV_BLITTER_SRCB_LO = $d328
.label DTV_BLITTER_SRCB_MI = $d329
.label DTV_BLITTER_SRCB_HI = $d32a
// Blitter Source B Modulo
// Blitter Source B Modulo
.label DTV_BLITTER_SRCB_MOD_LO = $d32b
.label DTV_BLITTER_SRCB_MOD_HI = $d32c
// Blitter Source B Line Length
// Blitter Source B Line Length
.label DTV_BLITTER_SRCB_LIN_LO = $d32d
.label DTV_BLITTER_SRCB_LIN_HI = $d32e
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
.label DTV_BLITTER_SRCB_STEP = $d32f
// Blitter Destination Start
// Blitter Destination Start
.label DTV_BLITTER_DEST_LO = $d330
.label DTV_BLITTER_DEST_MI = $d331
.label DTV_BLITTER_DEST_HI = $d332
// Blitter Source B Modulo
// Blitter Source B Modulo
.label DTV_BLITTER_DEST_MOD_LO = $d333
.label DTV_BLITTER_DEST_MOD_HI = $d334
// Blitter Source B Line Length
// Blitter Source B Line Length
.label DTV_BLITTER_DEST_LIN_LO = $d335
.label DTV_BLITTER_DEST_LIN_HI = $d336
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
.label DTV_BLITTER_DEST_STEP = $d337
// Blitter Blit Length
// Blitter Blit Length
.label DTV_BLITTER_LEN_LO = $d338
.label DTV_BLITTER_LEN_HI = $d339
// Blitter Control
// Blitter Control
.label DTV_BLITTER_CONTROL = $d33a
// Bit[0] Force Start Strobe when set
// Bit[0] Force Start Strobe when set
.const DTV_BLIT_FORCE_START = 1
// Bit[1] Source A Direction Positive when set
// Bit[1] Source A Direction Positive when set
.const DTV_BLIT_SRCA_FWD = 2
// Bit[2] Source B Direction Positive when set
// Bit[2] Source B Direction Positive when set
.const DTV_BLIT_SRCB_FWD = 4
// Bit[3] Destination Direction Positive when set
// Bit[3] Destination Direction Positive when set
.const DTV_BLIT_DEST_FWD = 8
// Blitter Transparency
// Blitter Transparency
.label DTV_BLITTER_TRANSPARANCY = $d33b
// No transparancy
// Bit[2]==Bit[1]==0: write in any case
// No transparancy
// Bit[2]==Bit[1]==0: write in any case
.const DTV_BLIT_TRANSPARANCY_NONE = 0
// Controls the ALU operation
// Controls the ALU operation
.label DTV_BLITTER_ALU = $d33e
.const DTV_BLIT_ADD = $30
// Blitter Control 2
// Blitter Control 2
.label DTV_BLITTER_CONTROL2 = $d33f
// Bit[0] Clear Blitter IRQ
// Bit[0] Clear Blitter IRQ
.const DTV_BLIT_CLEAR_IRQ = 1
// Bit[3] Destination Continue
// Bit[3] Destination Continue
.const DTV_BLIT_DEST_CONT = 8
// Bit[0] Busy when set (When reading)
// Bit[0] Busy when set (When reading)
.const DTV_BLIT_STATUS_BUSY = 1
.label SCREEN = $400
.const SRCA_LEN = 9
main: {
lda #DTV_FEATURE_ENABLE
sta DTV_FEATURE
// Instruct blitter not to continue previous blit
// Instruct blitter not to continue previous blit
lda #DTV_BLIT_CLEAR_IRQ
sta DTV_BLITTER_CONTROL2
lda #<SRCA
@ -91,7 +91,7 @@ main: {
sta DTV_BLITTER_SRCA_LIN_HI
lda #$10
sta DTV_BLITTER_SRCA_STEP
// Step 1.0
// Step 1.0
lda #<SRCB
sta DTV_BLITTER_SRCB_LO
lda #>SRCB
@ -106,7 +106,7 @@ main: {
sta DTV_BLITTER_SRCB_LIN_HI
lda #0
sta DTV_BLITTER_SRCB_STEP
// Step 0.0
// Step 0.0
lda #<SCREEN
sta DTV_BLITTER_DEST_LO
lda #>SCREEN
@ -121,7 +121,7 @@ main: {
sta DTV_BLITTER_DEST_LIN_HI
lda #$10
sta DTV_BLITTER_DEST_STEP
// Step 1.0
// Step 1.0
lda #SRCA_LEN
sta DTV_BLITTER_LEN_LO
lda #0
@ -130,20 +130,20 @@ main: {
sta DTV_BLITTER_ALU
lda #DTV_BLIT_TRANSPARANCY_NONE
sta DTV_BLITTER_TRANSPARANCY
// Start blitter
// Start blitter
lda #DTV_BLIT_FORCE_START|DTV_BLIT_SRCA_FWD|DTV_BLIT_SRCB_FWD|DTV_BLIT_DEST_FWD
sta DTV_BLITTER_CONTROL
// Instruct blitter to continue at DEST and restart SRC A/B
// Instruct blitter to continue at DEST and restart SRC A/B
lda #DTV_BLIT_DEST_CONT
sta DTV_BLITTER_CONTROL2
ldx #0
// wait til blitter is ready
// wait til blitter is ready
b2:
lda DTV_BLITTER_CONTROL2
and #DTV_BLIT_STATUS_BUSY
cmp #0
bne b2
// restart
// restart
lda #DTV_BLIT_FORCE_START|DTV_BLIT_SRCA_FWD|DTV_BLIT_SRCB_FWD|DTV_BLIT_DEST_FWD
sta DTV_BLITTER_CONTROL
inx

View File

@ -1181,73 +1181,73 @@ INITIAL ASM
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Blitter Source A Start
// Blitter Source A Start
.label DTV_BLITTER_SRCA_LO = $d320
.label DTV_BLITTER_SRCA_MI = $d321
.label DTV_BLITTER_SRCA_HI = $d322
// Blitter Source A Modulo
// Blitter Source A Modulo
.label DTV_BLITTER_SRCA_MOD_LO = $d323
.label DTV_BLITTER_SRCA_MOD_HI = $d324
// Blitter Source A Line Length
// Blitter Source A Line Length
.label DTV_BLITTER_SRCA_LIN_LO = $d325
.label DTV_BLITTER_SRCA_LIN_HI = $d326
// Blitter Source A Step ([7:4] integral part, [3:0] fractional part)
// Blitter Source A Step ([7:4] integral part, [3:0] fractional part)
.label DTV_BLITTER_SRCA_STEP = $d327
// Blitter Source B Start
// Blitter Source B Start
.label DTV_BLITTER_SRCB_LO = $d328
.label DTV_BLITTER_SRCB_MI = $d329
.label DTV_BLITTER_SRCB_HI = $d32a
// Blitter Source B Modulo
// Blitter Source B Modulo
.label DTV_BLITTER_SRCB_MOD_LO = $d32b
.label DTV_BLITTER_SRCB_MOD_HI = $d32c
// Blitter Source B Line Length
// Blitter Source B Line Length
.label DTV_BLITTER_SRCB_LIN_LO = $d32d
.label DTV_BLITTER_SRCB_LIN_HI = $d32e
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
.label DTV_BLITTER_SRCB_STEP = $d32f
// Blitter Destination Start
// Blitter Destination Start
.label DTV_BLITTER_DEST_LO = $d330
.label DTV_BLITTER_DEST_MI = $d331
.label DTV_BLITTER_DEST_HI = $d332
// Blitter Source B Modulo
// Blitter Source B Modulo
.label DTV_BLITTER_DEST_MOD_LO = $d333
.label DTV_BLITTER_DEST_MOD_HI = $d334
// Blitter Source B Line Length
// Blitter Source B Line Length
.label DTV_BLITTER_DEST_LIN_LO = $d335
.label DTV_BLITTER_DEST_LIN_HI = $d336
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
.label DTV_BLITTER_DEST_STEP = $d337
// Blitter Blit Length
// Blitter Blit Length
.label DTV_BLITTER_LEN_LO = $d338
.label DTV_BLITTER_LEN_HI = $d339
// Blitter Control
// Blitter Control
.label DTV_BLITTER_CONTROL = $d33a
// Bit[0] Force Start Strobe when set
// Bit[0] Force Start Strobe when set
.const DTV_BLIT_FORCE_START = 1
// Bit[1] Source A Direction Positive when set
// Bit[1] Source A Direction Positive when set
.const DTV_BLIT_SRCA_FWD = 2
// Bit[2] Source B Direction Positive when set
// Bit[2] Source B Direction Positive when set
.const DTV_BLIT_SRCB_FWD = 4
// Bit[3] Destination Direction Positive when set
// Bit[3] Destination Direction Positive when set
.const DTV_BLIT_DEST_FWD = 8
// Blitter Transparency
// Blitter Transparency
.label DTV_BLITTER_TRANSPARANCY = $d33b
// No transparancy
// Bit[2]==Bit[1]==0: write in any case
// No transparancy
// Bit[2]==Bit[1]==0: write in any case
.const DTV_BLIT_TRANSPARANCY_NONE = 0
// Controls the ALU operation
// Controls the ALU operation
.label DTV_BLITTER_ALU = $d33e
.const DTV_BLIT_ADD = $30
// Blitter Control 2
// Blitter Control 2
.label DTV_BLITTER_CONTROL2 = $d33f
// Bit[0] Clear Blitter IRQ
// Bit[0] Clear Blitter IRQ
.const DTV_BLIT_CLEAR_IRQ = 1
// Bit[3] Destination Continue
// Bit[3] Destination Continue
.const DTV_BLIT_DEST_CONT = 8
// Bit[0] Busy when set (When reading)
// Bit[0] Busy when set (When reading)
.const DTV_BLIT_STATUS_BUSY = 1
.label SCREEN = $400
.const SRCA_LEN = 9
@ -1273,7 +1273,7 @@ main: {
lda #DTV_FEATURE_ENABLE
sta DTV_FEATURE
//SEG11 [5] *((const byte*) DTV_BLITTER_CONTROL2#0) ← (const byte) DTV_BLIT_CLEAR_IRQ#0 -- _deref_pbuc1=vbuc2
// Instruct blitter not to continue previous blit
// Instruct blitter not to continue previous blit
lda #DTV_BLIT_CLEAR_IRQ
sta DTV_BLITTER_CONTROL2
//SEG12 [6] *((const byte*) DTV_BLITTER_SRCA_LO#0) ← <(const byte[]) SRCA#0 -- _deref_pbuc1=vbuc2
@ -1301,7 +1301,7 @@ main: {
lda #$10
sta DTV_BLITTER_SRCA_STEP
//SEG20 [14] *((const byte*) DTV_BLITTER_SRCB_LO#0) ← <(const byte[]) SRCB#0 -- _deref_pbuc1=vbuc2
// Step 1.0
// Step 1.0
lda #<SRCB
sta DTV_BLITTER_SRCB_LO
//SEG21 [15] *((const byte*) DTV_BLITTER_SRCB_MI#0) ← >(const byte[]) SRCB#0 -- _deref_pbuc1=vbuc2
@ -1326,7 +1326,7 @@ main: {
lda #0
sta DTV_BLITTER_SRCB_STEP
//SEG28 [22] *((const byte*) DTV_BLITTER_DEST_LO#0) ← <(const byte*) SCREEN#0 -- _deref_pbuc1=vbuc2
// Step 0.0
// Step 0.0
lda #<SCREEN
sta DTV_BLITTER_DEST_LO
//SEG29 [23] *((const byte*) DTV_BLITTER_DEST_MI#0) ← >(const byte*) SCREEN#0 -- _deref_pbuc1=vbuc2
@ -1351,7 +1351,7 @@ main: {
lda #$10
sta DTV_BLITTER_DEST_STEP
//SEG36 [30] *((const byte*) DTV_BLITTER_LEN_LO#0) ← (const byte) SRCA_LEN#0 -- _deref_pbuc1=vbuc2
// Step 1.0
// Step 1.0
lda #SRCA_LEN
sta DTV_BLITTER_LEN_LO
//SEG37 [31] *((const byte*) DTV_BLITTER_LEN_HI#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2
@ -1364,11 +1364,11 @@ main: {
lda #DTV_BLIT_TRANSPARANCY_NONE
sta DTV_BLITTER_TRANSPARANCY
//SEG40 [34] *((const byte*) DTV_BLITTER_CONTROL#0) ← (const byte) DTV_BLIT_FORCE_START#0|(const byte) DTV_BLIT_SRCA_FWD#0|(const byte) DTV_BLIT_SRCB_FWD#0|(const byte) DTV_BLIT_DEST_FWD#0 -- _deref_pbuc1=vbuc2
// Start blitter
// Start blitter
lda #DTV_BLIT_FORCE_START|DTV_BLIT_SRCA_FWD|DTV_BLIT_SRCB_FWD|DTV_BLIT_DEST_FWD
sta DTV_BLITTER_CONTROL
//SEG41 [35] *((const byte*) DTV_BLITTER_CONTROL2#0) ← (const byte) DTV_BLIT_DEST_CONT#0 -- _deref_pbuc1=vbuc2
// Instruct blitter to continue at DEST and restart SRC A/B
// Instruct blitter to continue at DEST and restart SRC A/B
lda #DTV_BLIT_DEST_CONT
sta DTV_BLITTER_CONTROL2
//SEG42 [36] phi from main to main::@2 [phi:main->main::@2]
@ -1377,7 +1377,7 @@ main: {
lda #0
sta r
jmp b2
// wait til blitter is ready
// wait til blitter is ready
//SEG44 [36] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
b2_from_b2:
jmp b2
@ -1399,7 +1399,7 @@ main: {
//SEG50 main::@3
b3:
//SEG51 [39] *((const byte*) DTV_BLITTER_CONTROL#0) ← (const byte) DTV_BLIT_FORCE_START#0|(const byte) DTV_BLIT_SRCA_FWD#0|(const byte) DTV_BLIT_SRCB_FWD#0|(const byte) DTV_BLIT_DEST_FWD#0 -- _deref_pbuc1=vbuc2
// restart
// restart
lda #DTV_BLIT_FORCE_START|DTV_BLIT_SRCA_FWD|DTV_BLIT_SRCB_FWD|DTV_BLIT_DEST_FWD
sta DTV_BLITTER_CONTROL
//SEG52 [40] (byte) main::r#1 ← ++ (byte) main::r#2 -- vbuz1=_inc_vbuz1
@ -1504,73 +1504,73 @@ ASSEMBLER BEFORE OPTIMIZATION
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Blitter Source A Start
// Blitter Source A Start
.label DTV_BLITTER_SRCA_LO = $d320
.label DTV_BLITTER_SRCA_MI = $d321
.label DTV_BLITTER_SRCA_HI = $d322
// Blitter Source A Modulo
// Blitter Source A Modulo
.label DTV_BLITTER_SRCA_MOD_LO = $d323
.label DTV_BLITTER_SRCA_MOD_HI = $d324
// Blitter Source A Line Length
// Blitter Source A Line Length
.label DTV_BLITTER_SRCA_LIN_LO = $d325
.label DTV_BLITTER_SRCA_LIN_HI = $d326
// Blitter Source A Step ([7:4] integral part, [3:0] fractional part)
// Blitter Source A Step ([7:4] integral part, [3:0] fractional part)
.label DTV_BLITTER_SRCA_STEP = $d327
// Blitter Source B Start
// Blitter Source B Start
.label DTV_BLITTER_SRCB_LO = $d328
.label DTV_BLITTER_SRCB_MI = $d329
.label DTV_BLITTER_SRCB_HI = $d32a
// Blitter Source B Modulo
// Blitter Source B Modulo
.label DTV_BLITTER_SRCB_MOD_LO = $d32b
.label DTV_BLITTER_SRCB_MOD_HI = $d32c
// Blitter Source B Line Length
// Blitter Source B Line Length
.label DTV_BLITTER_SRCB_LIN_LO = $d32d
.label DTV_BLITTER_SRCB_LIN_HI = $d32e
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
.label DTV_BLITTER_SRCB_STEP = $d32f
// Blitter Destination Start
// Blitter Destination Start
.label DTV_BLITTER_DEST_LO = $d330
.label DTV_BLITTER_DEST_MI = $d331
.label DTV_BLITTER_DEST_HI = $d332
// Blitter Source B Modulo
// Blitter Source B Modulo
.label DTV_BLITTER_DEST_MOD_LO = $d333
.label DTV_BLITTER_DEST_MOD_HI = $d334
// Blitter Source B Line Length
// Blitter Source B Line Length
.label DTV_BLITTER_DEST_LIN_LO = $d335
.label DTV_BLITTER_DEST_LIN_HI = $d336
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
.label DTV_BLITTER_DEST_STEP = $d337
// Blitter Blit Length
// Blitter Blit Length
.label DTV_BLITTER_LEN_LO = $d338
.label DTV_BLITTER_LEN_HI = $d339
// Blitter Control
// Blitter Control
.label DTV_BLITTER_CONTROL = $d33a
// Bit[0] Force Start Strobe when set
// Bit[0] Force Start Strobe when set
.const DTV_BLIT_FORCE_START = 1
// Bit[1] Source A Direction Positive when set
// Bit[1] Source A Direction Positive when set
.const DTV_BLIT_SRCA_FWD = 2
// Bit[2] Source B Direction Positive when set
// Bit[2] Source B Direction Positive when set
.const DTV_BLIT_SRCB_FWD = 4
// Bit[3] Destination Direction Positive when set
// Bit[3] Destination Direction Positive when set
.const DTV_BLIT_DEST_FWD = 8
// Blitter Transparency
// Blitter Transparency
.label DTV_BLITTER_TRANSPARANCY = $d33b
// No transparancy
// Bit[2]==Bit[1]==0: write in any case
// No transparancy
// Bit[2]==Bit[1]==0: write in any case
.const DTV_BLIT_TRANSPARANCY_NONE = 0
// Controls the ALU operation
// Controls the ALU operation
.label DTV_BLITTER_ALU = $d33e
.const DTV_BLIT_ADD = $30
// Blitter Control 2
// Blitter Control 2
.label DTV_BLITTER_CONTROL2 = $d33f
// Bit[0] Clear Blitter IRQ
// Bit[0] Clear Blitter IRQ
.const DTV_BLIT_CLEAR_IRQ = 1
// Bit[3] Destination Continue
// Bit[3] Destination Continue
.const DTV_BLIT_DEST_CONT = 8
// Bit[0] Busy when set (When reading)
// Bit[0] Busy when set (When reading)
.const DTV_BLIT_STATUS_BUSY = 1
.label SCREEN = $400
.const SRCA_LEN = 9
@ -1594,7 +1594,7 @@ main: {
lda #DTV_FEATURE_ENABLE
sta DTV_FEATURE
//SEG11 [5] *((const byte*) DTV_BLITTER_CONTROL2#0) ← (const byte) DTV_BLIT_CLEAR_IRQ#0 -- _deref_pbuc1=vbuc2
// Instruct blitter not to continue previous blit
// Instruct blitter not to continue previous blit
lda #DTV_BLIT_CLEAR_IRQ
sta DTV_BLITTER_CONTROL2
//SEG12 [6] *((const byte*) DTV_BLITTER_SRCA_LO#0) ← <(const byte[]) SRCA#0 -- _deref_pbuc1=vbuc2
@ -1622,7 +1622,7 @@ main: {
lda #$10
sta DTV_BLITTER_SRCA_STEP
//SEG20 [14] *((const byte*) DTV_BLITTER_SRCB_LO#0) ← <(const byte[]) SRCB#0 -- _deref_pbuc1=vbuc2
// Step 1.0
// Step 1.0
lda #<SRCB
sta DTV_BLITTER_SRCB_LO
//SEG21 [15] *((const byte*) DTV_BLITTER_SRCB_MI#0) ← >(const byte[]) SRCB#0 -- _deref_pbuc1=vbuc2
@ -1647,7 +1647,7 @@ main: {
lda #0
sta DTV_BLITTER_SRCB_STEP
//SEG28 [22] *((const byte*) DTV_BLITTER_DEST_LO#0) ← <(const byte*) SCREEN#0 -- _deref_pbuc1=vbuc2
// Step 0.0
// Step 0.0
lda #<SCREEN
sta DTV_BLITTER_DEST_LO
//SEG29 [23] *((const byte*) DTV_BLITTER_DEST_MI#0) ← >(const byte*) SCREEN#0 -- _deref_pbuc1=vbuc2
@ -1672,7 +1672,7 @@ main: {
lda #$10
sta DTV_BLITTER_DEST_STEP
//SEG36 [30] *((const byte*) DTV_BLITTER_LEN_LO#0) ← (const byte) SRCA_LEN#0 -- _deref_pbuc1=vbuc2
// Step 1.0
// Step 1.0
lda #SRCA_LEN
sta DTV_BLITTER_LEN_LO
//SEG37 [31] *((const byte*) DTV_BLITTER_LEN_HI#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2
@ -1685,11 +1685,11 @@ main: {
lda #DTV_BLIT_TRANSPARANCY_NONE
sta DTV_BLITTER_TRANSPARANCY
//SEG40 [34] *((const byte*) DTV_BLITTER_CONTROL#0) ← (const byte) DTV_BLIT_FORCE_START#0|(const byte) DTV_BLIT_SRCA_FWD#0|(const byte) DTV_BLIT_SRCB_FWD#0|(const byte) DTV_BLIT_DEST_FWD#0 -- _deref_pbuc1=vbuc2
// Start blitter
// Start blitter
lda #DTV_BLIT_FORCE_START|DTV_BLIT_SRCA_FWD|DTV_BLIT_SRCB_FWD|DTV_BLIT_DEST_FWD
sta DTV_BLITTER_CONTROL
//SEG41 [35] *((const byte*) DTV_BLITTER_CONTROL2#0) ← (const byte) DTV_BLIT_DEST_CONT#0 -- _deref_pbuc1=vbuc2
// Instruct blitter to continue at DEST and restart SRC A/B
// Instruct blitter to continue at DEST and restart SRC A/B
lda #DTV_BLIT_DEST_CONT
sta DTV_BLITTER_CONTROL2
//SEG42 [36] phi from main to main::@2 [phi:main->main::@2]
@ -1697,7 +1697,7 @@ main: {
//SEG43 [36] phi (byte) main::r#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@2#0] -- vbuxx=vbuc1
ldx #0
jmp b2
// wait til blitter is ready
// wait til blitter is ready
//SEG44 [36] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
b2_from_b2:
jmp b2
@ -1717,7 +1717,7 @@ main: {
//SEG50 main::@3
b3:
//SEG51 [39] *((const byte*) DTV_BLITTER_CONTROL#0) ← (const byte) DTV_BLIT_FORCE_START#0|(const byte) DTV_BLIT_SRCA_FWD#0|(const byte) DTV_BLIT_SRCB_FWD#0|(const byte) DTV_BLIT_DEST_FWD#0 -- _deref_pbuc1=vbuc2
// restart
// restart
lda #DTV_BLIT_FORCE_START|DTV_BLIT_SRCA_FWD|DTV_BLIT_SRCB_FWD|DTV_BLIT_DEST_FWD
sta DTV_BLITTER_CONTROL
//SEG52 [40] (byte) main::r#1 ← ++ (byte) main::r#2 -- vbuxx=_inc_vbuxx
@ -2024,73 +2024,73 @@ Score: 1561
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Blitter Source A Start
// Blitter Source A Start
.label DTV_BLITTER_SRCA_LO = $d320
.label DTV_BLITTER_SRCA_MI = $d321
.label DTV_BLITTER_SRCA_HI = $d322
// Blitter Source A Modulo
// Blitter Source A Modulo
.label DTV_BLITTER_SRCA_MOD_LO = $d323
.label DTV_BLITTER_SRCA_MOD_HI = $d324
// Blitter Source A Line Length
// Blitter Source A Line Length
.label DTV_BLITTER_SRCA_LIN_LO = $d325
.label DTV_BLITTER_SRCA_LIN_HI = $d326
// Blitter Source A Step ([7:4] integral part, [3:0] fractional part)
// Blitter Source A Step ([7:4] integral part, [3:0] fractional part)
.label DTV_BLITTER_SRCA_STEP = $d327
// Blitter Source B Start
// Blitter Source B Start
.label DTV_BLITTER_SRCB_LO = $d328
.label DTV_BLITTER_SRCB_MI = $d329
.label DTV_BLITTER_SRCB_HI = $d32a
// Blitter Source B Modulo
// Blitter Source B Modulo
.label DTV_BLITTER_SRCB_MOD_LO = $d32b
.label DTV_BLITTER_SRCB_MOD_HI = $d32c
// Blitter Source B Line Length
// Blitter Source B Line Length
.label DTV_BLITTER_SRCB_LIN_LO = $d32d
.label DTV_BLITTER_SRCB_LIN_HI = $d32e
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
.label DTV_BLITTER_SRCB_STEP = $d32f
// Blitter Destination Start
// Blitter Destination Start
.label DTV_BLITTER_DEST_LO = $d330
.label DTV_BLITTER_DEST_MI = $d331
.label DTV_BLITTER_DEST_HI = $d332
// Blitter Source B Modulo
// Blitter Source B Modulo
.label DTV_BLITTER_DEST_MOD_LO = $d333
.label DTV_BLITTER_DEST_MOD_HI = $d334
// Blitter Source B Line Length
// Blitter Source B Line Length
.label DTV_BLITTER_DEST_LIN_LO = $d335
.label DTV_BLITTER_DEST_LIN_HI = $d336
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
.label DTV_BLITTER_DEST_STEP = $d337
// Blitter Blit Length
// Blitter Blit Length
.label DTV_BLITTER_LEN_LO = $d338
.label DTV_BLITTER_LEN_HI = $d339
// Blitter Control
// Blitter Control
.label DTV_BLITTER_CONTROL = $d33a
// Bit[0] Force Start Strobe when set
// Bit[0] Force Start Strobe when set
.const DTV_BLIT_FORCE_START = 1
// Bit[1] Source A Direction Positive when set
// Bit[1] Source A Direction Positive when set
.const DTV_BLIT_SRCA_FWD = 2
// Bit[2] Source B Direction Positive when set
// Bit[2] Source B Direction Positive when set
.const DTV_BLIT_SRCB_FWD = 4
// Bit[3] Destination Direction Positive when set
// Bit[3] Destination Direction Positive when set
.const DTV_BLIT_DEST_FWD = 8
// Blitter Transparency
// Blitter Transparency
.label DTV_BLITTER_TRANSPARANCY = $d33b
// No transparancy
// Bit[2]==Bit[1]==0: write in any case
// No transparancy
// Bit[2]==Bit[1]==0: write in any case
.const DTV_BLIT_TRANSPARANCY_NONE = 0
// Controls the ALU operation
// Controls the ALU operation
.label DTV_BLITTER_ALU = $d33e
.const DTV_BLIT_ADD = $30
// Blitter Control 2
// Blitter Control 2
.label DTV_BLITTER_CONTROL2 = $d33f
// Bit[0] Clear Blitter IRQ
// Bit[0] Clear Blitter IRQ
.const DTV_BLIT_CLEAR_IRQ = 1
// Bit[3] Destination Continue
// Bit[3] Destination Continue
.const DTV_BLIT_DEST_CONT = 8
// Bit[0] Busy when set (When reading)
// Bit[0] Busy when set (When reading)
.const DTV_BLIT_STATUS_BUSY = 1
.label SCREEN = $400
.const SRCA_LEN = 9
@ -2106,7 +2106,7 @@ main: {
lda #DTV_FEATURE_ENABLE
sta DTV_FEATURE
//SEG11 [5] *((const byte*) DTV_BLITTER_CONTROL2#0) ← (const byte) DTV_BLIT_CLEAR_IRQ#0 -- _deref_pbuc1=vbuc2
// Instruct blitter not to continue previous blit
// Instruct blitter not to continue previous blit
lda #DTV_BLIT_CLEAR_IRQ
sta DTV_BLITTER_CONTROL2
//SEG12 [6] *((const byte*) DTV_BLITTER_SRCA_LO#0) ← <(const byte[]) SRCA#0 -- _deref_pbuc1=vbuc2
@ -2132,7 +2132,7 @@ main: {
lda #$10
sta DTV_BLITTER_SRCA_STEP
//SEG20 [14] *((const byte*) DTV_BLITTER_SRCB_LO#0) ← <(const byte[]) SRCB#0 -- _deref_pbuc1=vbuc2
// Step 1.0
// Step 1.0
lda #<SRCB
sta DTV_BLITTER_SRCB_LO
//SEG21 [15] *((const byte*) DTV_BLITTER_SRCB_MI#0) ← >(const byte[]) SRCB#0 -- _deref_pbuc1=vbuc2
@ -2155,7 +2155,7 @@ main: {
lda #0
sta DTV_BLITTER_SRCB_STEP
//SEG28 [22] *((const byte*) DTV_BLITTER_DEST_LO#0) ← <(const byte*) SCREEN#0 -- _deref_pbuc1=vbuc2
// Step 0.0
// Step 0.0
lda #<SCREEN
sta DTV_BLITTER_DEST_LO
//SEG29 [23] *((const byte*) DTV_BLITTER_DEST_MI#0) ← >(const byte*) SCREEN#0 -- _deref_pbuc1=vbuc2
@ -2178,7 +2178,7 @@ main: {
lda #$10
sta DTV_BLITTER_DEST_STEP
//SEG36 [30] *((const byte*) DTV_BLITTER_LEN_LO#0) ← (const byte) SRCA_LEN#0 -- _deref_pbuc1=vbuc2
// Step 1.0
// Step 1.0
lda #SRCA_LEN
sta DTV_BLITTER_LEN_LO
//SEG37 [31] *((const byte*) DTV_BLITTER_LEN_HI#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2
@ -2191,17 +2191,17 @@ main: {
lda #DTV_BLIT_TRANSPARANCY_NONE
sta DTV_BLITTER_TRANSPARANCY
//SEG40 [34] *((const byte*) DTV_BLITTER_CONTROL#0) ← (const byte) DTV_BLIT_FORCE_START#0|(const byte) DTV_BLIT_SRCA_FWD#0|(const byte) DTV_BLIT_SRCB_FWD#0|(const byte) DTV_BLIT_DEST_FWD#0 -- _deref_pbuc1=vbuc2
// Start blitter
// Start blitter
lda #DTV_BLIT_FORCE_START|DTV_BLIT_SRCA_FWD|DTV_BLIT_SRCB_FWD|DTV_BLIT_DEST_FWD
sta DTV_BLITTER_CONTROL
//SEG41 [35] *((const byte*) DTV_BLITTER_CONTROL2#0) ← (const byte) DTV_BLIT_DEST_CONT#0 -- _deref_pbuc1=vbuc2
// Instruct blitter to continue at DEST and restart SRC A/B
// Instruct blitter to continue at DEST and restart SRC A/B
lda #DTV_BLIT_DEST_CONT
sta DTV_BLITTER_CONTROL2
//SEG42 [36] phi from main to main::@2 [phi:main->main::@2]
//SEG43 [36] phi (byte) main::r#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@2#0] -- vbuxx=vbuc1
ldx #0
// wait til blitter is ready
// wait til blitter is ready
//SEG44 [36] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
//SEG45 [36] phi from main::@3 to main::@2 [phi:main::@3->main::@2]
//SEG46 [36] phi (byte) main::r#2 = (byte) main::r#1 [phi:main::@3->main::@2#0] -- register_copy
@ -2215,7 +2215,7 @@ main: {
bne b2
//SEG50 main::@3
//SEG51 [39] *((const byte*) DTV_BLITTER_CONTROL#0) ← (const byte) DTV_BLIT_FORCE_START#0|(const byte) DTV_BLIT_SRCA_FWD#0|(const byte) DTV_BLIT_SRCB_FWD#0|(const byte) DTV_BLIT_DEST_FWD#0 -- _deref_pbuc1=vbuc2
// restart
// restart
lda #DTV_BLIT_FORCE_START|DTV_BLIT_SRCA_FWD|DTV_BLIT_SRCB_FWD|DTV_BLIT_DEST_FWD
sta DTV_BLITTER_CONTROL
//SEG52 [40] (byte) main::r#1 ← ++ (byte) main::r#2 -- vbuxx=_inc_vbuxx

View File

@ -1,18 +1,18 @@
// Test C64DTV v2 256-colors and the 16-color redefinable palette
// Test C64DTV v2 256-colors and the 16-color redefinable palette
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.label RASTER = $d012
.label BGCOL = $d021
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Controls the graphics modes of the C64 DTV
// Controls the graphics modes of the C64 DTV
.label DTV_CONTROL = $d03c
.const DTV_BORDER_OFF = 2
.const DTV_HIGHCOLOR = 4
.const DTV_BADLINE_OFF = $20
// Defines colors for the 16 first colors ($00-$0f)
// Defines colors for the 16 first colors ($00-$0f)
.label DTV_PALETTE = $d200
main: {
sei
@ -24,7 +24,7 @@ main: {
lda RASTER
cmp #$40
bne b4
// Create rasterbars
// Create rasterbars
lda #0
sta BGCOL
ldx #$31
@ -59,7 +59,7 @@ main: {
cpx #0
bne b7
ldx #0
// Rotate palette
// Rotate palette
b8:
lda palette,x
sta DTV_PALETTE,x

View File

@ -1075,7 +1075,7 @@ Allocated zp ZP_BYTE:3 [ main::c#2 main::c#1 ]
INITIAL ASM
//SEG0 File Comments
// Test C64DTV v2 256-colors and the 16-color redefinable palette
// Test C64DTV v2 256-colors and the 16-color redefinable palette
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -1083,15 +1083,15 @@ INITIAL ASM
//SEG2 Global Constants & labels
.label RASTER = $d012
.label BGCOL = $d021
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Controls the graphics modes of the C64 DTV
// Controls the graphics modes of the C64 DTV
.label DTV_CONTROL = $d03c
.const DTV_BORDER_OFF = 2
.const DTV_HIGHCOLOR = 4
.const DTV_BADLINE_OFF = $20
// Defines colors for the 16 first colors ($00-$0f)
// Defines colors for the 16 first colors ($00-$0f)
.label DTV_PALETTE = $d200
//SEG3 @begin
bbegin:
@ -1130,7 +1130,7 @@ main: {
//SEG15 main::@6
b6:
//SEG16 [8] *((const byte*) BGCOL#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2
// Create rasterbars
// Create rasterbars
lda #0
sta BGCOL
//SEG17 [9] phi from main::@6 to main::@7 [phi:main::@6->main::@7]
@ -1185,7 +1185,7 @@ main: {
lda #0
sta c
jmp b8
// Rotate palette
// Rotate palette
//SEG28 [14] phi from main::@8 to main::@8 [phi:main::@8->main::@8]
b8_from_b8:
//SEG29 [14] phi (byte) main::c#2 = (byte) main::c#1 [phi:main::@8->main::@8#0] -- register_copy
@ -1233,7 +1233,7 @@ Uplifting [] best 11689 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Test C64DTV v2 256-colors and the 16-color redefinable palette
// Test C64DTV v2 256-colors and the 16-color redefinable palette
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -1241,15 +1241,15 @@ ASSEMBLER BEFORE OPTIMIZATION
//SEG2 Global Constants & labels
.label RASTER = $d012
.label BGCOL = $d021
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Controls the graphics modes of the C64 DTV
// Controls the graphics modes of the C64 DTV
.label DTV_CONTROL = $d03c
.const DTV_BORDER_OFF = 2
.const DTV_HIGHCOLOR = 4
.const DTV_BADLINE_OFF = $20
// Defines colors for the 16 first colors ($00-$0f)
// Defines colors for the 16 first colors ($00-$0f)
.label DTV_PALETTE = $d200
//SEG3 @begin
bbegin:
@ -1286,7 +1286,7 @@ main: {
//SEG15 main::@6
b6:
//SEG16 [8] *((const byte*) BGCOL#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2
// Create rasterbars
// Create rasterbars
lda #0
sta BGCOL
//SEG17 [9] phi from main::@6 to main::@7 [phi:main::@6->main::@7]
@ -1338,7 +1338,7 @@ main: {
//SEG27 [14] phi (byte) main::c#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@7->main::@8#0] -- vbuxx=vbuc1
ldx #0
jmp b8
// Rotate palette
// Rotate palette
//SEG28 [14] phi from main::@8 to main::@8 [phi:main::@8->main::@8]
b8_from_b8:
//SEG29 [14] phi (byte) main::c#2 = (byte) main::c#1 [phi:main::@8->main::@8#0] -- register_copy
@ -1598,7 +1598,7 @@ FINAL ASSEMBLER
Score: 10174
//SEG0 File Comments
// Test C64DTV v2 256-colors and the 16-color redefinable palette
// Test C64DTV v2 256-colors and the 16-color redefinable palette
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
@ -1606,15 +1606,15 @@ Score: 10174
//SEG2 Global Constants & labels
.label RASTER = $d012
.label BGCOL = $d021
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Controls the graphics modes of the C64 DTV
// Controls the graphics modes of the C64 DTV
.label DTV_CONTROL = $d03c
.const DTV_BORDER_OFF = 2
.const DTV_HIGHCOLOR = 4
.const DTV_BADLINE_OFF = $20
// Defines colors for the 16 first colors ($00-$0f)
// Defines colors for the 16 first colors ($00-$0f)
.label DTV_PALETTE = $d200
//SEG3 @begin
//SEG4 [1] phi from @begin to @6 [phi:@begin->@6]
@ -1640,7 +1640,7 @@ main: {
bne b4
//SEG15 main::@6
//SEG16 [8] *((const byte*) BGCOL#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2
// Create rasterbars
// Create rasterbars
lda #0
sta BGCOL
//SEG17 [9] phi from main::@6 to main::@7 [phi:main::@6->main::@7]
@ -1686,7 +1686,7 @@ main: {
//SEG26 [14] phi from main::@7 to main::@8 [phi:main::@7->main::@8]
//SEG27 [14] phi (byte) main::c#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@7->main::@8#0] -- vbuxx=vbuc1
ldx #0
// Rotate palette
// Rotate palette
//SEG28 [14] phi from main::@8 to main::@8 [phi:main::@8->main::@8]
//SEG29 [14] phi (byte) main::c#2 = (byte) main::c#1 [phi:main::@8->main::@8#0] -- register_copy
//SEG30 main::@8

View File

@ -1,18 +1,18 @@
// Interactive Explorer for C64DTV Screen Modes
// Interactive Explorer for C64DTV Screen Modes
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Processor port data direction register
// Processor port data direction register
.label PROCPORT_DDR = 0
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
.const PROCPORT_DDR_MEMORY_MASK = 7
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// RAM in $A000, $E000 I/O in $D000
// RAM in $A000, $E000 I/O in $D000
.const PROCPORT_RAM_IO = $35
// RAM in $A000, $E000 CHAR ROM in $D000
// RAM in $A000, $E000 CHAR ROM in $D000
.const PROCPORT_RAM_CHARROM = $31
// The address of the CHARGEN character set
// The address of the CHARGEN character set
.label CHARGEN = $d000
.label RASTER = $d012
.label BORDERCOL = $d020
@ -30,24 +30,24 @@
.const VIC_MCM = $10
.const VIC_CSEL = 8
.label VIC_MEMORY = $d018
// Color Ram
// Color Ram
.label COLS = $d800
// CIA#1 Port A: keyboard matrix columns and joystick #2
// CIA#1 Port A: keyboard matrix columns and joystick #2
.label CIA1_PORT_A = $dc00
// CIA#1 Port B: keyboard matrix rows and joystick #1.
// CIA#1 Port B: keyboard matrix rows and joystick #1.
.label CIA1_PORT_B = $dc01
// CIA #1 Port A data direction register.
// CIA #1 Port A data direction register.
.label CIA1_PORT_A_DDR = $dc02
// CIA #1 Port B data direction register.
// CIA #1 Port B data direction register.
.label CIA1_PORT_B_DDR = $dc03
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
.label CIA2_PORT_A = $dd00
// CIA #2 Port A data direction register.
// CIA #2 Port A data direction register.
.label CIA2_PORT_A_DDR = $dd02
// Feature enables or disables the extra C64 DTV features
// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
.const DTV_FEATURE_ENABLE = 1
// Controls the graphics modes of the C64 DTV
// Controls the graphics modes of the C64 DTV
.label DTV_CONTROL = $d03c
.const DTV_LINEAR = 1
.const DTV_BORDER_OFF = 2
@ -55,29 +55,29 @@
.const DTV_OVERSCAN = 8
.const DTV_COLORRAM_OFF = $10
.const DTV_CHUNKY = $40
// Defines colors for the 16 first colors ($00-$0f)
// Defines colors for the 16 first colors ($00-$0f)
.label DTV_PALETTE = $d200
// Linear Graphics Plane A Counter Control
// Linear Graphics Plane A Counter Control
.label DTV_PLANEA_START_LO = $d03a
.label DTV_PLANEA_START_MI = $d03b
.label DTV_PLANEA_START_HI = $d045
.label DTV_PLANEA_STEP = $d046
.label DTV_PLANEA_MODULO_LO = $d038
.label DTV_PLANEA_MODULO_HI = $d039
// Linear Graphics Plane B Counter Control
// Linear Graphics Plane B Counter Control
.label DTV_PLANEB_START_LO = $d049
.label DTV_PLANEB_START_MI = $d04a
.label DTV_PLANEB_START_HI = $d04b
.label DTV_PLANEB_STEP = $d04c
.label DTV_PLANEB_MODULO_LO = $d047
.label DTV_PLANEB_MODULO_HI = $d048
// Select memory bank where color data is fetched from (bits 11:0)
// Memory address of Color RAM is ColorBank*$400
// Select memory bank where color data is fetched from (bits 11:0)
// Memory address of Color RAM is ColorBank*$400
.label DTV_COLOR_BANK_LO = $d036
.label DTV_COLOR_BANK_HI = $d037
.const DTV_COLOR_BANK_DEFAULT = $1d800
// Selects memory bank for normal VIC color mode and lower data for high color modes. (bits 5:0)
// Memory address of VIC Graphics is GraphicsBank*$10000
// Selects memory bank for normal VIC color mode and lower data for high color modes. (bits 5:0)
// Memory address of VIC Graphics is GraphicsBank*$10000
.label DTV_GRAPHICS_VIC_BANK = $d03d
.const KEY_CRSR_RIGHT = 2
.const KEY_CRSR_DOWN = 7
@ -86,49 +86,49 @@
.const KEY_CTRL = $3a
.const KEY_SPACE = $3c
.const KEY_COMMODORE = $3d
// Left shift is pressed
// Left shift is pressed
.const KEY_MODIFIER_LSHIFT = 1
// Right shift is pressed
// Right shift is pressed
.const KEY_MODIFIER_RSHIFT = 2
// CTRL is pressed
// CTRL is pressed
.const KEY_MODIFIER_CTRL = 4
// Commodore is pressed
// Commodore is pressed
.const KEY_MODIFIER_COMMODORE = 8
// VIC Screens
// VIC Screens
.label VIC_SCREEN0 = $4000
.label VIC_SCREEN1 = $4400
.label VIC_SCREEN2 = $4800
.label VIC_SCREEN3 = $4c00
.label VIC_SCREEN4 = $5000
// VIC Charset from ROM
// VIC Charset from ROM
.label VIC_CHARSET_ROM = $5800
// VIC Bitmap
// VIC Bitmap
.label VIC_BITMAP = $6000
// 8BPP Chunky Bitmap (contains 8bpp pixels)
// 8BPP Chunky Bitmap (contains 8bpp pixels)
.const PLANE_8BPP_CHUNKY = $20000
// Plane with horisontal stripes
// Plane with horisontal stripes
.const PLANE_HORISONTAL = $30000
// Plane with vertical stripes
// Plane with vertical stripes
.const PLANE_VERTICAL = $32000
// Plane with horisontal stripes every 2 pixels
// Plane with horisontal stripes every 2 pixels
.const PLANE_HORISONTAL2 = $34000
// Plane with vertical stripes every 2 pixels
// Plane with vertical stripes every 2 pixels
.const PLANE_VERTICAL2 = $36000
// Plane with blank pixels
// Plane with blank pixels
.const PLANE_BLANK = $38000
// Plane with all pixels
// Plane with all pixels
.const PLANE_FULL = $3a000
// Plane with all pixels
// Plane with all pixels
.const PLANE_CHARSET8 = $3c000
// Screen containing the FORM
// Screen containing the FORM
.label FORM_SCREEN = $400
// Charset used for the FORM
// Charset used for the FORM
.label FORM_CHARSET = $1800
// Number of form fields
// Number of form fields
.const form_fields_cnt = $24
// The number of frames to use for a full blink cycle
// The number of frames to use for a full blink cycle
.const FORM_CURSOR_BLINK = $28
// Any shift is pressed
// Any shift is pressed
.const KEY_MODIFIER_SHIFT = KEY_MODIFIER_LSHIFT|KEY_MODIFIER_RSHIFT
.label form_ctrl_bmm = form_fields_val+1
.label form_ctrl_mcm = form_fields_val+2
@ -172,13 +172,13 @@
.label form_cursor_count = $e
main: {
sei
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
lda #PROCPORT_RAM_IO
sta PROCPORT
// Enable DTV extended modes
// Enable DTV extended modes
lda #DTV_FEATURE_ENABLE
sta DTV_FEATURE
jsr keyboard_init
@ -193,7 +193,7 @@ main: {
jsr gfx_mode
jmp b2
}
// Change graphics mode to show the selected graphics mode
// Change graphics mode to show the selected graphics mode
gfx_mode: {
.label _31 = $a
.label _33 = 3
@ -394,10 +394,10 @@ gfx_mode: {
sta DTV_PLANEB_MODULO_LO
lda #0
sta DTV_PLANEB_MODULO_HI
// VIC Graphics Bank
// VIC Graphics Bank
lda #3
sta CIA2_PORT_A_DDR
// Set VIC Bank bits to output - all others to input
// Set VIC Bank bits to output - all others to input
lda #3^VIC_SCREEN0/$4000
sta CIA2_PORT_A
lda form_vic_screen
@ -427,8 +427,8 @@ gfx_mode: {
lsr
lsr
ora _65
// Set VIC Bank
// VIC memory
// Set VIC Bank
// VIC memory
sta VIC_MEMORY
lda form_vic_cols
jsr get_vic_screen
@ -461,7 +461,7 @@ gfx_mode: {
lda cy
cmp #$19
bne b10
// Background colors
// Background colors
lda #0
sta BORDERCOL
lda form_vic_bg0_hi
@ -492,12 +492,12 @@ gfx_mode: {
asl
ora form_vic_bg3_lo
sta BGCOL4
// DTV Palette
// DTV Palette
lda form_dtv_palet
cmp #0
beq b18
ldy #0
// DTV Palette - Grey Tones
// DTV Palette - Grey Tones
b13:
tya
sta DTV_PALETTE,y
@ -513,7 +513,7 @@ gfx_mode: {
cmp #KEY_SPACE
bne b19
rts
// DTV Palette - default
// DTV Palette - default
b18:
ldy #0
b15:
@ -524,9 +524,9 @@ gfx_mode: {
bne b15
jmp b19
}
// Get the next event from the keyboard event buffer.
// Returns $ff if there is no event waiting. As all events are <$7f it is enough to examine bit 7 when determining if there is any event to process.
// The buffer is filled by keyboard_event_scan()
// Get the next event from the keyboard event buffer.
// Returns $ff if there is no event waiting. As all events are <$7f it is enough to examine bit 7 when determining if there is any event to process.
// The buffer is filled by keyboard_event_scan()
keyboard_event_get: {
lda keyboard_events_size
cmp #0
@ -540,10 +540,10 @@ keyboard_event_get: {
breturn:
rts
}
// Scans the entire matrix to determine which keys have been pressed/depressed.
// Generates keyboard events into the event buffer. Events can be read using keyboard_event_get().
// Handles debounce and only generates events when the status of a key changes.
// Also stores current status of modifiers in keyboard_modifiers.
// Scans the entire matrix to determine which keys have been pressed/depressed.
// Generates keyboard events into the event buffer. Events can be read using keyboard_event_get().
// Handles debounce and only generates events when the status of a key changes.
// Also stores current status of modifiers in keyboard_modifiers.
keyboard_event_scan: {
.label row_scan = $12
.label keycode = 8
@ -608,7 +608,7 @@ keyboard_event_scan: {
sta keyboard_modifiers
breturn:
rts
// Something has changed on the keyboard row - check each column
// Something has changed on the keyboard row - check each column
b6:
lda #0
sta col
@ -627,7 +627,7 @@ keyboard_event_scan: {
and keyboard_matrix_col_bitmask,y
cmp #0
beq b7
// Key pressed
// Key pressed
lda keycode
ldy keyboard_events_size
sta keyboard_events,y
@ -638,7 +638,7 @@ keyboard_event_scan: {
lda col
cmp #8
bne b4
// Store the current keyboard status for the row to debounce
// Store the current keyboard status for the row to debounce
lda row_scan
ldy row
sta keyboard_scan_values,y
@ -646,14 +646,14 @@ keyboard_event_scan: {
b7:
lda #$40
ora keycode
// Key released
// Key released
ldy keyboard_events_size
sta keyboard_events,y
inc keyboard_events_size
jmp b5
}
// Determine if a specific key is currently pressed based on the last keyboard_event_scan()
// Returns 0 is not pressed and non-0 if pressed
// Determine if a specific key is currently pressed based on the last keyboard_event_scan()
// Returns 0 is not pressed and non-0 if pressed
keyboard_event_pressed: {
.label row_bits = 8
.label keycode = 7
@ -671,11 +671,11 @@ keyboard_event_pressed: {
and row_bits
rts
}
// Read a single row of the keyboard matrix
// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs.
// Returns the keys pressed on the row as bits according to the C64 key matrix.
// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write
// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader.
// Read a single row of the keyboard matrix
// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs.
// Returns the keys pressed on the row as bits according to the C64 key matrix.
// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write
// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader.
keyboard_matrix_read: {
tay
lda keyboard_matrix_row_bitmask,y
@ -684,7 +684,7 @@ keyboard_matrix_read: {
eor #$ff
rts
}
// Get the VIC screen address from the screen index
// Get the VIC screen address from the screen index
get_vic_screen: {
.label return = 3
cmp #0
@ -728,7 +728,7 @@ get_vic_screen: {
breturn:
rts
}
// Get the VIC charset/bitmap address from the index
// Get the VIC charset/bitmap address from the index
get_vic_charset: {
.label return = 3
cmp #0
@ -748,7 +748,7 @@ get_vic_charset: {
breturn:
rts
}
// Get plane address from a plane index (from the form)
// Get plane address from a plane index (from the form)
get_plane: {
.label return = $a
cmp #0
@ -942,7 +942,7 @@ get_plane: {
breturn:
rts
}
// Show the form - and let the user change values
// Show the form - and let the user change values
form_mode: {
.label preset_current = $f
lda #<COLS
@ -971,33 +971,33 @@ form_mode: {
jsr form_render_values
lda form_fields_val
jsr render_preset_name
// DTV Graphics Bank
// DTV Graphics Bank
lda #($ffffffff&FORM_CHARSET)/$10000
sta DTV_GRAPHICS_VIC_BANK
// DTV Color Bank
// DTV Color Bank
lda #DTV_COLOR_BANK_DEFAULT/$400
sta DTV_COLOR_BANK_LO
lda #0
sta DTV_COLOR_BANK_HI
// VIC Graphics Bank
// VIC Graphics Bank
lda #3
sta CIA2_PORT_A_DDR
// Set VIC Bank bits to output - all others to input
// Set VIC Bank bits to output - all others to input
lda #3^FORM_CHARSET/$4000
sta CIA2_PORT_A
// Set VIC Bank
// DTV Graphics Mode
// Set VIC Bank
// DTV Graphics Mode
lda #0
sta DTV_CONTROL
// VIC Graphics Mode
// VIC Graphics Mode
lda #VIC_DEN|VIC_RSEL|3
sta VIC_CONTROL
lda #VIC_CSEL
sta VIC_CONTROL2
// VIC Memory Pointers
// VIC Memory Pointers
lda #(FORM_SCREEN&$3fff)/$40|(FORM_CHARSET&$3fff)/$400
sta VIC_MEMORY
// DTV Plane A to FORM_SCREEN also
// DTV Plane A to FORM_SCREEN also
lda #<FORM_SCREEN
sta DTV_PLANEA_START_LO
lda #>FORM_SCREEN
@ -1005,20 +1005,20 @@ form_mode: {
lda #0
sta DTV_PLANEA_START_HI
tay
// DTV Palette - default
// DTV Palette - default
b1:
lda DTV_PALETTE_DEFAULT,y
sta DTV_PALETTE,y
iny
cpy #$10
bne b1
// Screen colors
// Screen colors
lda #0
sta BGCOL
sta BORDERCOL
lda form_fields_val
sta preset_current
// Let the user change values in the form
// Let the user change values in the form
b5:
lda RASTER
cmp #$ff
@ -1040,8 +1040,8 @@ form_mode: {
jsr render_preset_name
jmp b5
}
// Render form preset name in the form
// idx is the ID of the preset
// Render form preset name in the form
// idx is the ID of the preset
render_preset_name: {
.label name = 3
cmp #0
@ -1152,7 +1152,7 @@ render_preset_name: {
name_10: .text "8bpp Pixel Cell @"
name_11: .text "Standard Charset @"
}
// Print a string at a specific screen position
// Print a string at a specific screen position
print_str_at: {
.label at = 5
.label str = 3
@ -1180,7 +1180,7 @@ print_str_at: {
!:
jmp b1
}
// Render all form values from the form_fields_val array
// Render all form values from the form_fields_val array
form_render_values: {
.label field = 3
.label idx = 2
@ -1200,8 +1200,8 @@ form_render_values: {
bcc b1
rts
}
// Get the screen address of a form field
// field_idx is the index of the field to get the screen address for
// Get the screen address of a form field
// field_idx is the index of the field to get the screen address for
form_field_ptr: {
.label return = 3
.label field_idx = 2
@ -1223,8 +1223,8 @@ form_field_ptr: {
sta return+1
rts
}
// Apply a form value preset to the form values
// idx is the ID of the preset
// Apply a form value preset to the form values
// idx is the ID of the preset
apply_preset: {
.label preset = 3
cmp #0
@ -1316,7 +1316,7 @@ apply_preset: {
sta preset+1
b22:
ldy #0
// Copy preset values into the fields
// Copy preset values into the fields
b23:
lda (preset),y
sta form_fields_val,y
@ -1325,8 +1325,8 @@ apply_preset: {
bne b23
rts
}
// 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
// Reads keyboard and allows the user to navigate and change the fields of the form
// Returns 0 if space is not pressed, non-0 if space is pressed
form_control: {
.label field = 3
stx form_field_ptr.field_idx
@ -1359,7 +1359,7 @@ form_control: {
lda #$7f
ldy #0
and (field),y
// Unblink the cursor
// Unblink the cursor
sta (field),y
lda #KEY_MODIFIER_SHIFT
and keyboard_modifiers
@ -1395,7 +1395,7 @@ form_control: {
lda form_fields_max,x
sta form_fields_val,x
b12:
// Render field value
// Render field value
lda form_fields_val,x
tay
lda print_hextab,y
@ -1427,8 +1427,8 @@ form_control: {
sta (field),y
jmp b3
}
// Set the screen to use for the form.
// screen is the start address of the screen to use
// Set the screen to use for the form.
// screen is the start address of the screen to use
form_set_screen: {
.label line = 3
ldy #0
@ -1453,8 +1453,8 @@ form_set_screen: {
bne b1
rts
}
// Print a number of zero-terminated strings, each followed by a newline.
// The sequence of lines is terminated by another zero.
// Print a number of zero-terminated strings, each followed by a newline.
// The sequence of lines is terminated by another zero.
print_str_lines: {
.label str = 3
lda print_set_screen.screen
@ -1492,7 +1492,7 @@ print_str_lines: {
sta print_char_cursor+1
jmp b1
}
// Print a newline
// Print a newline
print_ln: {
b1:
lda print_line_cursor
@ -1512,7 +1512,7 @@ print_ln: {
!:
rts
}
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label _0 = 5
.label sc = 3
@ -1543,12 +1543,12 @@ print_cls: {
bne b1
rts
}
// Set the screen to print on. Also resets current line/char cursor.
// Set the screen to print on. Also resets current line/char cursor.
print_set_screen: {
.label screen = $10
rts
}
// Initialize the different graphics in the memory
// Initialize the different graphics in the memory
gfx_init: {
jsr gfx_init_screen0
jsr gfx_init_screen1
@ -1567,7 +1567,7 @@ gfx_init: {
jsr gfx_init_plane_full
rts
}
// Initialize Plane with all pixels
// Initialize Plane with all pixels
gfx_init_plane_full: {
lda #$ff
sta gfx_init_plane_fill.fill
@ -1582,7 +1582,7 @@ gfx_init_plane_full: {
jsr gfx_init_plane_fill
rts
}
// Initialize 320*200 1bpp pixel ($2000) plane with identical bytes
// Initialize 320*200 1bpp pixel ($2000) plane with identical bytes
gfx_init_plane_fill: {
.label _0 = $13
.label _1 = 3
@ -1658,11 +1658,11 @@ gfx_init_plane_fill: {
jsr dtvSetCpuBankSegment1
rts
}
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
dtvSetCpuBankSegment1: {
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
.label cpuBank = $ff
sta cpuBank
.byte $32, $dd
@ -1670,7 +1670,7 @@ dtvSetCpuBankSegment1: {
.byte $32, $00
rts
}
// Initialize Plane with blank pixels
// Initialize Plane with blank pixels
gfx_init_plane_blank: {
lda #0
sta gfx_init_plane_fill.fill
@ -1685,7 +1685,7 @@ gfx_init_plane_blank: {
jsr gfx_init_plane_fill
rts
}
// Initialize Plane with Vertical Stripes every 2 pixels
// Initialize Plane with Vertical Stripes every 2 pixels
gfx_init_plane_vertical2: {
lda #$1b
sta gfx_init_plane_fill.fill
@ -1700,7 +1700,7 @@ gfx_init_plane_vertical2: {
jsr gfx_init_plane_fill
rts
}
// Initialize Plane with Horizontal Stripes every 2 pixels
// Initialize Plane with Horizontal Stripes every 2 pixels
gfx_init_plane_horisontal2: {
.const gfxbCpuBank = PLANE_HORISONTAL2/$4000
.label gfxa = 3
@ -1739,7 +1739,7 @@ gfx_init_plane_horisontal2: {
rts
row_bitmask: .byte 0, $55, $aa, $ff
}
// Initialize Plane with Vertical Stripes
// Initialize Plane with Vertical Stripes
gfx_init_plane_vertical: {
.const gfxbCpuBank = PLANE_VERTICAL/$4000
.label gfxb = 3
@ -1773,7 +1773,7 @@ gfx_init_plane_vertical: {
jsr dtvSetCpuBankSegment1
rts
}
// Initialize Plane with Horizontal Stripes
// Initialize Plane with Horizontal Stripes
gfx_init_plane_horisontal: {
.const gfxbCpuBank = PLANE_HORISONTAL/$4000
.label gfxa = 3
@ -1821,7 +1821,7 @@ gfx_init_plane_horisontal: {
!:
jmp b4
}
// Initialize Plane with 8bpp charset
// Initialize Plane with 8bpp charset
gfx_init_plane_charset8: {
.const gfxbCpuBank = PLANE_CHARSET8/$4000
.label bits = 8
@ -1892,7 +1892,7 @@ gfx_init_plane_charset8: {
jsr dtvSetCpuBankSegment1
rts
}
// Initialize 8BPP Chunky Bitmap (contains 8bpp pixels)
// Initialize 8BPP Chunky Bitmap (contains 8bpp pixels)
gfx_init_plane_8bppchunky: {
.label _6 = $10
.label gfxb = 5
@ -1958,7 +1958,7 @@ gfx_init_plane_8bppchunky: {
jsr dtvSetCpuBankSegment1
rts
}
// Initialize VIC bitmap
// Initialize VIC bitmap
gfx_init_vic_bitmap: {
.const lines_cnt = 9
.label l = 2
@ -1985,7 +1985,7 @@ gfx_init_vic_bitmap: {
lines_x: .byte 0, $ff, $ff, 0, 0, $80, $ff, $80, 0, $80
lines_y: .byte 0, 0, $c7, $c7, 0, 0, $64, $c7, $64, 0
}
// Draw a line on the bitmap
// Draw a line on the bitmap
bitmap_line: {
.label xd = 8
.label yd = 7
@ -2248,7 +2248,7 @@ bitmap_line_ydxd: {
bne b1
rts
}
// Clear all graphics on the bitmap
// Clear all graphics on the bitmap
bitmap_clear: {
.label bitmap = 3
.label y = 2
@ -2278,7 +2278,7 @@ bitmap_clear: {
bne b1
rts
}
// Initialize the bitmap plotter tables for a specific bitmap
// Initialize the bitmap plotter tables for a specific bitmap
bitmap_init: {
.label _6 = 2
.label yoffs = 3
@ -2373,7 +2373,7 @@ gfx_init_charset: {
sta PROCPORT
rts
}
// Initialize VIC screen 4 - all chars are 00
// Initialize VIC screen 4 - all chars are 00
gfx_init_screen4: {
.label ch = 3
.label cy = 2
@ -2402,7 +2402,7 @@ gfx_init_screen4: {
bne b1
rts
}
// Initialize VIC screen 3 ( value is %00xx00yy where xx is xpos and yy is ypos
// Initialize VIC screen 3 ( value is %00xx00yy where xx is xpos and yy is ypos
gfx_init_screen3: {
.label _1 = 7
.label ch = 3
@ -2441,7 +2441,7 @@ gfx_init_screen3: {
bne b1
rts
}
// Initialize VIC screen 2 ( value is %ccccrrrr where cccc is (x+y mod $f) and rrrr is %1111-%cccc)
// Initialize VIC screen 2 ( value is %ccccrrrr where cccc is (x+y mod $f) and rrrr is %1111-%cccc)
gfx_init_screen2: {
.label col2 = 7
.label ch = 3
@ -2486,7 +2486,7 @@ gfx_init_screen2: {
bne b1
rts
}
// Initialize VIC screen 1 ( value is %0000cccc where cccc is (x+y mod $f))
// Initialize VIC screen 1 ( value is %0000cccc where cccc is (x+y mod $f))
gfx_init_screen1: {
.label ch = 3
.label cy = 2
@ -2518,7 +2518,7 @@ gfx_init_screen1: {
bne b1
rts
}
// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos)
// Initialize VIC screen 0 ( value is %yyyyxxxx where yyyy is ypos and xxxx is xpos)
gfx_init_screen0: {
.label _1 = 7
.label ch = 3
@ -2557,65 +2557,65 @@ gfx_init_screen0: {
bne b1
rts
}
// Initialize keyboard reading by setting CIA#$ Data Direction Registers
// Initialize keyboard reading by setting CIA#$ Data Direction Registers
keyboard_init: {
// Keyboard Matrix Columns Write Mode
// Keyboard Matrix Columns Write Mode
lda #$ff
sta CIA1_PORT_A_DDR
// Keyboard Matrix Columns Read Mode
// Keyboard Matrix Columns Read Mode
lda #0
sta CIA1_PORT_B_DDR
rts
}
// Default vallues for the palette
// 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
print_hextab: .text "0123456789abcdef"
// Keyboard row bitmask as expected by CIA#1 Port A when reading a specific keyboard matrix row (rows are numbered 0-7)
// Keyboard row bitmask as expected by CIA#1 Port A when reading a specific keyboard matrix row (rows are numbered 0-7)
keyboard_matrix_row_bitmask: .byte $fe, $fd, $fb, $f7, $ef, $df, $bf, $7f
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
keyboard_matrix_col_bitmask: .byte 1, 2, 4, 8, $10, $20, $40, $80
// Keyboard event buffer. Contains keycodes for key presses/releases. Presses are represented by the keycode. Releases by keycode | $40. The buffer is filled by keyboard_scan()
// Keyboard event buffer. Contains keycodes for key presses/releases. Presses are represented by the keycode. Releases by keycode | $40. The buffer is filled by keyboard_scan()
keyboard_events: .fill 8, 0
// The values scanned values for each row. Set by keyboard_scan() and used by keyboard_get_event()
// The values scanned values for each row. Set by keyboard_scan() and used by keyboard_get_event()
keyboard_scan_values: .fill 8, 0
// Tables for the plotter - initialized by calling bitmap_draw_init();
// Tables for the plotter - initialized by calling bitmap_draw_init();
bitmap_plot_xlo: .fill $100, 0
bitmap_plot_xhi: .fill $100, 0
bitmap_plot_ylo: .fill $100, 0
bitmap_plot_yhi: .fill $100, 0
bitmap_plot_bit: .fill $100, 0
// Form fields x/y-positions
// Form fields x/y-positions
form_fields_x: .byte 8, $c, $c, $c, $c, $c, $c, $c, $c, $c, $19, $18, $19, $18, $19, $18, $19, $19, $18, $19, $18, $19, $18, $19, $25, $25, $25, $25, $24, $25, $24, $25, $24, $25, $24, $25
form_fields_y: .byte 2, 5, 6, 7, 8, 9, $a, $b, $c, $d, 5, 6, 6, 7, 7, 8, 8, $b, $c, $c, $d, $d, $e, $e, 5, 6, 7, $a, $b, $b, $c, $c, $d, $d, $e, $e
// Form field max values (all values are in the interval 0..max)
// Form field max values (all values are in the interval 0..max)
form_fields_max: .byte $a, 1, 1, 1, 1, 1, 1, 1, 1, 1, $d, $f, $f, $f, $f, $f, $f, $d, $f, $f, $f, $f, $f, $f, 3, 1, 4, 1, $f, $f, $f, $f, $f, $f, $f, $f
// Form fields values
// Form fields values
form_fields_val: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
// Preset: Standard Char Mode
// Preset: Standard Char Mode
preset_stdchar: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
// Preset: Extended Color Char Mode
// Preset: Extended Color Char Mode
preset_ecmchar: .byte 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 5, 0, 6
// Preset: Standard Bitmap
// Preset: Standard Bitmap
preset_stdbm: .byte 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
// Preset: MC Bitmap
// Preset: MC Bitmap
preset_mcbm: .byte 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0
// Preset: Hicolor Standard Char Mode
// Preset: Hicolor Standard Char Mode
preset_hi_stdchar: .byte 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0
// Preset: Hicolor Extended Color Char Mode
// Preset: Hicolor Extended Color Char Mode
preset_hi_ecmchar: .byte 5, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 6, 8, 9, $c, $c
// Preset: Two plane mode
// Preset: Two plane mode
preset_twoplane: .byte 6, 1, 0, 1, 1, 1, 0, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 7, 0, $d, 4, 0, 0, 0, 0
// Preset: Chunky 8bpp
// Preset: Chunky 8bpp
preset_chunky: .byte 7, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0
// Preset: Sixs FREDs mode
// Preset: Sixs FREDs mode
preset_sixsfred: .byte 8, 1, 1, 1, 1, 1, 0, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, $a, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
// Preset: Sixs FREDs 2 mode
// Preset: Sixs FREDs 2 mode
preset_sixsfred2: .byte 9, 1, 1, 1, 0, 1, 0, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, $a, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0
// Preset: 8bpp Pixel Cell
// Preset: 8bpp Pixel Cell
preset_8bpppixelcell: .byte $a, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, $b, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0
// Table with addresses of the y-lines of the form. The first line contains the address of the form screen.
// Table with addresses of the y-lines of the form. The first line contains the address of the form screen.
form_line_lo: .fill $19, 0
form_line_hi: .fill $19, 0
// Charset ROM
// Charset ROM
FORM_TEXT: .text " C64 DTV Graphics Mode Explorer @"+" @"+" PRESET 0 Standard Charset @"+" @"+" CONTROL PLANE A VIC II @"+" bmm 0 pattern p0 screen s0 @"+" mcm 0 start 00 gfx g0 @"+" ecm 0 step 00 colors c0 @"+" hicolor 0 modulo 00 @"+" linear 0 COLORS @"+" color off 0 PLANE B palet 0 @"+" chunky 0 pattern p0 bgcol0 00 @"+" border off 0 start 00 bgcol1 00 @"+" overscan 0 step 00 bgcol2 00 @"+" modulo 00 bgcol3 00 @"+"@"
FORM_COLS: .text "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@"+" @"+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@"+" @"+" nnnnnnnnnnnn mmmmmmmmmm ooooooooo @"+" nnnnnnnnnnnn mmmmmmmmmm ooooooooo @"+" nnnnnnnnnnnn mmmmmmmmmm ooooooooo @"+" nnnnnnnnnnnn mmmmmmmmmm ooooooooo @"+" nnnnnnnnnnnn mmmmmmmmmm @"+" nnnnnnnnnnnn jjjjjjjjj @"+" nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @"+" nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @"+" nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @"+" nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @"+" nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @"+" nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @"+"@"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
// Multiple calls with different (constant?) parameters should yield different values at runtime
// Currently the same constant parameter is passed on every call.
// Reason: Multiple versioned parameter constants x0#0, x0#1 are only output as a single constant in the ASM .const x0 = 0
// Multiple calls with different (constant?) parameters should yield different values at runtime
// Currently the same constant parameter is passed on every call.
// Reason: Multiple versioned parameter constants x0#0, x0#1 are only output as a single constant in the ASM .const x0 = 0
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -228,9 +228,9 @@ Allocated zp ZP_WORD:4 [ screen#10 screen#14 screen#11 ]
INITIAL ASM
//SEG0 File Comments
// Multiple calls with different (constant?) parameters should yield different values at runtime
// Currently the same constant parameter is passed on every call.
// Reason: Multiple versioned parameter constants x0#0, x0#1 are only output as a single constant in the ASM .const x0 = 0
// Multiple calls with different (constant?) parameters should yield different values at runtime
// Currently the same constant parameter is passed on every call.
// Reason: Multiple versioned parameter constants x0#0, x0#1 are only output as a single constant in the ASM .const x0 = 0
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -349,9 +349,9 @@ Allocated (was zp ZP_WORD:4) zp ZP_WORD:3 [ screen#10 screen#14 screen#11 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Multiple calls with different (constant?) parameters should yield different values at runtime
// Currently the same constant parameter is passed on every call.
// Reason: Multiple versioned parameter constants x0#0, x0#1 are only output as a single constant in the ASM .const x0 = 0
// Multiple calls with different (constant?) parameters should yield different values at runtime
// Currently the same constant parameter is passed on every call.
// Reason: Multiple versioned parameter constants x0#0, x0#1 are only output as a single constant in the ASM .const x0 = 0
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -504,9 +504,9 @@ FINAL ASSEMBLER
Score: 348
//SEG0 File Comments
// Multiple calls with different (constant?) parameters should yield different values at runtime
// Currently the same constant parameter is passed on every call.
// Reason: Multiple versioned parameter constants x0#0, x0#1 are only output as a single constant in the ASM .const x0 = 0
// Multiple calls with different (constant?) parameters should yield different values at runtime
// Currently the same constant parameter is passed on every call.
// Reason: Multiple versioned parameter constants x0#0, x0#1 are only output as a single constant in the ASM .const x0 = 0
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -1,4 +1,4 @@
// Example of NOP-casting a dereferenced signed byte to a byte
// Example of NOP-casting a dereferenced signed byte to a byte
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -139,7 +139,7 @@ Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
INITIAL ASM
//SEG0 File Comments
// Example of NOP-casting a dereferenced signed byte to a byte
// Example of NOP-casting a dereferenced signed byte to a byte
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -210,7 +210,7 @@ Uplifting [] best 288 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Example of NOP-casting a dereferenced signed byte to a byte
// Example of NOP-casting a dereferenced signed byte to a byte
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -309,7 +309,7 @@ FINAL ASSEMBLER
Score: 186
//SEG0 File Comments
// Example of NOP-casting a dereferenced signed byte to a byte
// Example of NOP-casting a dereferenced signed byte to a byte
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -1,4 +1,4 @@
// Tests that casting inside constants in the output handles precedence between cast and + correctly - should generate the following KA-expression ($ff & sumw>>1)+1
// Tests that casting inside constants in the output handles precedence between cast and + correctly - should generate the following KA-expression ($ff & sumw>>1)+1
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -170,7 +170,7 @@ Complete equivalence classes
INITIAL ASM
//SEG0 File Comments
// Tests that casting inside constants in the output handles precedence between cast and + correctly - should generate the following KA-expression ($ff & sumw>>1)+1
// Tests that casting inside constants in the output handles precedence between cast and + correctly - should generate the following KA-expression ($ff & sumw>>1)+1
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -245,7 +245,7 @@ Uplifting [] best 61 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Tests that casting inside constants in the output handles precedence between cast and + correctly - should generate the following KA-expression ($ff & sumw>>1)+1
// Tests that casting inside constants in the output handles precedence between cast and + correctly - should generate the following KA-expression ($ff & sumw>>1)+1
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -354,7 +354,7 @@ FINAL ASSEMBLER
Score: 43
//SEG0 File Comments
// Tests that casting inside constants in the output handles precedence between cast and + correctly - should generate the following KA-expression ($ff & sumw>>1)+1
// Tests that casting inside constants in the output handles precedence between cast and + correctly - should generate the following KA-expression ($ff & sumw>>1)+1
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -1,4 +1,4 @@
// Draws a chess board in the upper left corner of the screen
// Draws a chess board in the upper left corner of the screen
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -247,7 +247,7 @@ Allocated zp ZP_BYTE:8 [ main::color#3 main::color#5 main::color#2 main::color#1
INITIAL ASM
//SEG0 File Comments
// Draws a chess board in the upper left corner of the screen
// Draws a chess board in the upper left corner of the screen
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -405,7 +405,7 @@ Uplifting [main] best 4863 combination zp ZP_BYTE:6 [ main::row#4 main::row#1 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Draws a chess board in the upper left corner of the screen
// Draws a chess board in the upper left corner of the screen
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -593,7 +593,7 @@ FINAL ASSEMBLER
Score: 3861
//SEG0 File Comments
// Draws a chess board in the upper left corner of the screen
// Draws a chess board in the upper left corner of the screen
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -27,7 +27,7 @@ irq: {
clc
adc irq_raster_next
sta irq_raster_next
// Setup next interrupt
// Setup next interrupt
tax
txa
and #7

View File

@ -318,7 +318,7 @@ irq: {
adc irq_raster_next
sta irq_raster_next_1
//SEG19 [9] (byte) irq::raster_next#0 ← (byte) irq_raster_next#1 -- vbuz1=vbuz2
// Setup next interrupt
// Setup next interrupt
lda irq_raster_next_1
sta raster_next
//SEG20 [10] (byte~) irq::$0 ← (byte) irq::raster_next#0 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuz1=vbuz2_band_vbuc1
@ -460,7 +460,7 @@ irq: {
adc irq_raster_next
sta irq_raster_next
//SEG19 [9] (byte) irq::raster_next#0 ← (byte) irq_raster_next#1 -- vbuxx=vbuz1
// Setup next interrupt
// Setup next interrupt
ldx irq_raster_next
//SEG20 [10] (byte~) irq::$0 ← (byte) irq::raster_next#0 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuaa=vbuxx_band_vbuc1
txa
@ -607,7 +607,7 @@ irq: {
adc irq_raster_next
sta irq_raster_next
//SEG19 [9] (byte) irq::raster_next#0 ← (byte) irq_raster_next#1 -- vbuxx=vbuz1
// Setup next interrupt
// Setup next interrupt
tax
//SEG20 [10] (byte~) irq::$0 ← (byte) irq::raster_next#0 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuaa=vbuxx_band_vbuc1
txa

View File

@ -1,15 +1,15 @@
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
// Processor port data direction register
// Processor port data direction register
.label PROCPORT_DDR = 0
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
.const PROCPORT_DDR_MEMORY_MASK = 7
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// RAM in $A000, $E000 I/O in $D000
// RAM in $A000, $E000 I/O in $D000
.const PROCPORT_RAM_IO = $35
// The offset of the sprite pointers from the screen start address
// The offset of the sprite pointers from the screen start address
.const SPRITE_PTRS = $3f8
.label SPRITES_XPOS = $d000
.label SPRITES_YPOS = $d001
@ -21,44 +21,44 @@
.label SPRITES_COLS = $d027
.label VIC_CONTROL = $d011
.label D018 = $d018
// VIC II IRQ Status Register
// VIC II IRQ Status Register
.label IRQ_STATUS = $d019
// VIC II IRQ Enable Register
// VIC II IRQ Enable Register
.label IRQ_ENABLE = $d01a
// Bits for the IRQ Status/Enable Registers
// Bits for the IRQ Status/Enable Registers
.const IRQ_RASTER = 1
// CIA#1 Interrupt Status & Control Register
// CIA#1 Interrupt Status & Control Register
.label CIA1_INTERRUPT = $dc0d
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
.const CIA_INTERRUPT_CLEAR = $7f
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
.label CIA2_PORT_A = $dd00
// CIA #2 Port A data direction register.
// CIA #2 Port A data direction register.
.label CIA2_PORT_A_DDR = $dd02
// The vector used when the HARDWARE serves IRQ interrupts
// The vector used when the HARDWARE serves IRQ interrupts
.label HARDWARE_IRQ = $fffe
// The colors of the C64
// The colors of the C64
.const BLACK = 0
// Address of the first screen
// Address of the first screen
.label PLAYFIELD_SCREEN_1 = $400
// Address of the second screen
// Address of the second screen
.label PLAYFIELD_SCREEN_2 = $2c00
// Address of the sprites covering the playfield
// Address of the sprites covering the playfield
.label PLAYFIELD_SPRITES = $2000
// Address of the charset
// Address of the charset
.label PLAYFIELD_CHARSET = $2800
// The size of the playfield
// The size of the playfield
.const PLAYFIELD_LINES = $16
.const PLAYFIELD_COLS = $a
// The Y-position of the first sprite row
// The Y-position of the first sprite row
.const SPRITES_FIRST_YPOS = $31
.label SIN = $1400
.label SIN_SPRITE = $2800
// Screen Sprite pointers on screen 1
// Screen Sprite pointers on screen 1
.label PLAYFIELD_SPRITE_PTRS_1 = PLAYFIELD_SCREEN_1+SPRITE_PTRS
// Screen Sprite pointers on screen 2
// Screen Sprite pointers on screen 2
.label PLAYFIELD_SPRITE_PTRS_2 = PLAYFIELD_SCREEN_2+SPRITE_PTRS
// The line of the first IRQ
// The line of the first IRQ
.const IRQ_RASTER_FIRST = SPRITES_FIRST_YPOS+$13
.const toSpritePtr1_return = PLAYFIELD_SPRITES>>6
.label render_screen_showing = 5
@ -68,19 +68,19 @@
.label irq_cnt = 8
.label sin_idx = 2
bbegin:
// The screen currently being showed to the user. $00 for screen 1 / $40 for screen 2.
// The screen currently being showed to the user. $00 for screen 1 / $40 for screen 2.
lda #0
sta render_screen_showing
// The raster line of the next IRQ
// The raster line of the next IRQ
lda #IRQ_RASTER_FIRST
sta irq_raster_next
// Y-pos of the sprites on the next IRQ
// Y-pos of the sprites on the next IRQ
lda #SPRITES_FIRST_YPOS+$15
sta irq_sprite_ypos
// Index of the sprites to show on the next IRQ
// Index of the sprites to show on the next IRQ
lda #toSpritePtr1_return+3
sta irq_sprite_ptr
// Counting the 10 IRQs
// Counting the 10 IRQs
lda #0
sta irq_cnt
jsr main
@ -163,31 +163,31 @@ loop: {
inc sin_idx
jmp b4
}
// Setup the IRQ
// Setup the IRQ
sprites_irq_init: {
sei
// Acknowledge any IRQ and setup the next one
// Acknowledge any IRQ and setup the next one
lda #IRQ_RASTER
sta IRQ_STATUS
lda CIA1_INTERRUPT
// Disable kernal & basic
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
lda #PROCPORT_RAM_IO
sta PROCPORT
// Disable CIA 1 Timer IRQ
// Disable CIA 1 Timer IRQ
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
// Set raster line
// Set raster line
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
lda #IRQ_RASTER_FIRST
sta RASTER
// Enable Raster Interrupt
// Enable Raster Interrupt
lda #IRQ_RASTER
sta IRQ_ENABLE
// Set the IRQ routine
// Set the IRQ routine
lda #<sprites_irq
sta HARDWARE_IRQ
lda #>sprites_irq
@ -195,7 +195,7 @@ sprites_irq_init: {
cli
rts
}
// Setup the sprites
// Setup the sprites
sprites_init: {
.label xpos = 2
lda #$f
@ -224,18 +224,18 @@ sprites_init: {
bne b1
rts
}
// Raster Interrupt Routine - sets up the sprites covering the playfield
// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST
// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers
// Raster Interrupt Routine - sets up the sprites covering the playfield
// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST
// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers
sprites_irq: {
.const toSpritePtr2_return = PLAYFIELD_SPRITES>>6
.label raster_sprite_gfx_modify = $a
sta rega+1
stx regx+1
// (*BGCOL)++;
// Clear decimal flag (because it is used by the score algorithm)
//(*BGCOL)++;
// Clear decimal flag (because it is used by the score algorithm)
cld
// Place the sprites
// Place the sprites
lda irq_sprite_ypos
sta SPRITES_YPOS
sta SPRITES_YPOS+2
@ -243,7 +243,7 @@ sprites_irq: {
sta SPRITES_YPOS+6
ldx irq_raster_next
inx
// Wait for the y-position before changing sprite pointers
// Wait for the y-position before changing sprite pointers
stx raster_sprite_gfx_modify
b1:
lda RASTER
@ -282,10 +282,10 @@ sprites_irq: {
adc irq_sprite_ptr
sta irq_sprite_ptr
b7:
// Setup next interrupt
// Setup next interrupt
lda irq_raster_next
sta RASTER
// Acknowledge the IRQ and setup the next one
// Acknowledge the IRQ and setup the next one
lda #IRQ_RASTER
sta IRQ_STATUS
rega:

View File

@ -2191,15 +2191,15 @@ INITIAL ASM
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// Processor port data direction register
// Processor port data direction register
.label PROCPORT_DDR = 0
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
.const PROCPORT_DDR_MEMORY_MASK = 7
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// RAM in $A000, $E000 I/O in $D000
// RAM in $A000, $E000 I/O in $D000
.const PROCPORT_RAM_IO = $35
// The offset of the sprite pointers from the screen start address
// The offset of the sprite pointers from the screen start address
.const SPRITE_PTRS = $3f8
.label SPRITES_XPOS = $d000
.label SPRITES_YPOS = $d001
@ -2211,44 +2211,44 @@ INITIAL ASM
.label SPRITES_COLS = $d027
.label VIC_CONTROL = $d011
.label D018 = $d018
// VIC II IRQ Status Register
// VIC II IRQ Status Register
.label IRQ_STATUS = $d019
// VIC II IRQ Enable Register
// VIC II IRQ Enable Register
.label IRQ_ENABLE = $d01a
// Bits for the IRQ Status/Enable Registers
// Bits for the IRQ Status/Enable Registers
.const IRQ_RASTER = 1
// CIA#1 Interrupt Status & Control Register
// CIA#1 Interrupt Status & Control Register
.label CIA1_INTERRUPT = $dc0d
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
.const CIA_INTERRUPT_CLEAR = $7f
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
.label CIA2_PORT_A = $dd00
// CIA #2 Port A data direction register.
// CIA #2 Port A data direction register.
.label CIA2_PORT_A_DDR = $dd02
// The vector used when the HARDWARE serves IRQ interrupts
// The vector used when the HARDWARE serves IRQ interrupts
.label HARDWARE_IRQ = $fffe
// The colors of the C64
// The colors of the C64
.const BLACK = 0
// Address of the first screen
// Address of the first screen
.label PLAYFIELD_SCREEN_1 = $400
// Address of the second screen
// Address of the second screen
.label PLAYFIELD_SCREEN_2 = $2c00
// Address of the sprites covering the playfield
// Address of the sprites covering the playfield
.label PLAYFIELD_SPRITES = $2000
// Address of the charset
// Address of the charset
.label PLAYFIELD_CHARSET = $2800
// The size of the playfield
// The size of the playfield
.const PLAYFIELD_LINES = $16
.const PLAYFIELD_COLS = $a
// The Y-position of the first sprite row
// The Y-position of the first sprite row
.const SPRITES_FIRST_YPOS = $31
.label SIN = $1400
.label SIN_SPRITE = $2800
// Screen Sprite pointers on screen 1
// Screen Sprite pointers on screen 1
.label PLAYFIELD_SPRITE_PTRS_1 = PLAYFIELD_SCREEN_1+SPRITE_PTRS
// Screen Sprite pointers on screen 2
// Screen Sprite pointers on screen 2
.label PLAYFIELD_SPRITE_PTRS_2 = PLAYFIELD_SCREEN_2+SPRITE_PTRS
// The line of the first IRQ
// The line of the first IRQ
.const IRQ_RASTER_FIRST = SPRITES_FIRST_YPOS+$13
.const toSpritePtr1_return = PLAYFIELD_SPRITES>>6
.label render_screen_showing = $b
@ -2275,7 +2275,7 @@ bbegin:
//SEG4 @4
b4:
//SEG5 [1] (byte) render_screen_showing#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
// The screen currently being showed to the user. $00 for screen 1 / $40 for screen 2.
// The screen currently being showed to the user. $00 for screen 1 / $40 for screen 2.
lda #0
sta render_screen_showing
//SEG6 kickasm(location (const byte*) PLAYFIELD_SPRITES#0) {{ .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++) { .for (var y=0;y<21; y++) { .var gfx_y = sprite_gfx_y + mod(2100+y-sprite_gfx_y,21) .for (var c=0; c<3; c++) { .byte sprites.getSinglecolorByte(sx*3+c,gfx_y) } } .byte 0 } } }}
@ -2283,11 +2283,11 @@ b4:
//SEG7 @5
b5:
//SEG8 [3] (byte) irq_raster_next#0 ← (const byte) IRQ_RASTER_FIRST#0 -- vbuz1=vbuc1
// The raster line of the next IRQ
// The raster line of the next IRQ
lda #IRQ_RASTER_FIRST
sta irq_raster_next
//SEG9 [4] (byte) irq_sprite_ypos#0 ← (const byte) SPRITES_FIRST_YPOS#0+(byte/signed byte/word/signed word/dword/signed dword) 21 -- vbuz1=vbuc1
// Y-pos of the sprites on the next IRQ
// Y-pos of the sprites on the next IRQ
lda #SPRITES_FIRST_YPOS+$15
sta irq_sprite_ypos
//SEG10 [5] phi from @5 to toSpritePtr1 [phi:@5->toSpritePtr1]
@ -2299,11 +2299,11 @@ toSpritePtr1:
//SEG12 @10
b10:
//SEG13 [6] (byte) irq_sprite_ptr#0 ← (const byte) toSpritePtr1_return#0+(byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuz1=vbuc1
// Index of the sprites to show on the next IRQ
// Index of the sprites to show on the next IRQ
lda #toSpritePtr1_return+3
sta irq_sprite_ptr
//SEG14 [7] (byte) irq_cnt#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
// Counting the 10 IRQs
// Counting the 10 IRQs
lda #0
sta irq_cnt
jmp b7
@ -2533,29 +2533,29 @@ loop: {
jmp b1
}
//SEG93 sprites_irq_init
// Setup the IRQ
// Setup the IRQ
sprites_irq_init: {
//SEG94 asm { sei }
sei
//SEG95 [50] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Acknowledge any IRQ and setup the next one
// Acknowledge any IRQ and setup the next one
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG96 asm { ldaCIA1_INTERRUPT }
lda CIA1_INTERRUPT
//SEG97 [52] *((const byte*) PROCPORT_DDR#0) ← (const byte) PROCPORT_DDR_MEMORY_MASK#0 -- _deref_pbuc1=vbuc2
// Disable kernal & basic
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
//SEG98 [53] *((const byte*) PROCPORT#0) ← (const byte) PROCPORT_RAM_IO#0 -- _deref_pbuc1=vbuc2
lda #PROCPORT_RAM_IO
sta PROCPORT
//SEG99 [54] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 -- _deref_pbuc1=vbuc2
// Disable CIA 1 Timer IRQ
// Disable CIA 1 Timer IRQ
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
//SEG100 [55] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
// Set raster line
// Set raster line
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
@ -2563,11 +2563,11 @@ sprites_irq_init: {
lda #IRQ_RASTER_FIRST
sta RASTER
//SEG102 [57] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Enable Raster Interrupt
// Enable Raster Interrupt
lda #IRQ_RASTER
sta IRQ_ENABLE
//SEG103 [58] *((const void()**) HARDWARE_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) sprites_irq() -- _deref_pptc1=pprc2
// Set the IRQ routine
// Set the IRQ routine
lda #<sprites_irq
sta HARDWARE_IRQ
lda #>sprites_irq
@ -2581,7 +2581,7 @@ sprites_irq_init: {
rts
}
//SEG107 sprites_init
// Setup the sprites
// Setup the sprites
sprites_init: {
.label s2 = $13
.label xpos = 9
@ -2644,9 +2644,9 @@ sprites_init: {
rts
}
//SEG127 sprites_irq
// Raster Interrupt Routine - sets up the sprites covering the playfield
// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST
// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers
// Raster Interrupt Routine - sets up the sprites covering the playfield
// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST
// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers
sprites_irq: {
.const toSpritePtr2_return = PLAYFIELD_SPRITES>>6
.label _0 = $15
@ -2662,11 +2662,11 @@ sprites_irq: {
stx regx+1
sty regy+1
//SEG129 asm { cld }
// (*BGCOL)++;
// Clear decimal flag (because it is used by the score algorithm)
//(*BGCOL)++;
// Clear decimal flag (because it is used by the score algorithm)
cld
//SEG130 [74] (byte) sprites_irq::ypos#0 ← (byte) irq_sprite_ypos#0 -- vbuz1=vbuz2
// Place the sprites
// Place the sprites
lda irq_sprite_ypos
sta ypos
//SEG131 [75] *((const byte*) SPRITES_YPOS#0) ← (byte) sprites_irq::ypos#0 -- _deref_pbuc1=vbuz1
@ -2686,7 +2686,7 @@ sprites_irq: {
iny
sty _0
//SEG136 [80] (byte) sprites_irq::raster_sprite_gfx_modify#0 ← (byte/signed word/word/dword/signed dword~) sprites_irq::$0 -- vbuz1=vbuz2
// Wait for the y-position before changing sprite pointers
// Wait for the y-position before changing sprite pointers
lda _0
sta raster_sprite_gfx_modify
jmp b1
@ -2774,11 +2774,11 @@ sprites_irq: {
//SEG160 sprites_irq::@7
b7:
//SEG161 [97] *((const byte*) RASTER#0) ← (byte) irq_raster_next#4 -- _deref_pbuc1=vbuz1
// Setup next interrupt
// Setup next interrupt
lda irq_raster_next_4
sta RASTER
//SEG162 [98] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Acknowledge the IRQ and setup the next one
// Acknowledge the IRQ and setup the next one
lda #IRQ_RASTER
sta IRQ_STATUS
jmp breturn
@ -3136,15 +3136,15 @@ ASSEMBLER BEFORE OPTIMIZATION
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// Processor port data direction register
// Processor port data direction register
.label PROCPORT_DDR = 0
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
.const PROCPORT_DDR_MEMORY_MASK = 7
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// RAM in $A000, $E000 I/O in $D000
// RAM in $A000, $E000 I/O in $D000
.const PROCPORT_RAM_IO = $35
// The offset of the sprite pointers from the screen start address
// The offset of the sprite pointers from the screen start address
.const SPRITE_PTRS = $3f8
.label SPRITES_XPOS = $d000
.label SPRITES_YPOS = $d001
@ -3156,44 +3156,44 @@ ASSEMBLER BEFORE OPTIMIZATION
.label SPRITES_COLS = $d027
.label VIC_CONTROL = $d011
.label D018 = $d018
// VIC II IRQ Status Register
// VIC II IRQ Status Register
.label IRQ_STATUS = $d019
// VIC II IRQ Enable Register
// VIC II IRQ Enable Register
.label IRQ_ENABLE = $d01a
// Bits for the IRQ Status/Enable Registers
// Bits for the IRQ Status/Enable Registers
.const IRQ_RASTER = 1
// CIA#1 Interrupt Status & Control Register
// CIA#1 Interrupt Status & Control Register
.label CIA1_INTERRUPT = $dc0d
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
.const CIA_INTERRUPT_CLEAR = $7f
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
.label CIA2_PORT_A = $dd00
// CIA #2 Port A data direction register.
// CIA #2 Port A data direction register.
.label CIA2_PORT_A_DDR = $dd02
// The vector used when the HARDWARE serves IRQ interrupts
// The vector used when the HARDWARE serves IRQ interrupts
.label HARDWARE_IRQ = $fffe
// The colors of the C64
// The colors of the C64
.const BLACK = 0
// Address of the first screen
// Address of the first screen
.label PLAYFIELD_SCREEN_1 = $400
// Address of the second screen
// Address of the second screen
.label PLAYFIELD_SCREEN_2 = $2c00
// Address of the sprites covering the playfield
// Address of the sprites covering the playfield
.label PLAYFIELD_SPRITES = $2000
// Address of the charset
// Address of the charset
.label PLAYFIELD_CHARSET = $2800
// The size of the playfield
// The size of the playfield
.const PLAYFIELD_LINES = $16
.const PLAYFIELD_COLS = $a
// The Y-position of the first sprite row
// The Y-position of the first sprite row
.const SPRITES_FIRST_YPOS = $31
.label SIN = $1400
.label SIN_SPRITE = $2800
// Screen Sprite pointers on screen 1
// Screen Sprite pointers on screen 1
.label PLAYFIELD_SPRITE_PTRS_1 = PLAYFIELD_SCREEN_1+SPRITE_PTRS
// Screen Sprite pointers on screen 2
// Screen Sprite pointers on screen 2
.label PLAYFIELD_SPRITE_PTRS_2 = PLAYFIELD_SCREEN_2+SPRITE_PTRS
// The line of the first IRQ
// The line of the first IRQ
.const IRQ_RASTER_FIRST = SPRITES_FIRST_YPOS+$13
.const toSpritePtr1_return = PLAYFIELD_SPRITES>>6
.label render_screen_showing = 5
@ -3208,7 +3208,7 @@ bbegin:
//SEG4 @4
b4:
//SEG5 [1] (byte) render_screen_showing#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
// The screen currently being showed to the user. $00 for screen 1 / $40 for screen 2.
// The screen currently being showed to the user. $00 for screen 1 / $40 for screen 2.
lda #0
sta render_screen_showing
//SEG6 kickasm(location (const byte*) PLAYFIELD_SPRITES#0) {{ .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++) { .for (var y=0;y<21; y++) { .var gfx_y = sprite_gfx_y + mod(2100+y-sprite_gfx_y,21) .for (var c=0; c<3; c++) { .byte sprites.getSinglecolorByte(sx*3+c,gfx_y) } } .byte 0 } } }}
@ -3216,11 +3216,11 @@ b4:
//SEG7 @5
b5:
//SEG8 [3] (byte) irq_raster_next#0 ← (const byte) IRQ_RASTER_FIRST#0 -- vbuz1=vbuc1
// The raster line of the next IRQ
// The raster line of the next IRQ
lda #IRQ_RASTER_FIRST
sta irq_raster_next
//SEG9 [4] (byte) irq_sprite_ypos#0 ← (const byte) SPRITES_FIRST_YPOS#0+(byte/signed byte/word/signed word/dword/signed dword) 21 -- vbuz1=vbuc1
// Y-pos of the sprites on the next IRQ
// Y-pos of the sprites on the next IRQ
lda #SPRITES_FIRST_YPOS+$15
sta irq_sprite_ypos
//SEG10 [5] phi from @5 to toSpritePtr1 [phi:@5->toSpritePtr1]
@ -3232,11 +3232,11 @@ toSpritePtr1:
//SEG12 @10
b10:
//SEG13 [6] (byte) irq_sprite_ptr#0 ← (const byte) toSpritePtr1_return#0+(byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuz1=vbuc1
// Index of the sprites to show on the next IRQ
// Index of the sprites to show on the next IRQ
lda #toSpritePtr1_return+3
sta irq_sprite_ptr
//SEG14 [7] (byte) irq_cnt#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
// Counting the 10 IRQs
// Counting the 10 IRQs
lda #0
sta irq_cnt
jmp b7
@ -3452,29 +3452,29 @@ loop: {
jmp b1
}
//SEG93 sprites_irq_init
// Setup the IRQ
// Setup the IRQ
sprites_irq_init: {
//SEG94 asm { sei }
sei
//SEG95 [50] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Acknowledge any IRQ and setup the next one
// Acknowledge any IRQ and setup the next one
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG96 asm { ldaCIA1_INTERRUPT }
lda CIA1_INTERRUPT
//SEG97 [52] *((const byte*) PROCPORT_DDR#0) ← (const byte) PROCPORT_DDR_MEMORY_MASK#0 -- _deref_pbuc1=vbuc2
// Disable kernal & basic
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
//SEG98 [53] *((const byte*) PROCPORT#0) ← (const byte) PROCPORT_RAM_IO#0 -- _deref_pbuc1=vbuc2
lda #PROCPORT_RAM_IO
sta PROCPORT
//SEG99 [54] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 -- _deref_pbuc1=vbuc2
// Disable CIA 1 Timer IRQ
// Disable CIA 1 Timer IRQ
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
//SEG100 [55] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
// Set raster line
// Set raster line
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
@ -3482,11 +3482,11 @@ sprites_irq_init: {
lda #IRQ_RASTER_FIRST
sta RASTER
//SEG102 [57] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Enable Raster Interrupt
// Enable Raster Interrupt
lda #IRQ_RASTER
sta IRQ_ENABLE
//SEG103 [58] *((const void()**) HARDWARE_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) sprites_irq() -- _deref_pptc1=pprc2
// Set the IRQ routine
// Set the IRQ routine
lda #<sprites_irq
sta HARDWARE_IRQ
lda #>sprites_irq
@ -3500,7 +3500,7 @@ sprites_irq_init: {
rts
}
//SEG107 sprites_init
// Setup the sprites
// Setup the sprites
sprites_init: {
.label xpos = 2
//SEG108 [61] *((const byte*) SPRITES_ENABLE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 15 -- _deref_pbuc1=vbuc2
@ -3557,9 +3557,9 @@ sprites_init: {
rts
}
//SEG127 sprites_irq
// Raster Interrupt Routine - sets up the sprites covering the playfield
// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST
// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers
// Raster Interrupt Routine - sets up the sprites covering the playfield
// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST
// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers
sprites_irq: {
.const toSpritePtr2_return = PLAYFIELD_SPRITES>>6
.label raster_sprite_gfx_modify = $a
@ -3567,11 +3567,11 @@ sprites_irq: {
sta rega+1
stx regx+1
//SEG129 asm { cld }
// (*BGCOL)++;
// Clear decimal flag (because it is used by the score algorithm)
//(*BGCOL)++;
// Clear decimal flag (because it is used by the score algorithm)
cld
//SEG130 [74] (byte) sprites_irq::ypos#0 ← (byte) irq_sprite_ypos#0 -- vbuaa=vbuz1
// Place the sprites
// Place the sprites
lda irq_sprite_ypos
//SEG131 [75] *((const byte*) SPRITES_YPOS#0) ← (byte) sprites_irq::ypos#0 -- _deref_pbuc1=vbuaa
sta SPRITES_YPOS
@ -3585,7 +3585,7 @@ sprites_irq: {
ldx irq_raster_next
inx
//SEG136 [80] (byte) sprites_irq::raster_sprite_gfx_modify#0 ← (byte/signed word/word/dword/signed dword~) sprites_irq::$0 -- vbuz1=vbuxx
// Wait for the y-position before changing sprite pointers
// Wait for the y-position before changing sprite pointers
stx raster_sprite_gfx_modify
jmp b1
//SEG137 sprites_irq::@1
@ -3664,11 +3664,11 @@ sprites_irq: {
//SEG160 sprites_irq::@7
b7:
//SEG161 [97] *((const byte*) RASTER#0) ← (byte) irq_raster_next#4 -- _deref_pbuc1=vbuz1
// Setup next interrupt
// Setup next interrupt
lda irq_raster_next
sta RASTER
//SEG162 [98] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Acknowledge the IRQ and setup the next one
// Acknowledge the IRQ and setup the next one
lda #IRQ_RASTER
sta IRQ_STATUS
jmp breturn
@ -4201,15 +4201,15 @@ Score: 7709
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// Processor port data direction register
// Processor port data direction register
.label PROCPORT_DDR = 0
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
.const PROCPORT_DDR_MEMORY_MASK = 7
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// RAM in $A000, $E000 I/O in $D000
// RAM in $A000, $E000 I/O in $D000
.const PROCPORT_RAM_IO = $35
// The offset of the sprite pointers from the screen start address
// The offset of the sprite pointers from the screen start address
.const SPRITE_PTRS = $3f8
.label SPRITES_XPOS = $d000
.label SPRITES_YPOS = $d001
@ -4221,44 +4221,44 @@ Score: 7709
.label SPRITES_COLS = $d027
.label VIC_CONTROL = $d011
.label D018 = $d018
// VIC II IRQ Status Register
// VIC II IRQ Status Register
.label IRQ_STATUS = $d019
// VIC II IRQ Enable Register
// VIC II IRQ Enable Register
.label IRQ_ENABLE = $d01a
// Bits for the IRQ Status/Enable Registers
// Bits for the IRQ Status/Enable Registers
.const IRQ_RASTER = 1
// CIA#1 Interrupt Status & Control Register
// CIA#1 Interrupt Status & Control Register
.label CIA1_INTERRUPT = $dc0d
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
.const CIA_INTERRUPT_CLEAR = $7f
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
.label CIA2_PORT_A = $dd00
// CIA #2 Port A data direction register.
// CIA #2 Port A data direction register.
.label CIA2_PORT_A_DDR = $dd02
// The vector used when the HARDWARE serves IRQ interrupts
// The vector used when the HARDWARE serves IRQ interrupts
.label HARDWARE_IRQ = $fffe
// The colors of the C64
// The colors of the C64
.const BLACK = 0
// Address of the first screen
// Address of the first screen
.label PLAYFIELD_SCREEN_1 = $400
// Address of the second screen
// Address of the second screen
.label PLAYFIELD_SCREEN_2 = $2c00
// Address of the sprites covering the playfield
// Address of the sprites covering the playfield
.label PLAYFIELD_SPRITES = $2000
// Address of the charset
// Address of the charset
.label PLAYFIELD_CHARSET = $2800
// The size of the playfield
// The size of the playfield
.const PLAYFIELD_LINES = $16
.const PLAYFIELD_COLS = $a
// The Y-position of the first sprite row
// The Y-position of the first sprite row
.const SPRITES_FIRST_YPOS = $31
.label SIN = $1400
.label SIN_SPRITE = $2800
// Screen Sprite pointers on screen 1
// Screen Sprite pointers on screen 1
.label PLAYFIELD_SPRITE_PTRS_1 = PLAYFIELD_SCREEN_1+SPRITE_PTRS
// Screen Sprite pointers on screen 2
// Screen Sprite pointers on screen 2
.label PLAYFIELD_SPRITE_PTRS_2 = PLAYFIELD_SCREEN_2+SPRITE_PTRS
// The line of the first IRQ
// The line of the first IRQ
.const IRQ_RASTER_FIRST = SPRITES_FIRST_YPOS+$13
.const toSpritePtr1_return = PLAYFIELD_SPRITES>>6
.label render_screen_showing = 5
@ -4271,28 +4271,28 @@ Score: 7709
bbegin:
//SEG4 @4
//SEG5 [1] (byte) render_screen_showing#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
// The screen currently being showed to the user. $00 for screen 1 / $40 for screen 2.
// The screen currently being showed to the user. $00 for screen 1 / $40 for screen 2.
lda #0
sta render_screen_showing
//SEG6 kickasm(location (const byte*) PLAYFIELD_SPRITES#0) {{ .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++) { .for (var y=0;y<21; y++) { .var gfx_y = sprite_gfx_y + mod(2100+y-sprite_gfx_y,21) .for (var c=0; c<3; c++) { .byte sprites.getSinglecolorByte(sx*3+c,gfx_y) } } .byte 0 } } }}
//SEG7 @5
//SEG8 [3] (byte) irq_raster_next#0 ← (const byte) IRQ_RASTER_FIRST#0 -- vbuz1=vbuc1
// The raster line of the next IRQ
// The raster line of the next IRQ
lda #IRQ_RASTER_FIRST
sta irq_raster_next
//SEG9 [4] (byte) irq_sprite_ypos#0 ← (const byte) SPRITES_FIRST_YPOS#0+(byte/signed byte/word/signed word/dword/signed dword) 21 -- vbuz1=vbuc1
// Y-pos of the sprites on the next IRQ
// Y-pos of the sprites on the next IRQ
lda #SPRITES_FIRST_YPOS+$15
sta irq_sprite_ypos
//SEG10 [5] phi from @5 to toSpritePtr1 [phi:@5->toSpritePtr1]
//SEG11 toSpritePtr1
//SEG12 @10
//SEG13 [6] (byte) irq_sprite_ptr#0 ← (const byte) toSpritePtr1_return#0+(byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuz1=vbuc1
// Index of the sprites to show on the next IRQ
// Index of the sprites to show on the next IRQ
lda #toSpritePtr1_return+3
sta irq_sprite_ptr
//SEG14 [7] (byte) irq_cnt#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1
// Counting the 10 IRQs
// Counting the 10 IRQs
lda #0
sta irq_cnt
//SEG15 @7
@ -4454,29 +4454,29 @@ loop: {
jmp b4
}
//SEG93 sprites_irq_init
// Setup the IRQ
// Setup the IRQ
sprites_irq_init: {
//SEG94 asm { sei }
sei
//SEG95 [50] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Acknowledge any IRQ and setup the next one
// Acknowledge any IRQ and setup the next one
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG96 asm { ldaCIA1_INTERRUPT }
lda CIA1_INTERRUPT
//SEG97 [52] *((const byte*) PROCPORT_DDR#0) ← (const byte) PROCPORT_DDR_MEMORY_MASK#0 -- _deref_pbuc1=vbuc2
// Disable kernal & basic
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
//SEG98 [53] *((const byte*) PROCPORT#0) ← (const byte) PROCPORT_RAM_IO#0 -- _deref_pbuc1=vbuc2
lda #PROCPORT_RAM_IO
sta PROCPORT
//SEG99 [54] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 -- _deref_pbuc1=vbuc2
// Disable CIA 1 Timer IRQ
// Disable CIA 1 Timer IRQ
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
//SEG100 [55] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
// Set raster line
// Set raster line
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
@ -4484,11 +4484,11 @@ sprites_irq_init: {
lda #IRQ_RASTER_FIRST
sta RASTER
//SEG102 [57] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Enable Raster Interrupt
// Enable Raster Interrupt
lda #IRQ_RASTER
sta IRQ_ENABLE
//SEG103 [58] *((const void()**) HARDWARE_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) sprites_irq() -- _deref_pptc1=pprc2
// Set the IRQ routine
// Set the IRQ routine
lda #<sprites_irq
sta HARDWARE_IRQ
lda #>sprites_irq
@ -4500,7 +4500,7 @@ sprites_irq_init: {
rts
}
//SEG107 sprites_init
// Setup the sprites
// Setup the sprites
sprites_init: {
.label xpos = 2
//SEG108 [61] *((const byte*) SPRITES_ENABLE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 15 -- _deref_pbuc1=vbuc2
@ -4549,9 +4549,9 @@ sprites_init: {
rts
}
//SEG127 sprites_irq
// Raster Interrupt Routine - sets up the sprites covering the playfield
// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST
// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers
// Raster Interrupt Routine - sets up the sprites covering the playfield
// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST
// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers
sprites_irq: {
.const toSpritePtr2_return = PLAYFIELD_SPRITES>>6
.label raster_sprite_gfx_modify = $a
@ -4559,11 +4559,11 @@ sprites_irq: {
sta rega+1
stx regx+1
//SEG129 asm { cld }
// (*BGCOL)++;
// Clear decimal flag (because it is used by the score algorithm)
//(*BGCOL)++;
// Clear decimal flag (because it is used by the score algorithm)
cld
//SEG130 [74] (byte) sprites_irq::ypos#0 ← (byte) irq_sprite_ypos#0 -- vbuaa=vbuz1
// Place the sprites
// Place the sprites
lda irq_sprite_ypos
//SEG131 [75] *((const byte*) SPRITES_YPOS#0) ← (byte) sprites_irq::ypos#0 -- _deref_pbuc1=vbuaa
sta SPRITES_YPOS
@ -4577,7 +4577,7 @@ sprites_irq: {
ldx irq_raster_next
inx
//SEG136 [80] (byte) sprites_irq::raster_sprite_gfx_modify#0 ← (byte/signed word/word/dword/signed dword~) sprites_irq::$0 -- vbuz1=vbuxx
// Wait for the y-position before changing sprite pointers
// Wait for the y-position before changing sprite pointers
stx raster_sprite_gfx_modify
//SEG137 sprites_irq::@1
b1:
@ -4641,11 +4641,11 @@ sprites_irq: {
//SEG160 sprites_irq::@7
b7:
//SEG161 [97] *((const byte*) RASTER#0) ← (byte) irq_raster_next#4 -- _deref_pbuc1=vbuz1
// Setup next interrupt
// Setup next interrupt
lda irq_raster_next
sta RASTER
//SEG162 [98] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Acknowledge the IRQ and setup the next one
// Acknowledge the IRQ and setup the next one
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG163 sprites_irq::@return

View File

@ -1,18 +1,18 @@
// Tetris Game for the Commodore 64
// The tetris game tries to match NES tetris gameplay pretty closely
// Source: https://meatfighter.com/nintendotetrisai/
// Tetris Game for the Commodore 64
// The tetris game tries to match NES tetris gameplay pretty closely
// Source: https://meatfighter.com/nintendotetrisai/
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
// Processor port data direction register
// Processor port data direction register
.label PROCPORT_DDR = 0
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
.const PROCPORT_DDR_MEMORY_MASK = 7
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// RAM in $A000, $E000 I/O in $D000
// RAM in $A000, $E000 I/O in $D000
.const PROCPORT_RAM_IO = $35
// The offset of the sprite pointers from the screen start address
// The offset of the sprite pointers from the screen start address
.const SPRITE_PTRS = $3f8
.label SPRITES_XPOS = $d000
.label SPRITES_YPOS = $d001
@ -33,29 +33,29 @@
.const VIC_DEN = $10
.const VIC_RSEL = 8
.label D018 = $d018
// VIC II IRQ Status Register
// VIC II IRQ Status Register
.label IRQ_STATUS = $d019
// VIC II IRQ Enable Register
// VIC II IRQ Enable Register
.label IRQ_ENABLE = $d01a
// Bits for the IRQ Status/Enable Registers
// Bits for the IRQ Status/Enable Registers
.const IRQ_RASTER = 1
// Color Ram
// Color Ram
.label COLS = $d800
// CIA#1 Port A: keyboard matrix columns and joystick #2
// CIA#1 Port A: keyboard matrix columns and joystick #2
.label CIA1_PORT_A = $dc00
// CIA#1 Port B: keyboard matrix rows and joystick #1.
// CIA#1 Port B: keyboard matrix rows and joystick #1.
.label CIA1_PORT_B = $dc01
// CIA#1 Interrupt Status & Control Register
// CIA#1 Interrupt Status & Control Register
.label CIA1_INTERRUPT = $dc0d
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
.const CIA_INTERRUPT_CLEAR = $7f
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
// CIA#2 Port A: Serial bus, RS-232, VIC memory bank
.label CIA2_PORT_A = $dd00
// CIA #2 Port A data direction register.
// CIA #2 Port A data direction register.
.label CIA2_PORT_A_DDR = $dd02
// The vector used when the HARDWARE serves IRQ interrupts
// The vector used when the HARDWARE serves IRQ interrupts
.label HARDWARE_IRQ = $fffe
// The colors of the C64
// The colors of the C64
.const BLACK = 0
.const RED = 2
.const CYAN = 3
@ -77,53 +77,53 @@
.const KEY_CTRL = $3a
.const KEY_SPACE = $3c
.const KEY_COMMODORE = $3d
// Left shift is pressed
// Left shift is pressed
.const KEY_MODIFIER_LSHIFT = 1
// Right shift is pressed
// Right shift is pressed
.const KEY_MODIFIER_RSHIFT = 2
// CTRL is pressed
// CTRL is pressed
.const KEY_MODIFIER_CTRL = 4
// Commodore is pressed
// Commodore is pressed
.const KEY_MODIFIER_COMMODORE = 8
// SID registers for random number generation
// SID registers for random number generation
.label SID_VOICE3_FREQ = $d40e
.label SID_VOICE3_CONTROL = $d412
.const SID_CONTROL_NOISE = $80
.label SID_VOICE3_OSC = $d41b
// Address of the first screen
// Address of the first screen
.label PLAYFIELD_SCREEN_1 = $400
// Address of the second screen
// Address of the second screen
.label PLAYFIELD_SCREEN_2 = $2c00
// Address of the original playscreen chars
// Address of the original playscreen chars
.label PLAYFIELD_SCREEN_ORIGINAL = $1800
// Address of the original playscreen colors
// Address of the original playscreen colors
.label PLAYFIELD_COLORS_ORIGINAL = $1c00
// Address of the sprites covering the playfield
// Address of the sprites covering the playfield
.label PLAYFIELD_SPRITES = $2000
// Address of the charset
// Address of the charset
.label PLAYFIELD_CHARSET = $2800
// The size of the playfield
// The size of the playfield
.const PLAYFIELD_LINES = $16
.const PLAYFIELD_COLS = $a
// The Y-position of the first sprite row
// The Y-position of the first sprite row
.const SPRITES_FIRST_YPOS = $31
// The rate of moving down the current piece fast (number of frames between moves if movedown is not forced)
// The rate of moving down the current piece fast (number of frames between moves if movedown is not forced)
.const current_movedown_fast = $a
// No collision
// No collision
.const COLLISION_NONE = 0
// Playfield piece collision (cell on top of other cell on the playfield)
// Playfield piece collision (cell on top of other cell on the playfield)
.const COLLISION_PLAYFIELD = 1
// Bottom collision (cell below bottom of the playfield)
// Bottom collision (cell below bottom of the playfield)
.const COLLISION_BOTTOM = 2
// Left side collision (cell beyond the left side of the playfield)
// Left side collision (cell beyond the left side of the playfield)
.const COLLISION_LEFT = 4
// Right side collision (cell beyond the right side of the playfield)
// Right side collision (cell beyond the right side of the playfield)
.const COLLISION_RIGHT = 8
// Screen Sprite pointers on screen 1
// Screen Sprite pointers on screen 1
.label PLAYFIELD_SPRITE_PTRS_1 = PLAYFIELD_SCREEN_1+SPRITE_PTRS
// Screen Sprite pointers on screen 2
// Screen Sprite pointers on screen 2
.label PLAYFIELD_SPRITE_PTRS_2 = PLAYFIELD_SCREEN_2+SPRITE_PTRS
// The line of the first IRQ
// The line of the first IRQ
.const IRQ_RASTER_FIRST = SPRITES_FIRST_YPOS+$13
.const toSpritePtr1_return = PLAYFIELD_SPRITES>>6
.label keyboard_events_size = $23
@ -163,20 +163,20 @@
.label current_piece_101 = 5
.label current_piece_102 = 5
bbegin:
// The screen currently being showed to the user. $00 for screen 1 / $40 for screen 2.
// The screen currently being showed to the user. $00 for screen 1 / $40 for screen 2.
lda #0
sta render_screen_showing
// Original Color Data
// The raster line of the next IRQ
// Original Color Data
// The raster line of the next IRQ
lda #IRQ_RASTER_FIRST
sta irq_raster_next
// Y-pos of the sprites on the next IRQ
// Y-pos of the sprites on the next IRQ
lda #SPRITES_FIRST_YPOS+$15
sta irq_sprite_ypos
// Index of the sprites to show on the next IRQ
// Index of the sprites to show on the next IRQ
lda #toSpritePtr1_return+3
sta irq_sprite_ptr
// Counting the 10 IRQs
// Counting the 10 IRQs
lda #0
sta irq_cnt
jsr main
@ -230,7 +230,7 @@ main: {
lda #0
sta render_screen_show
b1:
// Wait for a frame to pass
// Wait for a frame to pass
b4:
lda RASTER
cmp #$ff
@ -270,7 +270,7 @@ main: {
jsr render_screen_swap
jmp b1
}
// Swap rendering to the other screen (used for double buffering)
// Swap rendering to the other screen (used for double buffering)
render_screen_swap: {
lda render_screen_render
eor #$40
@ -280,7 +280,7 @@ render_screen_swap: {
sta render_screen_show
rts
}
// Show the current score
// Show the current score
render_score: {
.label score_bytes = score_bcd
.const score_offset = $28*5+$1c
@ -347,11 +347,11 @@ render_score: {
jsr render_bcd
rts
}
// Render BCD digits on a screen.
// - screen: pointer to the screen to render on
// - offset: offset on the screen
// - bcd: The BCD-value to render
// - only_low: if non-zero only renders the low digit
// Render BCD digits on a screen.
// - screen: pointer to the screen to render on
// - offset: offset on the screen
// - bcd: The BCD-value to render
// - only_low: if non-zero only renders the low digit
render_bcd: {
.const ZERO_CHAR = $35
.label screen = 5
@ -392,7 +392,7 @@ render_bcd: {
!:
rts
}
// Render the next tetromino in the "next" area
// Render the next tetromino in the "next" area
render_next: {
.const next_area_offset = $28*$c+$18+4
.label next_piece_char = $a
@ -463,8 +463,8 @@ render_next: {
sta (screen_next_area),y
jmp b6
}
// Render the current moving piece at position (current_xpos, current_ypos)
// Ignores cases where parts of the tetromino is outside the playfield (sides/bottom) since the movement collision routine prevents this.
// Render the current moving piece at position (current_xpos, current_ypos)
// Ignores cases where parts of the tetromino is outside the playfield (sides/bottom) since the movement collision routine prevents this.
render_moving: {
.label ypos2 = $b
.label screen_line = 7
@ -528,7 +528,7 @@ render_moving: {
bne b4
jmp b3
}
// Render the static playfield on the screen (all pieces already locked into place)
// Render the static playfield on the screen (all pieces already locked into place)
render_playfield: {
.label screen_line = 5
.label i = $a
@ -571,9 +571,9 @@ render_playfield: {
bne b1
rts
}
// Perform any movement of the current piece
// key_event is the next keyboard_event() og $ff if no keyboard event is pending
// Returns a byte signaling whether rendering is needed. (0 no render, >0 render needed)
// Perform any movement of the current piece
// key_event is the next keyboard_event() og $ff if no keyboard event is pending
// Returns a byte signaling whether rendering is needed. (0 no render, >0 render needed)
play_movement: {
.label render = 9
.label return = 9
@ -602,8 +602,8 @@ play_movement: {
sta return
jmp breturn
}
// Rotate the current piece based on key-presses
// Return non-zero if a render is needed
// Rotate the current piece based on key-presses
// Return non-zero if a render is needed
play_move_rotate: {
.label orientation = $a
cmp #KEY_Z
@ -651,8 +651,8 @@ play_move_rotate: {
sta orientation
jmp b4
}
// Test if there is a collision between the current piece moved to (x, y) and anything on the playfield or the playfield boundaries
// Returns information about the type of the collision detected
// Test if there is a collision between the current piece moved to (x, y) and anything on the playfield or the playfield boundaries
// Returns information about the type of the collision detected
play_collision: {
.label xpos = $c
.label ypos = $b
@ -744,10 +744,10 @@ play_collision: {
sta i_13
jmp b2
}
// Move left/right or rotate the current piece
// Return non-zero if a render is needed
// Move left/right or rotate the current piece
// Return non-zero if a render is needed
play_move_leftright: {
// Handle keyboard events
// Handle keyboard events
cmp #KEY_COMMA
beq b1
cmp #KEY_DOT
@ -790,8 +790,8 @@ play_move_leftright: {
dec current_xpos
jmp b2
}
// Move down the current piece
// Return non-zero if a render is needed
// Move down the current piece
// Return non-zero if a render is needed
play_move_down: {
inc current_movedown_counter
cmp #KEY_SPACE
@ -857,12 +857,12 @@ play_move_down: {
inc current_ypos
jmp b7
}
// Spawn a new piece
// Moves the next piece into the current and spawns a new next piece
// Spawn a new piece
// Moves the next piece into the current and spawns a new next piece
play_spawn_current: {
.label _0 = 4
.label piece_idx = $21
// Move next piece into current
// Move next piece into current
ldx next_piece_idx
txa
asl
@ -906,13 +906,13 @@ play_spawn_current: {
sta piece_idx
jmp b2
}
// Get a random number from the SID voice 3,
// Must be initialized with sid_rnd_init()
// Get a random number from the SID voice 3,
// Must be initialized with sid_rnd_init()
sid_rnd: {
lda SID_VOICE3_OSC
rts
}
// Update the score based on the number of lines removed
// Update the score based on the number of lines removed
play_update_score: {
.label lines_before = 4
.label add_bcd = $2b
@ -963,10 +963,10 @@ play_update_score: {
breturn:
rts
}
// Increase the level
// Increase the level
play_increase_level: {
inc level
// Update speed of moving tetrominos down
// Update speed of moving tetrominos down
lda level
cmp #$1d
beq !+
@ -985,13 +985,13 @@ play_increase_level: {
and level_bcd
cmp #$a
bne b3
// If level low nybble hits $a change to $10
// If level low nybble hits $a change to $10
lda #6
clc
adc level_bcd
sta level_bcd
b3:
// Increase the score values gained
// Increase the score values gained
sed
ldx #0
b4:
@ -1018,10 +1018,10 @@ play_increase_level: {
cld
rts
}
// Look through the playfield for lines - and remove any lines found
// Utilizes two cursors on the playfield - one reading cells and one writing cells
// Whenever a full line is detected the writing cursor is instructed to write to the same line once more.
// Returns the number of lines removed
// Look through the playfield for lines - and remove any lines found
// Utilizes two cursors on the playfield - one reading cells and one writing cells
// Whenever a full line is detected the writing cursor is instructed to write to the same line once more.
// Returns the number of lines removed
play_remove_lines: {
.label c = $c
.label x = $a
@ -1033,7 +1033,7 @@ play_remove_lines: {
sta y
ldx #PLAYFIELD_LINES*PLAYFIELD_COLS-1
ldy #PLAYFIELD_LINES*PLAYFIELD_COLS-1
// Read all lines and rewrite them
// Read all lines and rewrite them
b1:
lda #1
sta full
@ -1069,7 +1069,7 @@ play_remove_lines: {
cmp #PLAYFIELD_LINES-1+1
bne b1
b5:
// Write zeros in the rest of the lines
// Write zeros in the rest of the lines
cpx #$ff
bne b6
rts
@ -1079,7 +1079,7 @@ play_remove_lines: {
dex
jmp b5
}
// Lock the current piece onto the playfield
// Lock the current piece onto the playfield
play_lock_current: {
.label ypos2 = $10
.label playfield_line = 5
@ -1137,8 +1137,8 @@ play_lock_current: {
sta i_9
jmp b2
}
// Determine if a specific key is currently pressed based on the last keyboard_event_scan()
// Returns 0 is not pressed and non-0 if pressed
// Determine if a specific key is currently pressed based on the last keyboard_event_scan()
// Returns 0 is not pressed and non-0 if pressed
keyboard_event_pressed: {
.label row_bits = $a
.label keycode = 9
@ -1156,9 +1156,9 @@ keyboard_event_pressed: {
and row_bits
rts
}
// Get the next event from the keyboard event buffer.
// Returns $ff if there is no event waiting. As all events are <$7f it is enough to examine bit 7 when determining if there is any event to process.
// The buffer is filled by keyboard_event_scan()
// Get the next event from the keyboard event buffer.
// Returns $ff if there is no event waiting. As all events are <$7f it is enough to examine bit 7 when determining if there is any event to process.
// The buffer is filled by keyboard_event_scan()
keyboard_event_get: {
lda keyboard_events_size
cmp #0
@ -1173,10 +1173,10 @@ keyboard_event_get: {
breturn:
rts
}
// Scans the entire matrix to determine which keys have been pressed/depressed.
// Generates keyboard events into the event buffer. Events can be read using keyboard_event_get().
// Handles debounce and only generates events when the status of a key changes.
// Also stores current status of modifiers in keyboard_modifiers.
// Scans the entire matrix to determine which keys have been pressed/depressed.
// Generates keyboard events into the event buffer. Events can be read using keyboard_event_get().
// Handles debounce and only generates events when the status of a key changes.
// Also stores current status of modifiers in keyboard_modifiers.
keyboard_event_scan: {
.label row_scan = $b
.label keycode = $a
@ -1237,7 +1237,7 @@ keyboard_event_scan: {
ora #KEY_MODIFIER_COMMODORE
breturn:
rts
// Something has changed on the keyboard row - check each column
// Something has changed on the keyboard row - check each column
b6:
ldx #0
b4:
@ -1254,7 +1254,7 @@ keyboard_event_scan: {
and row_scan
cmp #0
beq b7
// Key pressed
// Key pressed
lda keycode
ldy keyboard_events_size
sta keyboard_events,y
@ -1264,7 +1264,7 @@ keyboard_event_scan: {
inx
cpx #8
bne b4
// Store the current keyboard status for the row to debounce
// Store the current keyboard status for the row to debounce
lda row_scan
ldy row
sta keyboard_scan_values,y
@ -1272,17 +1272,17 @@ keyboard_event_scan: {
b7:
lda #$40
ora keycode
// Key released
// Key released
ldy keyboard_events_size
sta keyboard_events,y
inc keyboard_events_size
jmp b5
}
// Read a single row of the keyboard matrix
// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs.
// Returns the keys pressed on the row as bits according to the C64 key matrix.
// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write
// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader.
// Read a single row of the keyboard matrix
// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs.
// Returns the keys pressed on the row as bits according to the C64 key matrix.
// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write
// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader.
keyboard_matrix_read: {
lda keyboard_matrix_row_bitmask,x
sta CIA1_PORT_A
@ -1290,7 +1290,7 @@ keyboard_matrix_read: {
eor #$ff
rts
}
// Update $D018 to show the current screen (used for double buffering)
// Update $D018 to show the current screen (used for double buffering)
render_show: {
.const toD0181_return = (>(PLAYFIELD_SCREEN_1&$3fff)<<2)|(>PLAYFIELD_CHARSET)>>2&$f
.const toD0182_return = (>(PLAYFIELD_SCREEN_2&$3fff)<<2)|(>PLAYFIELD_CHARSET)>>2&$f
@ -1312,7 +1312,7 @@ render_show: {
lda #toD0181_return
jmp b2
}
// Initialize play data tables
// Initialize play data tables
play_init: {
.label pli = 5
.label idx = 2
@ -1349,11 +1349,11 @@ play_init: {
bne b1
lda #PLAYFIELD_COLS*PLAYFIELD_LINES
sta playfield_lines_idx+PLAYFIELD_LINES
// Set initial speed of moving down a tetromino
// Set initial speed of moving down a tetromino
lda MOVEDOWN_SLOW_SPEEDS
sta current_movedown_slow
ldx #0
// Set the initial score add values
// Set the initial score add values
b2:
txa
asl
@ -1372,31 +1372,31 @@ play_init: {
bne b2
rts
}
// Setup the IRQ
// Setup the IRQ
sprites_irq_init: {
sei
// Acknowledge any IRQ and setup the next one
// Acknowledge any IRQ and setup the next one
lda #IRQ_RASTER
sta IRQ_STATUS
lda CIA1_INTERRUPT
// Disable kernal & basic
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta PROCPORT_DDR
lda #PROCPORT_RAM_IO
sta PROCPORT
// Disable CIA 1 Timer IRQ
// Disable CIA 1 Timer IRQ
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
// Set raster line
// Set raster line
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
lda #IRQ_RASTER_FIRST
sta RASTER
// Enable Raster Interrupt
// Enable Raster Interrupt
lda #IRQ_RASTER
sta IRQ_ENABLE
// Set the IRQ routine
// Set the IRQ routine
lda #<sprites_irq
sta HARDWARE_IRQ
lda #>sprites_irq
@ -1404,7 +1404,7 @@ sprites_irq_init: {
cli
rts
}
// Setup the sprites
// Setup the sprites
sprites_init: {
.label xpos = 2
lda #$f
@ -1433,7 +1433,7 @@ sprites_init: {
bne b1
rts
}
// Initialize rendering
// Initialize rendering
render_init: {
.const vicSelectGfxBank1_toDd001_return = 3^(>PLAYFIELD_CHARSET)>>6
.label li_1 = 5
@ -1442,7 +1442,7 @@ render_init: {
sta CIA2_PORT_A_DDR
lda #vicSelectGfxBank1_toDd001_return
sta CIA2_PORT_A
// Enable Extended Background Color Mode
// Enable Extended Background Color Mode
lda #VIC_ECM|VIC_DEN|VIC_RSEL|3
sta D011
lda #BLACK
@ -1507,8 +1507,8 @@ render_init: {
bne b1
rts
}
// Copy the original screen data to the passed screen
// Also copies colors to $d800
// Copy the original screen data to the passed screen
// Also copies colors to $d800
render_screen_original: {
.const SPACE = 0
.label screen = $11
@ -1600,7 +1600,7 @@ render_screen_original: {
bne b1
rts
}
// Initialize SID voice 3 for random number generation
// Initialize SID voice 3 for random number generation
sid_rnd_init: {
lda #<$ffff
sta SID_VOICE3_FREQ
@ -1610,18 +1610,18 @@ sid_rnd_init: {
sta SID_VOICE3_CONTROL
rts
}
// Raster Interrupt Routine - sets up the sprites covering the playfield
// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST
// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers
// Raster Interrupt Routine - sets up the sprites covering the playfield
// Repeats 10 timers every 2 lines from line IRQ_RASTER_FIRST
// Utilizes duplicated gfx in the sprites to allow for some leeway in updating the sprite pointers
sprites_irq: {
.const toSpritePtr2_return = PLAYFIELD_SPRITES>>6
.label raster_sprite_gfx_modify = $2f
sta rega+1
stx regx+1
// (*BGCOL)++;
// Clear decimal flag (because it is used by the score algorithm)
//(*BGCOL)++;
// Clear decimal flag (because it is used by the score algorithm)
cld
// Place the sprites
// Place the sprites
lda irq_sprite_ypos
sta SPRITES_YPOS
sta SPRITES_YPOS+2
@ -1629,7 +1629,7 @@ sprites_irq: {
sta SPRITES_YPOS+6
ldx irq_raster_next
inx
// Wait for the y-position before changing sprite pointers
// Wait for the y-position before changing sprite pointers
stx raster_sprite_gfx_modify
b1:
lda RASTER
@ -1668,10 +1668,10 @@ sprites_irq: {
adc irq_sprite_ptr
sta irq_sprite_ptr
b7:
// Setup next interrupt
// Setup next interrupt
lda irq_raster_next
sta RASTER
// Acknowledge the IRQ and setup the next one
// Acknowledge the IRQ and setup the next one
lda #IRQ_RASTER
sta IRQ_STATUS
rega:
@ -1715,69 +1715,69 @@ sprites_irq: {
sta PLAYFIELD_SPRITE_PTRS_1+3
jmp b3
}
// Keyboard row bitmask as expected by CIA#1 Port A when reading a specific keyboard matrix row (rows are numbered 0-7)
// Keyboard row bitmask as expected by CIA#1 Port A when reading a specific keyboard matrix row (rows are numbered 0-7)
keyboard_matrix_row_bitmask: .byte $fe, $fd, $fb, $f7, $ef, $df, $bf, $7f
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
keyboard_matrix_col_bitmask: .byte 1, 2, 4, 8, $10, $20, $40, $80
// Keyboard event buffer. Contains keycodes for key presses/releases. Presses are represented by the keycode. Releases by keycode | $40. The buffer is filled by keyboard_scan()
// Keyboard event buffer. Contains keycodes for key presses/releases. Presses are represented by the keycode. Releases by keycode | $40. The buffer is filled by keyboard_scan()
keyboard_events: .fill 8, 0
// The values scanned values for each row. Set by keyboard_scan() and used by keyboard_get_event()
// The values scanned values for each row. Set by keyboard_scan() and used by keyboard_get_event()
keyboard_scan_values: .fill 8, 0
// The T-piece
// The T-piece
.align $40
PIECE_T: .byte 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0
// The S-piece
// The S-piece
.align $40
PIECE_S: .byte 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0
// The Z-piece
// The Z-piece
.align $40
PIECE_Z: .byte 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0
// The L-piece
// The L-piece
.align $40
PIECE_L: .byte 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0
// The J-piece
// The J-piece
.align $40
PIECE_J: .byte 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0
// The O-piece
// The O-piece
.align $40
PIECE_O: .byte 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0
// The I-piece
// The I-piece
.align $40
PIECE_I: .byte 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0
// The chars to use for the different pieces - when inside the playing area
// The chars to use for the different pieces - when inside the playing area
PIECES_CHARS: .byte $65, $66, $a6, $66, $65, $65, $a6
// The chars to use for the different pieces - when outside the playing area (eg. the next area).
// The chars to use for the different pieces - when outside the playing area (eg. the next area).
PIECES_NEXT_CHARS: .byte $63, $64, $a4, $64, $63, $63, $a4
// The initial X/Y for each piece
// The initial X/Y for each piece
PIECES_START_X: .byte 4, 4, 4, 4, 4, 4, 4
PIECES_START_Y: .byte 1, 1, 1, 1, 1, 0, 1
// The speed of moving down the piece when soft-drop is not activated
// This array holds the number of frames per move by level (0-29). For all levels 29+ the value is 1.
// The speed of moving down the piece when soft-drop is not activated
// This array holds the number of frames per move by level (0-29). For all levels 29+ the value is 1.
MOVEDOWN_SLOW_SPEEDS: .byte $30, $2b, $26, $21, $1c, $17, $12, $d, 8, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1
// Base Score values for removing 0-4 lines (in BCD)
// These values are added to score_add_bcd for each level gained.
// Base Score values for removing 0-4 lines (in BCD)
// These values are added to score_add_bcd for each level gained.
SCORE_BASE_BCD: .dword 0, $40, $100, $300, $1200
// 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 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
// The color #1 to use for the pieces for each level
// The color #1 to use for the pieces for each level
PIECES_COLORS_1: .byte BLUE, GREEN, PURPLE, BLUE, RED, LIGHT_GREEN, RED, BLUE, LIGHT_BLUE, RED, BLUE, GREEN, PURPLE, BLUE, RED, LIGHT_GREEN, RED, BLUE, LIGHT_BLUE, RED, BLUE, GREEN, PURPLE, BLUE, RED, LIGHT_GREEN, RED, BLUE, LIGHT_BLUE, RED
// The color #2 to use for the pieces for each level
// The color #2 to use for the pieces for each level
PIECES_COLORS_2: .byte CYAN, LIGHT_GREEN, PINK, LIGHT_GREEN, LIGHT_GREEN, LIGHT_BLUE, DARK_GREY, PURPLE, RED, ORANGE, CYAN, LIGHT_GREEN, PINK, LIGHT_GREEN, LIGHT_GREEN, LIGHT_BLUE, DARK_GREY, PURPLE, RED, ORANGE, CYAN, LIGHT_GREEN, PINK, LIGHT_GREEN, LIGHT_GREEN, LIGHT_BLUE, DARK_GREY, PURPLE, RED, ORANGE
// Pointers to the screen address for rendering each playfield line
// The lines for screen 1 is aligned with $80 and screen 2 with $40 - so XOR'ing with $40 gives screen 2 lines.
// Pointers to the screen address for rendering each playfield line
// The lines for screen 1 is aligned with $80 and screen 2 with $40 - so XOR'ing with $40 gives screen 2 lines.
.align $80
screen_lines_1: .fill 2*PLAYFIELD_LINES, 0
.align $40
screen_lines_2: .fill 2*PLAYFIELD_LINES, 0
// Pointers to the playfield address for each playfield line
// Pointers to the playfield address for each playfield line
playfield_lines: .fill 2*PLAYFIELD_LINES, 0
// The playfield. 0 is empty non-zero is color.
// The playfield is layed out line by line, meaning the first 10 bytes are line 1, the next 10 line 2 and so forth,
// The playfield. 0 is empty non-zero is color.
// The playfield is layed out line by line, meaning the first 10 bytes are line 1, the next 10 line 2 and so forth,
playfield: .fill PLAYFIELD_LINES*PLAYFIELD_COLS, 0
// The different pieces
// The different pieces
PIECES: .word PIECE_T, PIECE_S, PIECE_Z, PIECE_J, PIECE_O, PIECE_I, PIECE_L
// Indixes into the playfield for each playfield line
// Indixes into the playfield for each playfield line
playfield_lines_idx: .fill PLAYFIELD_LINES+1, 0
.pc = PLAYFIELD_CHARSET "PLAYFIELD_CHARSET"
.fill 8,$00 // Place a filled char at the start of the charset

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// Concatenate a char to a string
// Concatenate a char to a string
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -130,7 +130,7 @@ Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
INITIAL ASM
//SEG0 File Comments
// Concatenate a char to a string
// Concatenate a char to a string
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -201,7 +201,7 @@ Uplifting [] best 288 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Concatenate a char to a string
// Concatenate a char to a string
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -301,7 +301,7 @@ FINAL ASSEMBLER
Score: 186
//SEG0 File Comments
// Concatenate a char to a string
// Concatenate a char to a string
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -1,4 +1,4 @@
// Ensure that if()'s with constant comparisons are identified and eliminated
// Ensure that if()'s with constant comparisons are identified and eliminated
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -94,7 +94,7 @@ Complete equivalence classes
INITIAL ASM
//SEG0 File Comments
// Ensure that if()'s with constant comparisons are identified and eliminated
// Ensure that if()'s with constant comparisons are identified and eliminated
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -144,7 +144,7 @@ Uplifting [] best 57 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Ensure that if()'s with constant comparisons are identified and eliminated
// Ensure that if()'s with constant comparisons are identified and eliminated
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -219,7 +219,7 @@ FINAL ASSEMBLER
Score: 12
//SEG0 File Comments
// Ensure that if()'s with constant comparisons are identified and eliminated
// Ensure that if()'s with constant comparisons are identified and eliminated
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -1,4 +1,4 @@
// Test a constant with multiplication and division
// Test a constant with multiplication and division
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -96,7 +96,7 @@ Complete equivalence classes
INITIAL ASM
//SEG0 File Comments
// Test a constant with multiplication and division
// Test a constant with multiplication and division
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -142,7 +142,7 @@ Uplifting [] best 27 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Test a constant with multiplication and division
// Test a constant with multiplication and division
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -211,7 +211,7 @@ FINAL ASSEMBLER
Score: 12
//SEG0 File Comments
// Test a constant with multiplication and division
// Test a constant with multiplication and division
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -1,4 +1,4 @@
// Test that the compiler optimizes when the same parameter value is passed into a function in all calls
// Test that the compiler optimizes when the same parameter value is passed into a function in all calls
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -243,7 +243,7 @@ Allocated zp ZP_BYTE:9 [ sum::return#3 ]
INITIAL ASM
//SEG0 File Comments
// Test that the compiler optimizes when the same parameter value is passed into a function in all calls
// Test that the compiler optimizes when the same parameter value is passed into a function in all calls
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -379,7 +379,7 @@ Uplifting [sum] best 79 combination reg byte a [ sum::return#3 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Test that the compiler optimizes when the same parameter value is passed into a function in all calls
// Test that the compiler optimizes when the same parameter value is passed into a function in all calls
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -533,7 +533,7 @@ FINAL ASSEMBLER
Score: 52
//SEG0 File Comments
// Test that the compiler optimizes when the same parameter value is passed into a function in all calls
// Test that the compiler optimizes when the same parameter value is passed into a function in all calls
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -1,4 +1,4 @@
// Test that constant pointers are detected correctly
//Test that constant pointers are detected correctly
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -111,7 +111,7 @@ Complete equivalence classes
INITIAL ASM
//SEG0 File Comments
// Test that constant pointers are detected correctly
//Test that constant pointers are detected correctly
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -161,7 +161,7 @@ Uplifting [] best 57 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Test that constant pointers are detected correctly
//Test that constant pointers are detected correctly
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -238,7 +238,7 @@ FINAL ASSEMBLER
Score: 12
//SEG0 File Comments
// Test that constant pointers are detected correctly
//Test that constant pointers are detected correctly
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -1,5 +1,5 @@
// Test a constant word pointers (pointing to a word placed on zeropage).
// The result when running is "CML!" on the screen.
// Test a constant word pointers (pointing to a word placed on zeropage).
// The result when running is "CML!" on the screen.
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -129,8 +129,8 @@ Allocated zp ZP_BYTE:7 [ main::$4 ]
INITIAL ASM
//SEG0 File Comments
// Test a constant word pointers (pointing to a word placed on zeropage).
// The result when running is "CML!" on the screen.
// Test a constant word pointers (pointing to a word placed on zeropage).
// The result when running is "CML!" on the screen.
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -219,8 +219,8 @@ Uplifting [] best 75 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Test a constant word pointers (pointing to a word placed on zeropage).
// The result when running is "CML!" on the screen.
// Test a constant word pointers (pointing to a word placed on zeropage).
// The result when running is "CML!" on the screen.
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -324,8 +324,8 @@ FINAL ASSEMBLER
Score: 60
//SEG0 File Comments
// Test a constant word pointers (pointing to a word placed on zeropage).
// The result when running is "CML!" on the screen.
// Test a constant word pointers (pointing to a word placed on zeropage).
// The result when running is "CML!" on the screen.
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -1,4 +1,4 @@
// Concatenates string constants in different ways
// Concatenates string constants in different ways
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -170,7 +170,7 @@ Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
INITIAL ASM
//SEG0 File Comments
// Concatenates string constants in different ways
// Concatenates string constants in different ways
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -244,7 +244,7 @@ Uplifting [] best 288 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Concatenates string constants in different ways
// Concatenates string constants in different ways
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -354,7 +354,7 @@ FINAL ASSEMBLER
Score: 186
//SEG0 File Comments
// Concatenates string constants in different ways
// Concatenates string constants in different ways
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -14,7 +14,7 @@ main: {
jsr test_sbytes
rts
}
// Test different signed byte constants
// Test different signed byte constants
test_sbytes: {
.const bb = 0
.const bc = bb+2
@ -104,7 +104,7 @@ assert_sbyte: {
str1: .text "fail!@"
str2: .text "ok@"
}
// Print a zero-terminated string
// Print a zero-terminated string
print_str: {
.label str = 2
b1:
@ -127,7 +127,7 @@ print_str: {
!:
jmp b1
}
// Print a newline
// Print a newline
print_ln: {
b1:
lda print_line_cursor
@ -147,7 +147,7 @@ print_ln: {
!:
rts
}
// Test different byte constants
// Test different byte constants
test_bytes: {
.const bb = 0
.const bc = bb+2
@ -229,7 +229,7 @@ assert_byte: {
str1: .text "fail!@"
str2: .text "ok@"
}
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = 2
lda #<$400

View File

@ -1392,7 +1392,7 @@ main: {
rts
}
//SEG23 test_sbytes
// Test different signed byte constants
// Test different signed byte constants
test_sbytes: {
.const bb = 0
.const bc = bb+2
@ -1600,7 +1600,7 @@ assert_sbyte: {
str2: .text "ok@"
}
//SEG93 print_str
// Print a zero-terminated string
// Print a zero-terminated string
print_str: {
.label str = 8
//SEG94 [37] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1]
@ -1641,7 +1641,7 @@ print_str: {
jmp b1_from_b2
}
//SEG105 print_ln
// Print a newline
// Print a newline
print_ln: {
//SEG106 [44] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1]
b1_from_print_ln:
@ -1674,7 +1674,7 @@ print_ln: {
rts
}
//SEG113 test_bytes
// Test different byte constants
// Test different byte constants
test_bytes: {
.const bb = 0
.const bc = bb+2
@ -1853,7 +1853,7 @@ assert_byte: {
str2: .text "ok@"
}
//SEG174 print_cls
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = $10
//SEG175 [69] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1]
@ -2033,7 +2033,7 @@ main: {
rts
}
//SEG23 test_sbytes
// Test different signed byte constants
// Test different signed byte constants
test_sbytes: {
.const bb = 0
.const bc = bb+2
@ -2230,7 +2230,7 @@ assert_sbyte: {
str2: .text "ok@"
}
//SEG93 print_str
// Print a zero-terminated string
// Print a zero-terminated string
print_str: {
.label str = 2
//SEG94 [37] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1]
@ -2271,7 +2271,7 @@ print_str: {
jmp b1_from_b2
}
//SEG105 print_ln
// Print a newline
// Print a newline
print_ln: {
//SEG106 [44] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1]
b1_from_print_ln:
@ -2304,7 +2304,7 @@ print_ln: {
rts
}
//SEG113 test_bytes
// Test different byte constants
// Test different byte constants
test_bytes: {
.const bb = 0
.const bc = bb+2
@ -2474,7 +2474,7 @@ assert_byte: {
str2: .text "ok@"
}
//SEG174 print_cls
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = 2
//SEG175 [69] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1]
@ -2797,7 +2797,7 @@ main: {
rts
}
//SEG23 test_sbytes
// Test different signed byte constants
// Test different signed byte constants
test_sbytes: {
.const bb = 0
.const bc = bb+2
@ -2957,7 +2957,7 @@ assert_sbyte: {
str2: .text "ok@"
}
//SEG93 print_str
// Print a zero-terminated string
// Print a zero-terminated string
print_str: {
.label str = 2
//SEG94 [37] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1]
@ -2992,7 +2992,7 @@ print_str: {
jmp b1
}
//SEG105 print_ln
// Print a newline
// Print a newline
print_ln: {
//SEG106 [44] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1]
//SEG107 [44] phi (byte*) print_line_cursor#24 = (byte*) print_line_cursor#47 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy
@ -3020,7 +3020,7 @@ print_ln: {
rts
}
//SEG113 test_bytes
// Test different byte constants
// Test different byte constants
test_bytes: {
.const bb = 0
.const bc = bb+2
@ -3163,7 +3163,7 @@ assert_byte: {
str2: .text "ok@"
}
//SEG174 print_cls
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = 2
//SEG175 [69] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1]

View File

@ -1,4 +1,4 @@
// Test that a double-assignment works.
// Test that a double-assignment works.
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -86,7 +86,7 @@ Complete equivalence classes
INITIAL ASM
//SEG0 File Comments
// Test that a double-assignment works.
// Test that a double-assignment works.
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -136,7 +136,7 @@ Uplifting [] best 33 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Test that a double-assignment works.
// Test that a double-assignment works.
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -211,7 +211,7 @@ FINAL ASSEMBLER
Score: 16
//SEG0 File Comments
// Test that a double-assignment works.
// Test that a double-assignment works.
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -1,4 +1,4 @@
// Error cleaning up unused blocks
// Error cleaning up unused blocks
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"

View File

@ -304,7 +304,7 @@ Allocated zp ZP_BYTE:2 [ a#1 a#12 a#5 ]
INITIAL ASM
//SEG0 File Comments
// Error cleaning up unused blocks
// Error cleaning up unused blocks
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -414,7 +414,7 @@ Uplifting [mode] best 18376 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Error cleaning up unused blocks
// Error cleaning up unused blocks
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -582,7 +582,7 @@ FINAL ASSEMBLER
Score: 8868
//SEG0 File Comments
// Error cleaning up unused blocks
// Error cleaning up unused blocks
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)

View File

@ -1,7 +1,7 @@
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
@ -15,56 +15,56 @@
.const LIGHT_BLUE = $e
.const LIGHT_GREY = $f
.label print_line_cursor = $400
// 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
.const sz = 0
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
.label mulf_sqr1 = $2400
// g(x) = >((( 1 - x ) * ( 1 - x )))
// g(x) = >((( 1 - x ) * ( 1 - x )))
.label mulf_sqr2 = $2600
// A single sprite
// A single sprite
.label SPRITE = $3000
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
.label PERSP_Z = $2800
// Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$20;20]
// Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$20;20]
.label SINH = $2000
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$10,$10]
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$10,$10]
.label SINQ = $2200
// 16 bit Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$1f,$1f]
// 16 bit Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$1f,$1f]
.label SINH_LO = $4000
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
.label SINH_HI = $4200
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$0f,$0f]
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$0f,$0f]
.label SINQ_LO = $4400
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
.label SINQ_HI = $4600
.label COSH = SINH+$40
.label COSQ = SINQ+$40
.label sx = 2
.label sy = 3
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
main: {
sei
jsr sprites_init
// mulf_init();
//mulf_init();
lda #<mulf_sqr1
sta psp1
lda #>mulf_sqr1
@ -82,8 +82,8 @@ anim: {
lda #0
sta sy
sta sx
// signed byte xmin = 0;
// signed byte xmax = 0;
//signed byte xmin = 0;
//signed byte xmax = 0;
b4:
lda RASTER
cmp #$ff
@ -112,8 +112,8 @@ anim: {
lda zs,x
tax
jsr rotate_matrix
// if(*xr<xmin) xmin = *xr;
// if(*xr>xmax) xmax = *xr;
//if(*xr<xmin) xmin = *xr;
//if(*xr>xmax) xmax = *xr;
ldy i
lda xr
sta xrs,y
@ -147,7 +147,7 @@ anim: {
jsr debug_print
lda #LIGHT_BLUE
sta BORDERCOL
// Increment angles
// Increment angles
inc sx
inc sx
lda sy
@ -341,7 +341,7 @@ debug_print: {
!b1:
rts
}
// Print a signed byte as hex at a specific screen position
// Print a signed byte as hex at a specific screen position
print_sbyte_at: {
.label at = 6
cpx #0
@ -367,7 +367,7 @@ print_sbyte_at: {
tax
jmp b2
}
// Print a single char
// Print a single char
print_char_at: {
.label at = 6
.label ch = 8
@ -376,7 +376,7 @@ print_char_at: {
sta (at),y
rts
}
// Print a byte as HEX at a specific position
// Print a byte as HEX at a specific position
print_byte_at: {
.label at = 6
txa
@ -400,10 +400,10 @@ print_byte_at: {
jsr print_char_at
rts
}
// Rotate a 3D point (x,y,z) using the rotation matrix
// The rotation matrix is prepared by calling prepare_matrix()
// The passed points must be in the interval [-$3f;$3f].
// Implemented in assembler to utilize seriously fast multiplication
// Rotate a 3D point (x,y,z) using the rotation matrix
// The rotation matrix is prepared by calling prepare_matrix()
// The passed points must be in the interval [-$3f;$3f].
// Implemented in assembler to utilize seriously fast multiplication
rotate_matrix: {
.label x = 5
lda x
@ -500,9 +500,9 @@ rotate_matrix: {
sta xp
rts
}
// Store the rotation matrix into the rotation routine rotate()
// After this each call to rotate() will rotate a point with the matrix
// Implemented in assembler to utilize seriously fast multiplication
// Store the rotation matrix into the rotation routine rotate()
// After this each call to rotate() will rotate a point with the matrix
// Implemented in assembler to utilize seriously fast multiplication
store_matrix: {
lda rotation_matrix+0
sta rotate_matrix.A1+1
@ -542,9 +542,9 @@ store_matrix: {
sta rotate_matrix.I2+1
rts
}
// Prepare the 3x3 rotation matrix into rotation_matrix[]
// Angles sx, sy, sz are based on 2*PI=$100
// Method described in C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// Prepare the 3x3 rotation matrix into rotation_matrix[]
// Angles sx, sy, sz are based on 2*PI=$100
// Method described in C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
calculate_matrix: {
.label sy = 3
.label t1 = 4
@ -1050,7 +1050,7 @@ debug_print_init: {
str10: .text "xp@"
str11: .text "yp@"
}
// Print a string at a specific screen position
// Print a string at a specific screen position
print_str_at: {
.label at = 9
.label str = 6
@ -1074,7 +1074,7 @@ print_str_at: {
!:
jmp b1
}
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = 6
lda #<print_line_cursor
@ -1097,7 +1097,7 @@ print_cls: {
bne b1
rts
}
// Initialize sprites
// Initialize sprites
sprites_init: {
.label SCREEN = $400
.label sprites_ptr = SCREEN+$3f8
@ -1116,18 +1116,18 @@ sprites_init: {
}
print_hextab: .text "0123456789abcdef"
zs: .byte $34, $34, $34, $34, $34, $34, $34, $34
// Rotated positions
// Rotated positions
xrs: .fill 8, 0
yrs: .fill 8, 0
zrs: .fill 8, 0
// Persepctive factors (from zrs)
// Persepctive factors (from zrs)
pps: .fill 8, 0
// Rotated positions with persepctive
// Rotated positions with persepctive
xps: .fill 8, 0
yps: .fill 8, 0
// The rotation matrix
// The rotation matrix
rotation_matrix: .fill 9, 0
// Positions to rotate
// Positions to rotate
xs: .byte -$34, -$34, -$34, 0, 0, $34, $34, $34
ys: .byte -$34, 0, $34, -$34, $34, -$34, 0, $34
.pc = mulf_sqr1 "mulf_sqr1"

View File

@ -5657,10 +5657,10 @@ Allocated zp ZP_WORD:116 [ debug_print_init::$92 ]
INITIAL ASM
//SEG0 File Comments
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -5676,45 +5676,45 @@ INITIAL ASM
.const LIGHT_BLUE = $e
.const LIGHT_GREY = $f
.label print_line_cursor = $400
// 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
.const sz = 0
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
.label mulf_sqr1 = $2400
// g(x) = >((( 1 - x ) * ( 1 - x )))
// g(x) = >((( 1 - x ) * ( 1 - x )))
.label mulf_sqr2 = $2600
// A single sprite
// A single sprite
.label SPRITE = $3000
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
.label PERSP_Z = $2800
// Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$20;20]
// Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$20;20]
.label SINH = $2000
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$10,$10]
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$10,$10]
.label SINQ = $2200
// 16 bit Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$1f,$1f]
// 16 bit Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$1f,$1f]
.label SINH_LO = $4000
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
.label SINH_HI = $4200
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$0f,$0f]
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$0f,$0f]
.label SINQ_LO = $4400
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
.label SINQ_HI = $4600
.label COSH = SINH+$40
.label COSQ = SINQ+$40
@ -5730,10 +5730,10 @@ b33:
//SEG7 kickasm(location (const byte*) SPRITE#0) {{ .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) }}
//SEG8 kickasm(location (const signed byte*) PERSP_Z#0) {{ { .var d = 256.0 .var z0 = 6.0 // These values of d/z0 result in table values from $20 to $40 (effectively max is $3f) .for(var z=0;z<$100;z++) { .if(z>127) { .byte round(d / (z0 - ((z - 256) / 64.0))); } else { .byte round(d / (z0 - (z / 64.0))); } } } }}
//SEG9 kickasm(location (const signed byte*) SINH#0) {{ { .var min = -$2000 .var max = $2000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte round((min+(ampl/2)+(ampl/2)*sin(rad))/256) } } }}
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
//SEG10 kickasm(location (const signed byte*) SINQ#0) {{ { .var min = -$1000 .var max = $1000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte round((min+(ampl/2)+(ampl/2)*sin(rad))/256) } } }}
//SEG11 kickasm(location (const byte*) SINH_LO#0) {{ { .var min = -$2000 .var max = $2000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte <(min+(ampl/2)+(ampl/2)*sin(rad)) } } }}
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
//SEG12 kickasm(location (const byte*) SINH_HI#0) {{ { .var min = -$2000 .var max = $2000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte >(min+(ampl/2)+(ampl/2)*sin(rad)) } } }}
//SEG13 kickasm(location (const byte*) SINQ_LO#0) {{ { .var min = -$1000 .var max = $1000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte <(min+(ampl/2)+(ampl/2)*sin(rad)) } } }}
//SEG14 kickasm(location (const byte*) SINQ_HI#0) {{ { .var min = -$1000 .var max = $1000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte >(min+(ampl/2)+(ampl/2)*sin(rad)) } } }}
@ -5754,7 +5754,7 @@ main: {
//SEG21 main::@1
b1:
//SEG22 [15] *((const word*) psp1#0) ← ((word))(const byte*) mulf_sqr1#0 -- _deref_pwuc1=vwuc2
// mulf_init();
//mulf_init();
lda #<mulf_sqr1
sta psp1
lda #>mulf_sqr1
@ -5798,8 +5798,8 @@ anim: {
lda #0
sta sx
jmp b1
// signed byte xmin = 0;
// signed byte xmax = 0;
//signed byte xmin = 0;
//signed byte xmax = 0;
//SEG36 anim::@1
b1:
jmp b4
@ -5875,8 +5875,8 @@ anim: {
//SEG61 anim::@29
b29:
//SEG62 [38] *((const signed byte[8]) xrs#0 + (byte) anim::i#2) ← *((const signed byte*) xr#0) -- pbsc1_derefidx_vbuz1=_deref_pbsc2
// if(*xr<xmin) xmin = *xr;
// if(*xr>xmax) xmax = *xr;
//if(*xr<xmin) xmin = *xr;
//if(*xr>xmax) xmax = *xr;
ldy i
lda xr
sta xrs,y
@ -5943,7 +5943,7 @@ anim: {
lda #LIGHT_BLUE
sta BORDERCOL
//SEG80 [54] (signed byte) sx#3 ← (signed byte) sx#10 + (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbsz1=vbsz1_plus_2
// Increment angles
// Increment angles
inc sx
inc sx
//SEG81 [55] (signed byte) sy#3 ← (signed byte) sy#10 - (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbsz1=vbsz1_minus_vbuc1
@ -6413,7 +6413,7 @@ debug_print: {
rts
}
//SEG233 print_sbyte_at
// Print a signed byte as hex at a specific screen position
// Print a signed byte as hex at a specific screen position
print_sbyte_at: {
.label b = 9
.label at = 7
@ -6485,7 +6485,7 @@ print_sbyte_at: {
jmp b2_from_b5
}
//SEG256 print_char_at
// Print a single char
// Print a single char
print_char_at: {
.label at = $b
.label ch = $a
@ -6500,7 +6500,7 @@ print_char_at: {
rts
}
//SEG260 print_byte_at
// Print a byte as HEX at a specific position
// Print a byte as HEX at a specific position
print_byte_at: {
.label _0 = $2c
.label _2 = $2d
@ -6559,10 +6559,10 @@ print_byte_at: {
rts
}
//SEG278 rotate_matrix
// Rotate a 3D point (x,y,z) using the rotation matrix
// The rotation matrix is prepared by calling prepare_matrix()
// The passed points must be in the interval [-$3f;$3f].
// Implemented in assembler to utilize seriously fast multiplication
// Rotate a 3D point (x,y,z) using the rotation matrix
// The rotation matrix is prepared by calling prepare_matrix()
// The passed points must be in the interval [-$3f;$3f].
// Implemented in assembler to utilize seriously fast multiplication
rotate_matrix: {
.label x = $19
.label y = $1a
@ -6670,9 +6670,9 @@ rotate_matrix: {
rts
}
//SEG285 store_matrix
// Store the rotation matrix into the rotation routine rotate()
// After this each call to rotate() will rotate a point with the matrix
// Implemented in assembler to utilize seriously fast multiplication
// Store the rotation matrix into the rotation routine rotate()
// After this each call to rotate() will rotate a point with the matrix
// Implemented in assembler to utilize seriously fast multiplication
store_matrix: {
//SEG286 asm { ldarotation_matrix+0 starotate_matrix.A1+1 eor#$ff starotate_matrix.A2+1 ldarotation_matrix+1 starotate_matrix.B1+1 eor#$ff starotate_matrix.B2+1 ldarotation_matrix+2 starotate_matrix.C1+1 eor#$ff starotate_matrix.C2+1 ldarotation_matrix+3 starotate_matrix.D1+1 eor#$ff starotate_matrix.D2+1 ldarotation_matrix+4 starotate_matrix.E1+1 eor#$ff starotate_matrix.E2+1 ldarotation_matrix+5 starotate_matrix.F1+1 eor#$ff starotate_matrix.F2+1 ldarotation_matrix+6 starotate_matrix.G1+1 eor#$ff starotate_matrix.G2+1 ldarotation_matrix+7 starotate_matrix.H1+1 eor#$ff starotate_matrix.H2+1 ldarotation_matrix+8 starotate_matrix.I1+1 eor#$ff starotate_matrix.I2+1 }
lda rotation_matrix+0
@ -6718,9 +6718,9 @@ store_matrix: {
rts
}
//SEG289 calculate_matrix
// Prepare the 3x3 rotation matrix into rotation_matrix[]
// Angles sx, sy, sz are based on 2*PI=$100
// Method described in C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// Prepare the 3x3 rotation matrix into rotation_matrix[]
// Angles sx, sy, sz are based on 2*PI=$100
// Method described in C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
calculate_matrix: {
.label _10 = $38
.label _11 = $39
@ -7571,7 +7571,7 @@ debug_print_init: {
str11: .text "yp@"
}
//SEG479 print_str_at
// Print a string at a specific screen position
// Print a string at a specific screen position
print_str_at: {
.label at = $12
.label str = $10
@ -7613,7 +7613,7 @@ print_str_at: {
jmp b1_from_b2
}
//SEG491 print_cls
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = $14
//SEG492 [268] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1]
@ -7653,7 +7653,7 @@ print_cls: {
rts
}
//SEG502 sprites_init
// Initialize sprites
// Initialize sprites
sprites_init: {
.label SCREEN = $400
.label sprites_ptr = SCREEN+$3f8
@ -7695,18 +7695,18 @@ sprites_init: {
}
print_hextab: .text "0123456789abcdef"
zs: .byte $34, $34, $34, $34, $34, $34, $34, $34
// Rotated positions
// Rotated positions
xrs: .fill 8, 0
yrs: .fill 8, 0
zrs: .fill 8, 0
// Persepctive factors (from zrs)
// Persepctive factors (from zrs)
pps: .fill 8, 0
// Rotated positions with persepctive
// Rotated positions with persepctive
xps: .fill 8, 0
yps: .fill 8, 0
// The rotation matrix
// The rotation matrix
rotation_matrix: .fill 9, 0
// Positions to rotate
// Positions to rotate
xs: .byte -$34, -$34, -$34, 0, 0, $34, $34, $34
ys: .byte -$34, 0, $34, -$34, $34, -$34, 0, $34
.pc = mulf_sqr1 "mulf_sqr1"
@ -8463,10 +8463,10 @@ Allocated (was zp ZP_BYTE:55) zp ZP_BYTE:16 [ calculate_matrix::t10#0 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -8482,45 +8482,45 @@ ASSEMBLER BEFORE OPTIMIZATION
.const LIGHT_BLUE = $e
.const LIGHT_GREY = $f
.label print_line_cursor = $400
// 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
.const sz = 0
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
.label mulf_sqr1 = $2400
// g(x) = >((( 1 - x ) * ( 1 - x )))
// g(x) = >((( 1 - x ) * ( 1 - x )))
.label mulf_sqr2 = $2600
// A single sprite
// A single sprite
.label SPRITE = $3000
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
.label PERSP_Z = $2800
// Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$20;20]
// Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$20;20]
.label SINH = $2000
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$10,$10]
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$10,$10]
.label SINQ = $2200
// 16 bit Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$1f,$1f]
// 16 bit Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$1f,$1f]
.label SINH_LO = $4000
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
.label SINH_HI = $4200
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$0f,$0f]
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$0f,$0f]
.label SINQ_LO = $4400
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
.label SINQ_HI = $4600
.label COSH = SINH+$40
.label COSQ = SINQ+$40
@ -8536,10 +8536,10 @@ b33:
//SEG7 kickasm(location (const byte*) SPRITE#0) {{ .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) }}
//SEG8 kickasm(location (const signed byte*) PERSP_Z#0) {{ { .var d = 256.0 .var z0 = 6.0 // These values of d/z0 result in table values from $20 to $40 (effectively max is $3f) .for(var z=0;z<$100;z++) { .if(z>127) { .byte round(d / (z0 - ((z - 256) / 64.0))); } else { .byte round(d / (z0 - (z / 64.0))); } } } }}
//SEG9 kickasm(location (const signed byte*) SINH#0) {{ { .var min = -$2000 .var max = $2000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte round((min+(ampl/2)+(ampl/2)*sin(rad))/256) } } }}
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
//SEG10 kickasm(location (const signed byte*) SINQ#0) {{ { .var min = -$1000 .var max = $1000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte round((min+(ampl/2)+(ampl/2)*sin(rad))/256) } } }}
//SEG11 kickasm(location (const byte*) SINH_LO#0) {{ { .var min = -$2000 .var max = $2000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte <(min+(ampl/2)+(ampl/2)*sin(rad)) } } }}
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
//SEG12 kickasm(location (const byte*) SINH_HI#0) {{ { .var min = -$2000 .var max = $2000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte >(min+(ampl/2)+(ampl/2)*sin(rad)) } } }}
//SEG13 kickasm(location (const byte*) SINQ_LO#0) {{ { .var min = -$1000 .var max = $1000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte <(min+(ampl/2)+(ampl/2)*sin(rad)) } } }}
//SEG14 kickasm(location (const byte*) SINQ_HI#0) {{ { .var min = -$1000 .var max = $1000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte >(min+(ampl/2)+(ampl/2)*sin(rad)) } } }}
@ -8560,7 +8560,7 @@ main: {
//SEG21 main::@1
b1:
//SEG22 [15] *((const word*) psp1#0) ← ((word))(const byte*) mulf_sqr1#0 -- _deref_pwuc1=vwuc2
// mulf_init();
//mulf_init();
lda #<mulf_sqr1
sta psp1
lda #>mulf_sqr1
@ -8601,8 +8601,8 @@ anim: {
lda #0
sta sx
jmp b1
// signed byte xmin = 0;
// signed byte xmax = 0;
//signed byte xmin = 0;
//signed byte xmax = 0;
//SEG36 anim::@1
b1:
jmp b4
@ -8674,8 +8674,8 @@ anim: {
//SEG61 anim::@29
b29:
//SEG62 [38] *((const signed byte[8]) xrs#0 + (byte) anim::i#2) ← *((const signed byte*) xr#0) -- pbsc1_derefidx_vbuz1=_deref_pbsc2
// if(*xr<xmin) xmin = *xr;
// if(*xr>xmax) xmax = *xr;
//if(*xr<xmin) xmin = *xr;
//if(*xr>xmax) xmax = *xr;
ldy i
lda xr
sta xrs,y
@ -8736,7 +8736,7 @@ anim: {
lda #LIGHT_BLUE
sta BORDERCOL
//SEG80 [54] (signed byte) sx#3 ← (signed byte) sx#10 + (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbsz1=vbsz1_plus_2
// Increment angles
// Increment angles
inc sx
inc sx
//SEG81 [55] (signed byte) sy#3 ← (signed byte) sy#10 - (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbsz1=vbsz1_minus_vbuc1
@ -9163,7 +9163,7 @@ debug_print: {
rts
}
//SEG233 print_sbyte_at
// Print a signed byte as hex at a specific screen position
// Print a signed byte as hex at a specific screen position
print_sbyte_at: {
.label at = 6
//SEG234 [115] if((signed byte) print_sbyte_at::b#22<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte_at::@1 -- vbsxx_lt_0_then_la1
@ -9223,7 +9223,7 @@ print_sbyte_at: {
jmp b2_from_b5
}
//SEG256 print_char_at
// Print a single char
// Print a single char
print_char_at: {
.label at = 6
.label ch = 8
@ -9238,7 +9238,7 @@ print_char_at: {
rts
}
//SEG260 print_byte_at
// Print a byte as HEX at a specific position
// Print a byte as HEX at a specific position
print_byte_at: {
.label at = 6
//SEG261 [128] (byte~) print_byte_at::$0 ← (byte)(signed byte) print_sbyte_at::b#24 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4
@ -9286,10 +9286,10 @@ print_byte_at: {
rts
}
//SEG278 rotate_matrix
// Rotate a 3D point (x,y,z) using the rotation matrix
// The rotation matrix is prepared by calling prepare_matrix()
// The passed points must be in the interval [-$3f;$3f].
// Implemented in assembler to utilize seriously fast multiplication
// Rotate a 3D point (x,y,z) using the rotation matrix
// The rotation matrix is prepared by calling prepare_matrix()
// The passed points must be in the interval [-$3f;$3f].
// Implemented in assembler to utilize seriously fast multiplication
rotate_matrix: {
.label x = 5
//SEG279 [137] *((const signed byte*) xr#0) ← (signed byte) rotate_matrix::x#0 -- _deref_pbsc1=vbsz1
@ -9395,9 +9395,9 @@ rotate_matrix: {
rts
}
//SEG285 store_matrix
// Store the rotation matrix into the rotation routine rotate()
// After this each call to rotate() will rotate a point with the matrix
// Implemented in assembler to utilize seriously fast multiplication
// Store the rotation matrix into the rotation routine rotate()
// After this each call to rotate() will rotate a point with the matrix
// Implemented in assembler to utilize seriously fast multiplication
store_matrix: {
//SEG286 asm { ldarotation_matrix+0 starotate_matrix.A1+1 eor#$ff starotate_matrix.A2+1 ldarotation_matrix+1 starotate_matrix.B1+1 eor#$ff starotate_matrix.B2+1 ldarotation_matrix+2 starotate_matrix.C1+1 eor#$ff starotate_matrix.C2+1 ldarotation_matrix+3 starotate_matrix.D1+1 eor#$ff starotate_matrix.D2+1 ldarotation_matrix+4 starotate_matrix.E1+1 eor#$ff starotate_matrix.E2+1 ldarotation_matrix+5 starotate_matrix.F1+1 eor#$ff starotate_matrix.F2+1 ldarotation_matrix+6 starotate_matrix.G1+1 eor#$ff starotate_matrix.G2+1 ldarotation_matrix+7 starotate_matrix.H1+1 eor#$ff starotate_matrix.H2+1 ldarotation_matrix+8 starotate_matrix.I1+1 eor#$ff starotate_matrix.I2+1 }
lda rotation_matrix+0
@ -9443,9 +9443,9 @@ store_matrix: {
rts
}
//SEG289 calculate_matrix
// Prepare the 3x3 rotation matrix into rotation_matrix[]
// Angles sx, sy, sz are based on 2*PI=$100
// Method described in C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// Prepare the 3x3 rotation matrix into rotation_matrix[]
// Angles sx, sy, sz are based on 2*PI=$100
// Method described in C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
calculate_matrix: {
.label sy = 3
.label t1 = 4
@ -10217,7 +10217,7 @@ debug_print_init: {
str11: .text "yp@"
}
//SEG479 print_str_at
// Print a string at a specific screen position
// Print a string at a specific screen position
print_str_at: {
.label at = 9
.label str = 6
@ -10259,7 +10259,7 @@ print_str_at: {
jmp b1_from_b2
}
//SEG491 print_cls
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = 6
//SEG492 [268] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1]
@ -10299,7 +10299,7 @@ print_cls: {
rts
}
//SEG502 sprites_init
// Initialize sprites
// Initialize sprites
sprites_init: {
.label SCREEN = $400
.label sprites_ptr = SCREEN+$3f8
@ -10336,18 +10336,18 @@ sprites_init: {
}
print_hextab: .text "0123456789abcdef"
zs: .byte $34, $34, $34, $34, $34, $34, $34, $34
// Rotated positions
// Rotated positions
xrs: .fill 8, 0
yrs: .fill 8, 0
zrs: .fill 8, 0
// Persepctive factors (from zrs)
// Persepctive factors (from zrs)
pps: .fill 8, 0
// Rotated positions with persepctive
// Rotated positions with persepctive
xps: .fill 8, 0
yps: .fill 8, 0
// The rotation matrix
// The rotation matrix
rotation_matrix: .fill 9, 0
// Positions to rotate
// Positions to rotate
xs: .byte -$34, -$34, -$34, 0, 0, $34, $34, $34
ys: .byte -$34, 0, $34, -$34, $34, -$34, 0, $34
.pc = mulf_sqr1 "mulf_sqr1"
@ -11356,10 +11356,10 @@ FINAL ASSEMBLER
Score: 85538
//SEG0 File Comments
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
@ -11375,45 +11375,45 @@ Score: 85538
.const LIGHT_BLUE = $e
.const LIGHT_GREY = $f
.label print_line_cursor = $400
// 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
.const sz = 0
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
.label mulf_sqr1 = $2400
// g(x) = >((( 1 - x ) * ( 1 - x )))
// g(x) = >((( 1 - x ) * ( 1 - x )))
.label mulf_sqr2 = $2600
// A single sprite
// A single sprite
.label SPRITE = $3000
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
.label PERSP_Z = $2800
// Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$20;20]
// Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$20;20]
.label SINH = $2000
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$10,$10]
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$10,$10]
.label SINQ = $2200
// 16 bit Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$1f,$1f]
// 16 bit Sine and Cosine Tables
// Angles: $00=0, $80=PI,$100=2*PI
// Half Sine/Cosine: signed fixed [-$1f,$1f]
.label SINH_LO = $4000
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
.label SINH_HI = $4200
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$0f,$0f]
// sin(x) = cos(x+PI/2)
// Quarter Sine/Cosine: signed fixed [-$0f,$0f]
.label SINQ_LO = $4400
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
.label SINQ_HI = $4600
.label COSH = SINH+$40
.label COSQ = SINQ+$40
@ -11426,10 +11426,10 @@ Score: 85538
//SEG7 kickasm(location (const byte*) SPRITE#0) {{ .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) }}
//SEG8 kickasm(location (const signed byte*) PERSP_Z#0) {{ { .var d = 256.0 .var z0 = 6.0 // These values of d/z0 result in table values from $20 to $40 (effectively max is $3f) .for(var z=0;z<$100;z++) { .if(z>127) { .byte round(d / (z0 - ((z - 256) / 64.0))); } else { .byte round(d / (z0 - (z / 64.0))); } } } }}
//SEG9 kickasm(location (const signed byte*) SINH#0) {{ { .var min = -$2000 .var max = $2000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte round((min+(ampl/2)+(ampl/2)*sin(rad))/256) } } }}
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
//SEG10 kickasm(location (const signed byte*) SINQ#0) {{ { .var min = -$1000 .var max = $1000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte round((min+(ampl/2)+(ampl/2)*sin(rad))/256) } } }}
//SEG11 kickasm(location (const byte*) SINH_LO#0) {{ { .var min = -$2000 .var max = $2000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte <(min+(ampl/2)+(ampl/2)*sin(rad)) } } }}
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
//SEG12 kickasm(location (const byte*) SINH_HI#0) {{ { .var min = -$2000 .var max = $2000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte >(min+(ampl/2)+(ampl/2)*sin(rad)) } } }}
//SEG13 kickasm(location (const byte*) SINQ_LO#0) {{ { .var min = -$1000 .var max = $1000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte <(min+(ampl/2)+(ampl/2)*sin(rad)) } } }}
//SEG14 kickasm(location (const byte*) SINQ_HI#0) {{ { .var min = -$1000 .var max = $1000 .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte >(min+(ampl/2)+(ampl/2)*sin(rad)) } } }}
@ -11444,7 +11444,7 @@ main: {
jsr sprites_init
//SEG21 main::@1
//SEG22 [15] *((const word*) psp1#0) ← ((word))(const byte*) mulf_sqr1#0 -- _deref_pwuc1=vwuc2
// mulf_init();
//mulf_init();
lda #<mulf_sqr1
sta psp1
lda #>mulf_sqr1
@ -11475,8 +11475,8 @@ anim: {
sta sy
//SEG35 [22] phi (signed byte) sx#10 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:anim->anim::@1#1] -- vbsz1=vbuc1
sta sx
// signed byte xmin = 0;
// signed byte xmax = 0;
//signed byte xmin = 0;
//signed byte xmax = 0;
//SEG36 anim::@1
//SEG37 anim::@4
b4:
@ -11532,8 +11532,8 @@ anim: {
jsr rotate_matrix
//SEG61 anim::@29
//SEG62 [38] *((const signed byte[8]) xrs#0 + (byte) anim::i#2) ← *((const signed byte*) xr#0) -- pbsc1_derefidx_vbuz1=_deref_pbsc2
// if(*xr<xmin) xmin = *xr;
// if(*xr>xmax) xmax = *xr;
//if(*xr<xmin) xmin = *xr;
//if(*xr>xmax) xmax = *xr;
ldy i
lda xr
sta xrs,y
@ -11585,7 +11585,7 @@ anim: {
lda #LIGHT_BLUE
sta BORDERCOL
//SEG80 [54] (signed byte) sx#3 ← (signed byte) sx#10 + (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbsz1=vbsz1_plus_2
// Increment angles
// Increment angles
inc sx
inc sx
//SEG81 [55] (signed byte) sy#3 ← (signed byte) sy#10 - (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbsz1=vbsz1_minus_vbuc1
@ -11932,7 +11932,7 @@ debug_print: {
rts
}
//SEG233 print_sbyte_at
// Print a signed byte as hex at a specific screen position
// Print a signed byte as hex at a specific screen position
print_sbyte_at: {
.label at = 6
//SEG234 [115] if((signed byte) print_sbyte_at::b#22<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte_at::@1 -- vbsxx_lt_0_then_la1
@ -11981,7 +11981,7 @@ print_sbyte_at: {
jmp b2
}
//SEG256 print_char_at
// Print a single char
// Print a single char
print_char_at: {
.label at = 6
.label ch = 8
@ -11994,7 +11994,7 @@ print_char_at: {
rts
}
//SEG260 print_byte_at
// Print a byte as HEX at a specific position
// Print a byte as HEX at a specific position
print_byte_at: {
.label at = 6
//SEG261 [128] (byte~) print_byte_at::$0 ← (byte)(signed byte) print_sbyte_at::b#24 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4
@ -12036,10 +12036,10 @@ print_byte_at: {
rts
}
//SEG278 rotate_matrix
// Rotate a 3D point (x,y,z) using the rotation matrix
// The rotation matrix is prepared by calling prepare_matrix()
// The passed points must be in the interval [-$3f;$3f].
// Implemented in assembler to utilize seriously fast multiplication
// Rotate a 3D point (x,y,z) using the rotation matrix
// The rotation matrix is prepared by calling prepare_matrix()
// The passed points must be in the interval [-$3f;$3f].
// Implemented in assembler to utilize seriously fast multiplication
rotate_matrix: {
.label x = 5
//SEG279 [137] *((const signed byte*) xr#0) ← (signed byte) rotate_matrix::x#0 -- _deref_pbsc1=vbsz1
@ -12143,9 +12143,9 @@ rotate_matrix: {
rts
}
//SEG285 store_matrix
// Store the rotation matrix into the rotation routine rotate()
// After this each call to rotate() will rotate a point with the matrix
// Implemented in assembler to utilize seriously fast multiplication
// Store the rotation matrix into the rotation routine rotate()
// After this each call to rotate() will rotate a point with the matrix
// Implemented in assembler to utilize seriously fast multiplication
store_matrix: {
//SEG286 asm { ldarotation_matrix+0 starotate_matrix.A1+1 eor#$ff starotate_matrix.A2+1 ldarotation_matrix+1 starotate_matrix.B1+1 eor#$ff starotate_matrix.B2+1 ldarotation_matrix+2 starotate_matrix.C1+1 eor#$ff starotate_matrix.C2+1 ldarotation_matrix+3 starotate_matrix.D1+1 eor#$ff starotate_matrix.D2+1 ldarotation_matrix+4 starotate_matrix.E1+1 eor#$ff starotate_matrix.E2+1 ldarotation_matrix+5 starotate_matrix.F1+1 eor#$ff starotate_matrix.F2+1 ldarotation_matrix+6 starotate_matrix.G1+1 eor#$ff starotate_matrix.G2+1 ldarotation_matrix+7 starotate_matrix.H1+1 eor#$ff starotate_matrix.H2+1 ldarotation_matrix+8 starotate_matrix.I1+1 eor#$ff starotate_matrix.I2+1 }
lda rotation_matrix+0
@ -12189,9 +12189,9 @@ store_matrix: {
rts
}
//SEG289 calculate_matrix
// Prepare the 3x3 rotation matrix into rotation_matrix[]
// Angles sx, sy, sz are based on 2*PI=$100
// Method described in C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// Prepare the 3x3 rotation matrix into rotation_matrix[]
// Angles sx, sy, sz are based on 2*PI=$100
// Method described in C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
calculate_matrix: {
.label sy = 3
.label t1 = 4
@ -12887,7 +12887,7 @@ debug_print_init: {
str11: .text "yp@"
}
//SEG479 print_str_at
// Print a string at a specific screen position
// Print a string at a specific screen position
print_str_at: {
.label at = 9
.label str = 6
@ -12923,7 +12923,7 @@ print_str_at: {
jmp b1
}
//SEG491 print_cls
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = 6
//SEG492 [268] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1]
@ -12957,7 +12957,7 @@ print_cls: {
rts
}
//SEG502 sprites_init
// Initialize sprites
// Initialize sprites
sprites_init: {
.label SCREEN = $400
.label sprites_ptr = SCREEN+$3f8
@ -12988,18 +12988,18 @@ sprites_init: {
}
print_hextab: .text "0123456789abcdef"
zs: .byte $34, $34, $34, $34, $34, $34, $34, $34
// Rotated positions
// Rotated positions
xrs: .fill 8, 0
yrs: .fill 8, 0
zrs: .fill 8, 0
// Persepctive factors (from zrs)
// Persepctive factors (from zrs)
pps: .fill 8, 0
// Rotated positions with persepctive
// Rotated positions with persepctive
xps: .fill 8, 0
yps: .fill 8, 0
// The rotation matrix
// The rotation matrix
rotation_matrix: .fill 9, 0
// Positions to rotate
// Positions to rotate
xs: .byte -$34, -$34, -$34, 0, 0, $34, $34, $34
ys: .byte -$34, 0, $34, -$34, $34, -$34, 0, $34
.pc = mulf_sqr1 "mulf_sqr1"

View File

@ -1,18 +1,18 @@
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
.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
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
.label PERSP_Z = $2400
.label print_char_cursor = 4
.label print_line_cursor = 2
@ -89,7 +89,7 @@ do_perspective: {
str4: .text ",@"
str5: .text ")@"
}
// Print a newline
// Print a newline
print_ln: {
lda #<$400
sta print_line_cursor
@ -113,7 +113,7 @@ print_ln: {
!:
rts
}
// Print a zero-terminated string
// Print a zero-terminated string
print_str: {
.label str = 2
b1:
@ -136,7 +136,7 @@ print_str: {
!:
jmp b1
}
// Print a byte as HEX
// Print a byte as HEX
print_byte: {
txa
lsr
@ -153,7 +153,7 @@ print_byte: {
jsr print_char
rts
}
// Print a single char
// Print a single char
print_char: {
ldy #0
sta (print_char_cursor),y
@ -163,8 +163,8 @@ print_char: {
!:
rts
}
// Apply perspective to a 3d-point. Result is returned in (*xr,*yr)
// Implemented in assembler to utilize seriously fast multiplication
// Apply perspective to a 3d-point. Result is returned in (*xr,*yr)
// Implemented in assembler to utilize seriously fast multiplication
perspective: {
lda #do_perspective.x
sta xr
@ -192,7 +192,7 @@ perspective: {
sta xr
rts
}
// Print a signed byte as HEX
// Print a signed byte as HEX
print_sbyte: {
cpx #0
bmi b1
@ -211,7 +211,7 @@ print_sbyte: {
tax
jmp b2
}
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = 2
lda #<$400
@ -234,7 +234,7 @@ print_cls: {
bne b1
rts
}
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x) and g(x) = f(1-x)
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x) and g(x) = f(1-x)
mulf_init: {
.label val = 6
.label sqr = 2
@ -301,19 +301,19 @@ mulf_init: {
rts
}
print_hextab: .text "0123456789abcdef"
// Multiplication tables for seriously fast multiplication.
// This version is optimized for speed over accuracy
// - It can multiply signed numbers with no extra code - but only for numbers in [-$3f;$3f]
// - It throws away the low part of the 32-bit result
// - It return >a*b*4 to maximize precision (when passed maximal input values $3f*$3f the result is $3e)
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
// Multiplication tables for seriously fast multiplication.
// This version is optimized for speed over accuracy
// - It can multiply signed numbers with no extra code - but only for numbers in [-$3f;$3f]
// - It throws away the low part of the 32-bit result
// - It return >a*b*4 to maximize precision (when passed maximal input values $3f*$3f the result is $3e)
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
.align $100
mulf_sqr1: .fill $200, 0
// g(x) = >((( 1 - x ) * ( 1 - x )))
// g(x) = >((( 1 - x ) * ( 1 - x )))
.align $100
mulf_sqr2: .fill $200, 0
.pc = PERSP_Z "PERSP_Z"

View File

@ -1928,23 +1928,23 @@ Allocated zp ZP_BYTE:24 [ mulf_init::$10 ]
INITIAL ASM
//SEG0 File Comments
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// 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
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
.label PERSP_Z = $2400
.label print_char_cursor = 8
.label print_line_cursor = 2
@ -2184,7 +2184,7 @@ do_perspective: {
str5: .text ")@"
}
//SEG95 print_ln
// Print a newline
// Print a newline
print_ln: {
//SEG96 [40] phi from print_ln to print_ln::@1 [phi:print_ln->print_ln::@1]
b1_from_print_ln:
@ -2224,7 +2224,7 @@ print_ln: {
rts
}
//SEG105 print_str
// Print a zero-terminated string
// Print a zero-terminated string
print_str: {
.label str = 4
//SEG106 [45] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1]
@ -2265,7 +2265,7 @@ print_str: {
jmp b1_from_b2
}
//SEG117 print_byte
// Print a byte as HEX
// Print a byte as HEX
print_byte: {
.label _0 = $12
.label _2 = $13
@ -2311,7 +2311,7 @@ print_byte: {
rts
}
//SEG133 print_char
// Print a single char
// Print a single char
print_char: {
.label ch = 7
//SEG134 [60] *((byte*) print_char_cursor#44) ← (byte) print_char::ch#4 -- _deref_pbuz1=vbuz2
@ -2330,8 +2330,8 @@ print_char: {
rts
}
//SEG138 perspective
// Apply perspective to a 3d-point. Result is returned in (*xr,*yr)
// Implemented in assembler to utilize seriously fast multiplication
// Apply perspective to a 3d-point. Result is returned in (*xr,*yr)
// Implemented in assembler to utilize seriously fast multiplication
perspective: {
//SEG139 [63] *((const signed byte*) xr#0) ← (const signed byte) do_perspective::x#0 -- _deref_pbsc1=vbsc2
lda #do_perspective.x
@ -2369,7 +2369,7 @@ perspective: {
rts
}
//SEG145 print_sbyte
// Print a signed byte as HEX
// Print a signed byte as HEX
print_sbyte: {
.label b = $a
//SEG146 [69] if((signed byte) print_sbyte::b#4<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsz1_lt_0_then_la1
@ -2434,7 +2434,7 @@ print_sbyte: {
jmp b2_from_b5
}
//SEG171 print_cls
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = $b
//SEG172 [80] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1]
@ -2474,7 +2474,7 @@ print_cls: {
rts
}
//SEG182 mulf_init
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x) and g(x) = f(1-x)
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x) and g(x) = f(1-x)
mulf_init: {
.label _2 = $15
.label _4 = $16
@ -2594,19 +2594,19 @@ mulf_init: {
rts
}
print_hextab: .text "0123456789abcdef"
// Multiplication tables for seriously fast multiplication.
// This version is optimized for speed over accuracy
// - It can multiply signed numbers with no extra code - but only for numbers in [-$3f;$3f]
// - It throws away the low part of the 32-bit result
// - It return >a*b*4 to maximize precision (when passed maximal input values $3f*$3f the result is $3e)
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
// Multiplication tables for seriously fast multiplication.
// This version is optimized for speed over accuracy
// - It can multiply signed numbers with no extra code - but only for numbers in [-$3f;$3f]
// - It throws away the low part of the 32-bit result
// - It return >a*b*4 to maximize precision (when passed maximal input values $3f*$3f the result is $3e)
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
.align $100
mulf_sqr1: .fill $200, 0
// g(x) = >((( 1 - x ) * ( 1 - x )))
// g(x) = >((( 1 - x ) * ( 1 - x )))
.align $100
mulf_sqr2: .fill $200, 0
.pc = PERSP_Z "PERSP_Z"
@ -2745,23 +2745,23 @@ Allocated (was zp ZP_BYTE:20) zp ZP_BYTE:6 [ mulf_init::val#0 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// 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
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
.label PERSP_Z = $2400
.label print_char_cursor = 4
.label print_line_cursor = 2
@ -2996,7 +2996,7 @@ do_perspective: {
str5: .text ")@"
}
//SEG95 print_ln
// Print a newline
// Print a newline
print_ln: {
//SEG96 [40] phi from print_ln to print_ln::@1 [phi:print_ln->print_ln::@1]
b1_from_print_ln:
@ -3036,7 +3036,7 @@ print_ln: {
rts
}
//SEG105 print_str
// Print a zero-terminated string
// Print a zero-terminated string
print_str: {
.label str = 2
//SEG106 [45] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1]
@ -3077,7 +3077,7 @@ print_str: {
jmp b1_from_b2
}
//SEG117 print_byte
// Print a byte as HEX
// Print a byte as HEX
print_byte: {
//SEG118 [52] (byte~) print_byte::$0 ← (byte) print_byte::b#3 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4
txa
@ -3116,7 +3116,7 @@ print_byte: {
rts
}
//SEG133 print_char
// Print a single char
// Print a single char
print_char: {
//SEG134 [60] *((byte*) print_char_cursor#44) ← (byte) print_char::ch#4 -- _deref_pbuz1=vbuaa
ldy #0
@ -3133,8 +3133,8 @@ print_char: {
rts
}
//SEG138 perspective
// Apply perspective to a 3d-point. Result is returned in (*xr,*yr)
// Implemented in assembler to utilize seriously fast multiplication
// Apply perspective to a 3d-point. Result is returned in (*xr,*yr)
// Implemented in assembler to utilize seriously fast multiplication
perspective: {
//SEG139 [63] *((const signed byte*) xr#0) ← (const signed byte) do_perspective::x#0 -- _deref_pbsc1=vbsc2
lda #do_perspective.x
@ -3172,7 +3172,7 @@ perspective: {
rts
}
//SEG145 print_sbyte
// Print a signed byte as HEX
// Print a signed byte as HEX
print_sbyte: {
//SEG146 [69] if((signed byte) print_sbyte::b#4<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsxx_lt_0_then_la1
cpx #0
@ -3232,7 +3232,7 @@ print_sbyte: {
jmp b2_from_b5
}
//SEG171 print_cls
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = 2
//SEG172 [80] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1]
@ -3272,7 +3272,7 @@ print_cls: {
rts
}
//SEG182 mulf_init
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x) and g(x) = f(1-x)
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x) and g(x) = f(1-x)
mulf_init: {
.label val = 6
.label sqr = 2
@ -3379,19 +3379,19 @@ mulf_init: {
rts
}
print_hextab: .text "0123456789abcdef"
// Multiplication tables for seriously fast multiplication.
// This version is optimized for speed over accuracy
// - It can multiply signed numbers with no extra code - but only for numbers in [-$3f;$3f]
// - It throws away the low part of the 32-bit result
// - It return >a*b*4 to maximize precision (when passed maximal input values $3f*$3f the result is $3e)
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
// Multiplication tables for seriously fast multiplication.
// This version is optimized for speed over accuracy
// - It can multiply signed numbers with no extra code - but only for numbers in [-$3f;$3f]
// - It throws away the low part of the 32-bit result
// - It return >a*b*4 to maximize precision (when passed maximal input values $3f*$3f the result is $3e)
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
.align $100
mulf_sqr1: .fill $200, 0
// g(x) = >((( 1 - x ) * ( 1 - x )))
// g(x) = >((( 1 - x ) * ( 1 - x )))
.align $100
mulf_sqr2: .fill $200, 0
.pc = PERSP_Z "PERSP_Z"
@ -3776,23 +3776,23 @@ FINAL ASSEMBLER
Score: 3781
//SEG0 File Comments
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
// 3D Rotation using a Rotation Matrix
// Based on:
// - C= Hacking Magazine Issue 8. http://www.ffd2.com/fridge/chacking/c=hacking8.txt
// - Codebase64 Article http://codebase64.org/doku.php?id=base:3d_rotation
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// 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
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
// Perspective multiplication table containing (d/(z0-z)[z] for each z-value
.label PERSP_Z = $2400
.label print_char_cursor = 4
.label print_line_cursor = 2
@ -3962,7 +3962,7 @@ do_perspective: {
str5: .text ")@"
}
//SEG95 print_ln
// Print a newline
// Print a newline
print_ln: {
//SEG96 [40] phi from print_ln to print_ln::@1 [phi:print_ln->print_ln::@1]
//SEG97 [40] phi (byte*) print_line_cursor#11 = ((byte*))(word/signed word/dword/signed dword) 1024 [phi:print_ln->print_ln::@1#0] -- pbuz1=pbuc1
@ -3996,7 +3996,7 @@ print_ln: {
rts
}
//SEG105 print_str
// Print a zero-terminated string
// Print a zero-terminated string
print_str: {
.label str = 2
//SEG106 [45] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1]
@ -4031,7 +4031,7 @@ print_str: {
jmp b1
}
//SEG117 print_byte
// Print a byte as HEX
// Print a byte as HEX
print_byte: {
//SEG118 [52] (byte~) print_byte::$0 ← (byte) print_byte::b#3 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuxx_ror_4
txa
@ -4064,7 +4064,7 @@ print_byte: {
rts
}
//SEG133 print_char
// Print a single char
// Print a single char
print_char: {
//SEG134 [60] *((byte*) print_char_cursor#44) ← (byte) print_char::ch#4 -- _deref_pbuz1=vbuaa
ldy #0
@ -4079,8 +4079,8 @@ print_char: {
rts
}
//SEG138 perspective
// Apply perspective to a 3d-point. Result is returned in (*xr,*yr)
// Implemented in assembler to utilize seriously fast multiplication
// Apply perspective to a 3d-point. Result is returned in (*xr,*yr)
// Implemented in assembler to utilize seriously fast multiplication
perspective: {
//SEG139 [63] *((const signed byte*) xr#0) ← (const signed byte) do_perspective::x#0 -- _deref_pbsc1=vbsc2
lda #do_perspective.x
@ -4115,7 +4115,7 @@ perspective: {
rts
}
//SEG145 print_sbyte
// Print a signed byte as HEX
// Print a signed byte as HEX
print_sbyte: {
//SEG146 [69] if((signed byte) print_sbyte::b#4<(byte/signed byte/word/signed word/dword/signed dword) 0) goto print_sbyte::@1 -- vbsxx_lt_0_then_la1
cpx #0
@ -4160,7 +4160,7 @@ print_sbyte: {
jmp b2
}
//SEG171 print_cls
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = 2
//SEG172 [80] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1]
@ -4194,7 +4194,7 @@ print_cls: {
rts
}
//SEG182 mulf_init
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x) and g(x) = f(1-x)
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x) and g(x) = f(1-x)
mulf_init: {
.label val = 6
.label sqr = 2
@ -4289,19 +4289,19 @@ mulf_init: {
rts
}
print_hextab: .text "0123456789abcdef"
// Multiplication tables for seriously fast multiplication.
// This version is optimized for speed over accuracy
// - It can multiply signed numbers with no extra code - but only for numbers in [-$3f;$3f]
// - It throws away the low part of the 32-bit result
// - It return >a*b*4 to maximize precision (when passed maximal input values $3f*$3f the result is $3e)
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
// Multiplication tables for seriously fast multiplication.
// This version is optimized for speed over accuracy
// - It can multiply signed numbers with no extra code - but only for numbers in [-$3f;$3f]
// - It throws away the low part of the 32-bit result
// - It return >a*b*4 to maximize precision (when passed maximal input values $3f*$3f the result is $3e)
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
.align $100
mulf_sqr1: .fill $200, 0
// g(x) = >((( 1 - x ) * ( 1 - x )))
// g(x) = >((( 1 - x ) * ( 1 - x )))
.align $100
mulf_sqr2: .fill $200, 0
.pc = PERSP_Z "PERSP_Z"

View File

@ -47,7 +47,7 @@ lines: {
bcc b1
rts
}
// Draw a line on the bitmap
// Draw a line on the bitmap
bitmap_line: {
.label xd = 4
.label yd = 3
@ -326,7 +326,7 @@ init_screen: {
bne b1
rts
}
// Clear all graphics on the bitmap
// Clear all graphics on the bitmap
bitmap_clear: {
.label bitmap = 9
.label y = 2
@ -356,7 +356,7 @@ bitmap_clear: {
bne b1
rts
}
// Initialize the bitmap plotter tables for a specific bitmap
// Initialize the bitmap plotter tables for a specific bitmap
bitmap_init: {
.label _6 = 2
.label yoffs = 9
@ -410,7 +410,7 @@ bitmap_init: {
bne b3
rts
}
// Tables for the plotter - initialized by calling bitmap_draw_init();
// Tables for the plotter - initialized by calling bitmap_draw_init();
bitmap_plot_xlo: .fill $100, 0
bitmap_plot_xhi: .fill $100, 0
bitmap_plot_ylo: .fill $100, 0

View File

@ -2952,7 +2952,7 @@ lines: {
rts
}
//SEG43 bitmap_line
// Draw a line on the bitmap
// Draw a line on the bitmap
bitmap_line: {
.label xd = $2f
.label xd_1 = $2c
@ -3666,7 +3666,7 @@ init_screen: {
rts
}
//SEG300 bitmap_clear
// Clear all graphics on the bitmap
// Clear all graphics on the bitmap
bitmap_clear: {
.label bitmap = $20
.label x = $22
@ -3741,7 +3741,7 @@ bitmap_clear: {
rts
}
//SEG326 bitmap_init
// Initialize the bitmap plotter tables for a specific bitmap
// Initialize the bitmap plotter tables for a specific bitmap
bitmap_init: {
.label _0 = $3f
.label _6 = $40
@ -3892,7 +3892,7 @@ bitmap_init: {
//SEG372 [179] phi (byte) bitmap_init::bits#4 = (byte) bitmap_init::bits#1 [phi:bitmap_init::@10->bitmap_init::@2#0] -- register_copy
jmp b2
}
// Tables for the plotter - initialized by calling bitmap_draw_init();
// Tables for the plotter - initialized by calling bitmap_draw_init();
bitmap_plot_xlo: .fill $100, 0
bitmap_plot_xhi: .fill $100, 0
bitmap_plot_ylo: .fill $100, 0
@ -4376,7 +4376,7 @@ lines: {
rts
}
//SEG43 bitmap_line
// Draw a line on the bitmap
// Draw a line on the bitmap
bitmap_line: {
.label xd = 4
.label yd = 3
@ -5001,7 +5001,7 @@ init_screen: {
rts
}
//SEG300 bitmap_clear
// Clear all graphics on the bitmap
// Clear all graphics on the bitmap
bitmap_clear: {
.label bitmap = 9
.label y = 2
@ -5069,7 +5069,7 @@ bitmap_clear: {
rts
}
//SEG326 bitmap_init
// Initialize the bitmap plotter tables for a specific bitmap
// Initialize the bitmap plotter tables for a specific bitmap
bitmap_init: {
.label _6 = 2
.label yoffs = 9
@ -5192,7 +5192,7 @@ bitmap_init: {
//SEG372 [179] phi (byte) bitmap_init::bits#4 = (byte) bitmap_init::bits#1 [phi:bitmap_init::@10->bitmap_init::@2#0] -- register_copy
jmp b2
}
// Tables for the plotter - initialized by calling bitmap_draw_init();
// Tables for the plotter - initialized by calling bitmap_draw_init();
bitmap_plot_xlo: .fill $100, 0
bitmap_plot_xhi: .fill $100, 0
bitmap_plot_ylo: .fill $100, 0
@ -5895,7 +5895,7 @@ lines: {
rts
}
//SEG43 bitmap_line
// Draw a line on the bitmap
// Draw a line on the bitmap
bitmap_line: {
.label xd = 4
.label yd = 3
@ -6431,7 +6431,7 @@ init_screen: {
rts
}
//SEG300 bitmap_clear
// Clear all graphics on the bitmap
// Clear all graphics on the bitmap
bitmap_clear: {
.label bitmap = 9
.label y = 2
@ -6487,7 +6487,7 @@ bitmap_clear: {
rts
}
//SEG326 bitmap_init
// Initialize the bitmap plotter tables for a specific bitmap
// Initialize the bitmap plotter tables for a specific bitmap
bitmap_init: {
.label _6 = 2
.label yoffs = 9
@ -6587,7 +6587,7 @@ bitmap_init: {
//SEG371 [179] phi from bitmap_init::@10 to bitmap_init::@2 [phi:bitmap_init::@10->bitmap_init::@2]
//SEG372 [179] phi (byte) bitmap_init::bits#4 = (byte) bitmap_init::bits#1 [phi:bitmap_init::@10->bitmap_init::@2#0] -- register_copy
}
// Tables for the plotter - initialized by calling bitmap_draw_init();
// Tables for the plotter - initialized by calling bitmap_draw_init();
bitmap_plot_xlo: .fill $100, 0
bitmap_plot_xhi: .fill $100, 0
bitmap_plot_ylo: .fill $100, 0

View File

@ -1,14 +1,14 @@
// Allows analysis of the CHARGEN ROM font
// Allows analysis of the CHARGEN ROM font
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// The address of the CHARGEN character set
// The address of the CHARGEN character set
.label CHARGEN = $d000
// CIA#1 Port A: keyboard matrix columns and joystick #2
// CIA#1 Port A: keyboard matrix columns and joystick #2
.label CIA1_PORT_A = $dc00
// CIA#1 Port B: keyboard matrix rows and joystick #1.
// CIA#1 Port B: keyboard matrix rows and joystick #1.
.label CIA1_PORT_B = $dc01
.const KEY_F7 = 3
.const KEY_F1 = 4
@ -76,7 +76,7 @@ main: {
sta sc
lda #>SCREEN
sta sc+1
// Clear screen
// Clear screen
b1:
lda #' '
ldy #0
@ -184,7 +184,7 @@ main: {
b9:
lda #0
sta ch
// Check for key presses - and plot char if found
// Check for key presses - and plot char if found
b10:
ldx ch
jsr keyboard_get_keycode
@ -213,7 +213,7 @@ main: {
str2: .text "f5@"
str3: .text "f7@"
}
// Render 8x8 char (ch) as pixels on char canvas #pos
// Render 8x8 char (ch) as pixels on char canvas #pos
plot_chargen: {
.label _0 = 2
.label _1 = 2
@ -304,7 +304,7 @@ plot_chargen: {
cli
rts
}
// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word
// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word
mul8u: {
.const b = $a
.label mb = $b
@ -341,10 +341,10 @@ mul8u: {
rol mb+1
jmp b1
}
// Determines whether a specific key is currently pressed by accessing the matrix directly
// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7)
// All keys exist as as KEY_XXX constants.
// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed
// Determines whether a specific key is currently pressed by accessing the matrix directly
// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7)
// All keys exist as as KEY_XXX constants.
// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed
keyboard_key_pressed: {
txa
and #7
@ -358,11 +358,11 @@ keyboard_key_pressed: {
and keyboard_matrix_col_bitmask,y
rts
}
// Read a single row of the keyboard matrix
// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs.
// Returns the keys pressed on the row as bits according to the C64 key matrix.
// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write
// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader.
// Read a single row of the keyboard matrix
// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs.
// Returns the keys pressed on the row as bits according to the C64 key matrix.
// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write
// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader.
keyboard_matrix_read: {
lda keyboard_matrix_row_bitmask,x
sta CIA1_PORT_A
@ -370,15 +370,15 @@ keyboard_matrix_read: {
eor #$ff
rts
}
// Get the keycode corresponding to a specific screen code character
// ch is the character to get the key code for ($00-$3f)
// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled.
// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) .
// Get the keycode corresponding to a specific screen code character
// ch is the character to get the key code for ($00-$3f)
// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled.
// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) .
keyboard_get_keycode: {
lda keyboard_char_keycodes,x
rts
}
// Print a string at a specific screen position
// Print a string at a specific screen position
print_str_at: {
.label at = 9
.label str = 2
@ -402,10 +402,10 @@ print_str_at: {
!:
jmp b1
}
// Keyboard row bitmask as expected by CIA#1 Port A when reading a specific keyboard matrix row (rows are numbered 0-7)
// Keyboard row bitmask as expected by CIA#1 Port A when reading a specific keyboard matrix row (rows are numbered 0-7)
keyboard_matrix_row_bitmask: .byte $fe, $fd, $fb, $f7, $ef, $df, $bf, $7f
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
keyboard_matrix_col_bitmask: .byte 1, 2, 4, 8, $10, $20, $40, $80
// Keycodes for each screen code character from $00-$3f.
// Chars that do not have an unmodified keycode return $3f (representing RUN/STOP).
// Keycodes for each screen code character from $00-$3f.
// Chars that do not have an unmodified keycode return $3f (representing RUN/STOP).
keyboard_char_keycodes: .byte KEY_AT, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, $3f, KEY_POUND, $3f, KEY_ARROW_UP, KEY_ARROW_LEFT, KEY_SPACE, $3f, $3f, $3f, $3f, $3f, $3f, $3f, $3f, $3f, KEY_ASTERISK, KEY_PLUS, KEY_COMMA, KEY_MINUS, KEY_DOT, KEY_SLASH, KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_COLON, KEY_SEMICOLON, $3f, KEY_EQUALS, $3f, $3f

View File

@ -2606,19 +2606,19 @@ Allocated zp ZP_BYTE:61 [ keyboard_get_keycode::return#0 ]
INITIAL ASM
//SEG0 File Comments
// Allows analysis of the CHARGEN ROM font
// Allows analysis of the CHARGEN ROM font
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// The address of the CHARGEN character set
// The address of the CHARGEN character set
.label CHARGEN = $d000
// CIA#1 Port A: keyboard matrix columns and joystick #2
// CIA#1 Port A: keyboard matrix columns and joystick #2
.label CIA1_PORT_A = $dc00
// CIA#1 Port B: keyboard matrix rows and joystick #1.
// CIA#1 Port B: keyboard matrix rows and joystick #1.
.label CIA1_PORT_B = $dc01
.const KEY_F7 = 3
.const KEY_F1 = 4
@ -2714,7 +2714,7 @@ main: {
lda #>SCREEN
sta sc+1
jmp b1
// Clear screen
// Clear screen
//SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
b1_from_b1:
//SEG14 [5] phi (byte*) main::sc#2 = (byte*) main::sc#1 [phi:main::@1->main::@1#0] -- register_copy
@ -3015,7 +3015,7 @@ main: {
lda #0
sta ch
jmp b10
// Check for key presses - and plot char if found
// Check for key presses - and plot char if found
//SEG116 [49] phi from main::@12 to main::@10 [phi:main::@12->main::@10]
b10_from_b12:
//SEG117 [49] phi (byte) main::ch#2 = (byte) main::ch#1 [phi:main::@12->main::@10#0] -- register_copy
@ -3150,7 +3150,7 @@ main: {
str3: .text "f7@"
}
//SEG169 plot_chargen
// Render 8x8 char (ch) as pixels on char canvas #pos
// Render 8x8 char (ch) as pixels on char canvas #pos
plot_chargen: {
.label _0 = $2c
.label _1 = $2e
@ -3354,7 +3354,7 @@ plot_chargen: {
rts
}
//SEG228 mul8u
// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word
// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word
mul8u: {
.const b = $a
.label _1 = $35
@ -3428,10 +3428,10 @@ mul8u: {
jmp b1
}
//SEG251 keyboard_key_pressed
// Determines whether a specific key is currently pressed by accessing the matrix directly
// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7)
// All keys exist as as KEY_XXX constants.
// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed
// Determines whether a specific key is currently pressed by accessing the matrix directly
// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7)
// All keys exist as as KEY_XXX constants.
// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed
keyboard_key_pressed: {
.label _2 = $3a
.label colidx = $36
@ -3480,11 +3480,11 @@ keyboard_key_pressed: {
rts
}
//SEG262 keyboard_matrix_read
// Read a single row of the keyboard matrix
// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs.
// Returns the keys pressed on the row as bits according to the C64 key matrix.
// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write
// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader.
// Read a single row of the keyboard matrix
// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs.
// Returns the keys pressed on the row as bits according to the C64 key matrix.
// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write
// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader.
keyboard_matrix_read: {
.label return = $3c
.label rowid = $38
@ -3504,10 +3504,10 @@ keyboard_matrix_read: {
rts
}
//SEG267 keyboard_get_keycode
// Get the keycode corresponding to a specific screen code character
// ch is the character to get the key code for ($00-$3f)
// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled.
// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) .
// Get the keycode corresponding to a specific screen code character
// ch is the character to get the key code for ($00-$3f)
// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled.
// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) .
keyboard_get_keycode: {
.label return = $3d
.label ch = $28
@ -3523,7 +3523,7 @@ keyboard_get_keycode: {
rts
}
//SEG271 print_str_at
// Print a string at a specific screen position
// Print a string at a specific screen position
print_str_at: {
.label at = $1c
.label str = $1a
@ -3564,12 +3564,12 @@ print_str_at: {
!:
jmp b1_from_b2
}
// Keyboard row bitmask as expected by CIA#1 Port A when reading a specific keyboard matrix row (rows are numbered 0-7)
// Keyboard row bitmask as expected by CIA#1 Port A when reading a specific keyboard matrix row (rows are numbered 0-7)
keyboard_matrix_row_bitmask: .byte $fe, $fd, $fb, $f7, $ef, $df, $bf, $7f
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
keyboard_matrix_col_bitmask: .byte 1, 2, 4, 8, $10, $20, $40, $80
// Keycodes for each screen code character from $00-$3f.
// Chars that do not have an unmodified keycode return $3f (representing RUN/STOP).
// Keycodes for each screen code character from $00-$3f.
// Chars that do not have an unmodified keycode return $3f (representing RUN/STOP).
keyboard_char_keycodes: .byte KEY_AT, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, $3f, KEY_POUND, $3f, KEY_ARROW_UP, KEY_ARROW_LEFT, KEY_SPACE, $3f, $3f, $3f, $3f, $3f, $3f, $3f, $3f, $3f, KEY_ASTERISK, KEY_PLUS, KEY_COMMA, KEY_MINUS, KEY_DOT, KEY_SLASH, KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_COLON, KEY_SEMICOLON, $3f, KEY_EQUALS, $3f, $3f
REGISTER UPLIFT POTENTIAL REGISTERS
@ -3771,19 +3771,19 @@ Allocated (was zp ZP_WORD:23) zp ZP_WORD:11 [ mul8u::mb#2 mul8u::mb#1 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Allows analysis of the CHARGEN ROM font
// Allows analysis of the CHARGEN ROM font
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// The address of the CHARGEN character set
// The address of the CHARGEN character set
.label CHARGEN = $d000
// CIA#1 Port A: keyboard matrix columns and joystick #2
// CIA#1 Port A: keyboard matrix columns and joystick #2
.label CIA1_PORT_A = $dc00
// CIA#1 Port B: keyboard matrix rows and joystick #1.
// CIA#1 Port B: keyboard matrix rows and joystick #1.
.label CIA1_PORT_B = $dc01
.const KEY_F7 = 3
.const KEY_F1 = 4
@ -3872,7 +3872,7 @@ main: {
lda #>SCREEN
sta sc+1
jmp b1
// Clear screen
// Clear screen
//SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
b1_from_b1:
//SEG14 [5] phi (byte*) main::sc#2 = (byte*) main::sc#1 [phi:main::@1->main::@1#0] -- register_copy
@ -4140,7 +4140,7 @@ main: {
lda #0
sta ch
jmp b10
// Check for key presses - and plot char if found
// Check for key presses - and plot char if found
//SEG116 [49] phi from main::@12 to main::@10 [phi:main::@12->main::@10]
b10_from_b12:
//SEG117 [49] phi (byte) main::ch#2 = (byte) main::ch#1 [phi:main::@12->main::@10#0] -- register_copy
@ -4259,7 +4259,7 @@ main: {
str3: .text "f7@"
}
//SEG169 plot_chargen
// Render 8x8 char (ch) as pixels on char canvas #pos
// Render 8x8 char (ch) as pixels on char canvas #pos
plot_chargen: {
.label _0 = 2
.label _1 = 2
@ -4436,7 +4436,7 @@ plot_chargen: {
rts
}
//SEG228 mul8u
// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word
// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word
mul8u: {
.const b = $a
.label mb = $b
@ -4507,10 +4507,10 @@ mul8u: {
jmp b1
}
//SEG251 keyboard_key_pressed
// Determines whether a specific key is currently pressed by accessing the matrix directly
// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7)
// All keys exist as as KEY_XXX constants.
// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed
// Determines whether a specific key is currently pressed by accessing the matrix directly
// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7)
// All keys exist as as KEY_XXX constants.
// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed
keyboard_key_pressed: {
//SEG252 [114] (byte) keyboard_key_pressed::colidx#0 ← (byte) keyboard_key_pressed::key#6 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuyy=vbuxx_band_vbuc1
txa
@ -4539,11 +4539,11 @@ keyboard_key_pressed: {
rts
}
//SEG262 keyboard_matrix_read
// Read a single row of the keyboard matrix
// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs.
// Returns the keys pressed on the row as bits according to the C64 key matrix.
// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write
// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader.
// Read a single row of the keyboard matrix
// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs.
// Returns the keys pressed on the row as bits according to the C64 key matrix.
// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write
// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader.
keyboard_matrix_read: {
//SEG263 [122] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0 + (byte) keyboard_matrix_read::rowid#0) -- _deref_pbuc1=pbuc2_derefidx_vbuxx
lda keyboard_matrix_row_bitmask,x
@ -4558,10 +4558,10 @@ keyboard_matrix_read: {
rts
}
//SEG267 keyboard_get_keycode
// Get the keycode corresponding to a specific screen code character
// ch is the character to get the key code for ($00-$3f)
// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled.
// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) .
// Get the keycode corresponding to a specific screen code character
// ch is the character to get the key code for ($00-$3f)
// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled.
// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) .
keyboard_get_keycode: {
//SEG268 [125] (byte) keyboard_get_keycode::return#0 ← *((const byte[]) keyboard_char_keycodes#0 + (byte) keyboard_get_keycode::ch#0) -- vbuaa=pbuc1_derefidx_vbuxx
lda keyboard_char_keycodes,x
@ -4572,7 +4572,7 @@ keyboard_get_keycode: {
rts
}
//SEG271 print_str_at
// Print a string at a specific screen position
// Print a string at a specific screen position
print_str_at: {
.label at = 9
.label str = 2
@ -4613,12 +4613,12 @@ print_str_at: {
!:
jmp b1_from_b2
}
// Keyboard row bitmask as expected by CIA#1 Port A when reading a specific keyboard matrix row (rows are numbered 0-7)
// Keyboard row bitmask as expected by CIA#1 Port A when reading a specific keyboard matrix row (rows are numbered 0-7)
keyboard_matrix_row_bitmask: .byte $fe, $fd, $fb, $f7, $ef, $df, $bf, $7f
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
keyboard_matrix_col_bitmask: .byte 1, 2, 4, 8, $10, $20, $40, $80
// Keycodes for each screen code character from $00-$3f.
// Chars that do not have an unmodified keycode return $3f (representing RUN/STOP).
// Keycodes for each screen code character from $00-$3f.
// Chars that do not have an unmodified keycode return $3f (representing RUN/STOP).
keyboard_char_keycodes: .byte KEY_AT, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, $3f, KEY_POUND, $3f, KEY_ARROW_UP, KEY_ARROW_LEFT, KEY_SPACE, $3f, $3f, $3f, $3f, $3f, $3f, $3f, $3f, $3f, KEY_ASTERISK, KEY_PLUS, KEY_COMMA, KEY_MINUS, KEY_DOT, KEY_SLASH, KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_COLON, KEY_SEMICOLON, $3f, KEY_EQUALS, $3f, $3f
ASSEMBLER OPTIMIZATIONS
@ -5257,19 +5257,19 @@ FINAL ASSEMBLER
Score: 628893
//SEG0 File Comments
// Allows analysis of the CHARGEN ROM font
// Allows analysis of the CHARGEN ROM font
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
// Processor Port Register controlling RAM/ROM configuration and the datasette
// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
// The address of the CHARGEN character set
// The address of the CHARGEN character set
.label CHARGEN = $d000
// CIA#1 Port A: keyboard matrix columns and joystick #2
// CIA#1 Port A: keyboard matrix columns and joystick #2
.label CIA1_PORT_A = $dc00
// CIA#1 Port B: keyboard matrix rows and joystick #1.
// CIA#1 Port B: keyboard matrix rows and joystick #1.
.label CIA1_PORT_B = $dc01
.const KEY_F7 = 3
.const KEY_F1 = 4
@ -5347,7 +5347,7 @@ main: {
sta sc
lda #>SCREEN
sta sc+1
// Clear screen
// Clear screen
//SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
//SEG14 [5] phi (byte*) main::sc#2 = (byte*) main::sc#1 [phi:main::@1->main::@1#0] -- register_copy
//SEG15 main::@1
@ -5558,7 +5558,7 @@ main: {
//SEG115 [49] phi (byte) main::ch#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@9->main::@10#0] -- vbuz1=vbuc1
lda #0
sta ch
// Check for key presses - and plot char if found
// Check for key presses - and plot char if found
//SEG116 [49] phi from main::@12 to main::@10 [phi:main::@12->main::@10]
//SEG117 [49] phi (byte) main::ch#2 = (byte) main::ch#1 [phi:main::@12->main::@10#0] -- register_copy
//SEG118 main::@10
@ -5641,7 +5641,7 @@ main: {
str3: .text "f7@"
}
//SEG169 plot_chargen
// Render 8x8 char (ch) as pixels on char canvas #pos
// Render 8x8 char (ch) as pixels on char canvas #pos
plot_chargen: {
.label _0 = 2
.label _1 = 2
@ -5791,7 +5791,7 @@ plot_chargen: {
rts
}
//SEG228 mul8u
// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word
// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word
mul8u: {
.const b = $a
.label mb = $b
@ -5851,10 +5851,10 @@ mul8u: {
jmp b1
}
//SEG251 keyboard_key_pressed
// Determines whether a specific key is currently pressed by accessing the matrix directly
// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7)
// All keys exist as as KEY_XXX constants.
// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed
// Determines whether a specific key is currently pressed by accessing the matrix directly
// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7)
// All keys exist as as KEY_XXX constants.
// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed
keyboard_key_pressed: {
//SEG252 [114] (byte) keyboard_key_pressed::colidx#0 ← (byte) keyboard_key_pressed::key#6 & (byte/signed byte/word/signed word/dword/signed dword) 7 -- vbuyy=vbuxx_band_vbuc1
txa
@ -5879,11 +5879,11 @@ keyboard_key_pressed: {
rts
}
//SEG262 keyboard_matrix_read
// Read a single row of the keyboard matrix
// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs.
// Returns the keys pressed on the row as bits according to the C64 key matrix.
// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write
// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader.
// Read a single row of the keyboard matrix
// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs.
// Returns the keys pressed on the row as bits according to the C64 key matrix.
// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write
// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader.
keyboard_matrix_read: {
//SEG263 [122] *((const byte*) CIA1_PORT_A#0) ← *((const byte[8]) keyboard_matrix_row_bitmask#0 + (byte) keyboard_matrix_read::rowid#0) -- _deref_pbuc1=pbuc2_derefidx_vbuxx
lda keyboard_matrix_row_bitmask,x
@ -5896,10 +5896,10 @@ keyboard_matrix_read: {
rts
}
//SEG267 keyboard_get_keycode
// Get the keycode corresponding to a specific screen code character
// ch is the character to get the key code for ($00-$3f)
// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled.
// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) .
// Get the keycode corresponding to a specific screen code character
// ch is the character to get the key code for ($00-$3f)
// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled.
// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) .
keyboard_get_keycode: {
//SEG268 [125] (byte) keyboard_get_keycode::return#0 ← *((const byte[]) keyboard_char_keycodes#0 + (byte) keyboard_get_keycode::ch#0) -- vbuaa=pbuc1_derefidx_vbuxx
lda keyboard_char_keycodes,x
@ -5908,7 +5908,7 @@ keyboard_get_keycode: {
rts
}
//SEG271 print_str_at
// Print a string at a specific screen position
// Print a string at a specific screen position
print_str_at: {
.label at = 9
.label str = 2
@ -5943,11 +5943,11 @@ print_str_at: {
!:
jmp b1
}
// Keyboard row bitmask as expected by CIA#1 Port A when reading a specific keyboard matrix row (rows are numbered 0-7)
// Keyboard row bitmask as expected by CIA#1 Port A when reading a specific keyboard matrix row (rows are numbered 0-7)
keyboard_matrix_row_bitmask: .byte $fe, $fd, $fb, $f7, $ef, $df, $bf, $7f
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
// Keyboard matrix column bitmasks for a specific keybooard matrix column when reading the keyboard. (columns are numbered 0-7)
keyboard_matrix_col_bitmask: .byte 1, 2, 4, 8, $10, $20, $40, $80
// Keycodes for each screen code character from $00-$3f.
// Chars that do not have an unmodified keycode return $3f (representing RUN/STOP).
// Keycodes for each screen code character from $00-$3f.
// Chars that do not have an unmodified keycode return $3f (representing RUN/STOP).
keyboard_char_keycodes: .byte KEY_AT, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, $3f, KEY_POUND, $3f, KEY_ARROW_UP, KEY_ARROW_LEFT, KEY_SPACE, $3f, $3f, $3f, $3f, $3f, $3f, $3f, $3f, $3f, KEY_ASTERISK, KEY_PLUS, KEY_COMMA, KEY_MINUS, KEY_DOT, KEY_SLASH, KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_COLON, KEY_SEMICOLON, $3f, KEY_EQUALS, $3f, $3f

View File

@ -1,22 +1,22 @@
// Seriously fast multiply 8-bit version (8bit*8bit=8bit)
// Multiplies two signed 8-bit numbers and results in an 8-bit number
// C=A*B, A in [-64;64], B in [-96;95], C in [-96;95] - 64 acts a 1 (X*64=X)
// Uses the formula a*b = (a+b)^2/4 - (a-b)^2/4
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
// Seriously fast multiply 8-bit version (8bit*8bit=8bit)
// Multiplies two signed 8-bit numbers and results in an 8-bit number
// C=A*B, A in [-64;64], B in [-96;95], C in [-96;95] - 64 acts a 1 (X*64=X)
// Uses the formula a*b = (a+b)^2/4 - (a-b)^2/4
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.label print_line_cursor = $400
// Pointers to a, b and c=a*b
// Pointers to a, b and c=a*b
.label ap = $fd
.label bp = $fe
.label cp = $ff
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
.label mulf_sqr1 = $2000
// g(x) = >((( 1 - x ) * ( 1 - x )))
// g(x) = >((( 1 - x ) * ( 1 - x )))
.label mulf_sqr2 = $2200
main: {
.label at = 2
@ -107,7 +107,7 @@ main: {
bne b2
rts
}
// Print a signed byte as hex at a specific screen position
// Print a signed byte as hex at a specific screen position
print_sbyte_at: {
.label b = $a
.label at = 8
@ -134,7 +134,7 @@ print_sbyte_at: {
sta b
jmp b2
}
// Print a single char
// Print a single char
print_char_at: {
.label at = 8
.label ch = $b
@ -143,7 +143,7 @@ print_char_at: {
sta (at),y
rts
}
// Print a byte as HEX at a specific position
// Print a byte as HEX at a specific position
print_byte_at: {
.label at = 8
lda print_sbyte_at.b
@ -222,7 +222,7 @@ init_screen: {
bne b2
rts
}
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = 2
lda #<print_line_cursor

View File

@ -1304,27 +1304,27 @@ Allocated zp ZP_BYTE:31 [ fmul8::return#1 ]
INITIAL ASM
//SEG0 File Comments
// Seriously fast multiply 8-bit version (8bit*8bit=8bit)
// Multiplies two signed 8-bit numbers and results in an 8-bit number
// C=A*B, A in [-64;64], B in [-96;95], C in [-96;95] - 64 acts a 1 (X*64=X)
// Uses the formula a*b = (a+b)^2/4 - (a-b)^2/4
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
// Seriously fast multiply 8-bit version (8bit*8bit=8bit)
// Multiplies two signed 8-bit numbers and results in an 8-bit number
// C=A*B, A in [-64;64], B in [-96;95], C in [-96;95] - 64 acts a 1 (X*64=X)
// Uses the formula a*b = (a+b)^2/4 - (a-b)^2/4
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.label print_line_cursor = $400
// Pointers to a, b and c=a*b
// Pointers to a, b and c=a*b
.label ap = $fd
.label bp = $fe
.label cp = $ff
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
.label mulf_sqr1 = $2000
// g(x) = >((( 1 - x ) * ( 1 - x )))
// g(x) = >((( 1 - x ) * ( 1 - x )))
.label mulf_sqr2 = $2200
//SEG3 @begin
bbegin:
@ -1534,7 +1534,7 @@ main: {
rts
}
//SEG74 print_sbyte_at
// Print a signed byte as hex at a specific screen position
// Print a signed byte as hex at a specific screen position
print_sbyte_at: {
.label b = $d
.label at = $b
@ -1606,7 +1606,7 @@ print_sbyte_at: {
jmp b2_from_b5
}
//SEG97 print_char_at
// Print a single char
// Print a single char
print_char_at: {
.label at = $f
.label ch = $e
@ -1621,7 +1621,7 @@ print_char_at: {
rts
}
//SEG101 print_byte_at
// Print a byte as HEX at a specific position
// Print a byte as HEX at a specific position
print_byte_at: {
.label _0 = $1d
.label _2 = $1e
@ -1799,7 +1799,7 @@ init_screen: {
rts
}
//SEG153 print_cls
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = $15
//SEG154 [79] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1]
@ -1992,27 +1992,27 @@ Allocated (was zp ZP_BYTE:14) zp ZP_BYTE:11 [ print_char_at::ch#4 print_char_at:
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Seriously fast multiply 8-bit version (8bit*8bit=8bit)
// Multiplies two signed 8-bit numbers and results in an 8-bit number
// C=A*B, A in [-64;64], B in [-96;95], C in [-96;95] - 64 acts a 1 (X*64=X)
// Uses the formula a*b = (a+b)^2/4 - (a-b)^2/4
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
// Seriously fast multiply 8-bit version (8bit*8bit=8bit)
// Multiplies two signed 8-bit numbers and results in an 8-bit number
// C=A*B, A in [-64;64], B in [-96;95], C in [-96;95] - 64 acts a 1 (X*64=X)
// Uses the formula a*b = (a+b)^2/4 - (a-b)^2/4
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.label print_line_cursor = $400
// Pointers to a, b and c=a*b
// Pointers to a, b and c=a*b
.label ap = $fd
.label bp = $fe
.label cp = $ff
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
.label mulf_sqr1 = $2000
// g(x) = >((( 1 - x ) * ( 1 - x )))
// g(x) = >((( 1 - x ) * ( 1 - x )))
.label mulf_sqr2 = $2200
//SEG3 @begin
bbegin:
@ -2209,7 +2209,7 @@ main: {
rts
}
//SEG74 print_sbyte_at
// Print a signed byte as hex at a specific screen position
// Print a signed byte as hex at a specific screen position
print_sbyte_at: {
.label b = $a
.label at = 8
@ -2270,7 +2270,7 @@ print_sbyte_at: {
jmp b2_from_b5
}
//SEG97 print_char_at
// Print a single char
// Print a single char
print_char_at: {
.label at = 8
.label ch = $b
@ -2285,7 +2285,7 @@ print_char_at: {
rts
}
//SEG101 print_byte_at
// Print a byte as HEX at a specific position
// Print a byte as HEX at a specific position
print_byte_at: {
.label at = 8
//SEG102 [49] (byte~) print_byte_at::$0 ← (byte)(signed byte) print_sbyte_at::b#6 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4
@ -2439,7 +2439,7 @@ init_screen: {
rts
}
//SEG153 print_cls
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = 2
//SEG154 [79] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1]
@ -2732,27 +2732,27 @@ FINAL ASSEMBLER
Score: 10536
//SEG0 File Comments
// Seriously fast multiply 8-bit version (8bit*8bit=8bit)
// Multiplies two signed 8-bit numbers and results in an 8-bit number
// C=A*B, A in [-64;64], B in [-96;95], C in [-96;95] - 64 acts a 1 (X*64=X)
// Uses the formula a*b = (a+b)^2/4 - (a-b)^2/4
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
// Seriously fast multiply 8-bit version (8bit*8bit=8bit)
// Multiplies two signed 8-bit numbers and results in an 8-bit number
// C=A*B, A in [-64;64], B in [-96;95], C in [-96;95] - 64 acts a 1 (X*64=X)
// Uses the formula a*b = (a+b)^2/4 - (a-b)^2/4
// See the following for information about the method
// - http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// - http://codebase64.org/doku.php?id=magazines:chacking16
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.label print_line_cursor = $400
// Pointers to a, b and c=a*b
// Pointers to a, b and c=a*b
.label ap = $fd
.label bp = $fe
.label cp = $ff
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
// mulf_sqr tables will contain f(x)=int(x*x) and g(x) = f(1-x).
// f(x) = >(( x * x ))
.label mulf_sqr1 = $2000
// g(x) = >((( 1 - x ) * ( 1 - x )))
// g(x) = >((( 1 - x ) * ( 1 - x )))
.label mulf_sqr2 = $2200
//SEG3 @begin
//SEG4 @22
@ -2915,7 +2915,7 @@ main: {
rts
}
//SEG74 print_sbyte_at
// Print a signed byte as hex at a specific screen position
// Print a signed byte as hex at a specific screen position
print_sbyte_at: {
.label b = $a
.label at = 8
@ -2965,7 +2965,7 @@ print_sbyte_at: {
jmp b2
}
//SEG97 print_char_at
// Print a single char
// Print a single char
print_char_at: {
.label at = 8
.label ch = $b
@ -2978,7 +2978,7 @@ print_char_at: {
rts
}
//SEG101 print_byte_at
// Print a byte as HEX at a specific position
// Print a byte as HEX at a specific position
print_byte_at: {
.label at = 8
//SEG102 [49] (byte~) print_byte_at::$0 ← (byte)(signed byte) print_sbyte_at::b#6 >> (byte/signed byte/word/signed word/dword/signed dword) 4 -- vbuaa=vbuz1_ror_4
@ -3109,7 +3109,7 @@ init_screen: {
rts
}
//SEG153 print_cls
// Clear the screen. Also resets current line/char cursor.
// Clear the screen. Also resets current line/char cursor.
print_cls: {
.label sc = 2
//SEG154 [79] phi from print_cls to print_cls::@1 [phi:print_cls->print_cls::@1]

View File

@ -9,7 +9,7 @@ main: {
rts
str: .text "hello world!@"
}
// Print a newline
// Print a newline
print_ln: {
lda #<$400
sta print_line_cursor
@ -33,7 +33,7 @@ print_ln: {
!:
rts
}
// Print a zero-terminated string
// Print a zero-terminated string
print_str: {
.label str = 2
lda #<$400

View File

@ -366,7 +366,7 @@ main: {
str: .text "hello world!@"
}
//SEG19 print_ln
// Print a newline
// Print a newline
print_ln: {
//SEG20 [10] phi from print_ln to print_ln::@1 [phi:print_ln->print_ln::@1]
b1_from_print_ln:
@ -406,7 +406,7 @@ print_ln: {
rts
}
//SEG29 print_str
// Print a zero-terminated string
// Print a zero-terminated string
print_str: {
.label str = 4
//SEG30 [15] phi from print_str to print_str::@1 [phi:print_str->print_str::@1]
@ -528,7 +528,7 @@ main: {
str: .text "hello world!@"
}
//SEG19 print_ln
// Print a newline
// Print a newline
print_ln: {
//SEG20 [10] phi from print_ln to print_ln::@1 [phi:print_ln->print_ln::@1]
b1_from_print_ln:
@ -568,7 +568,7 @@ print_ln: {
rts
}
//SEG29 print_str
// Print a zero-terminated string
// Print a zero-terminated string
print_str: {
.label str = 2
//SEG30 [15] phi from print_str to print_str::@1 [phi:print_str->print_str::@1]
@ -725,7 +725,7 @@ main: {
str: .text "hello world!@"
}
//SEG19 print_ln
// Print a newline
// Print a newline
print_ln: {
//SEG20 [10] phi from print_ln to print_ln::@1 [phi:print_ln->print_ln::@1]
//SEG21 [10] phi (byte*) print_line_cursor#6 = ((byte*))(word/signed word/dword/signed dword) 1024 [phi:print_ln->print_ln::@1#0] -- pbuz1=pbuc1
@ -759,7 +759,7 @@ print_ln: {
rts
}
//SEG29 print_str
// Print a zero-terminated string
// Print a zero-terminated string
print_str: {
.label str = 2
//SEG30 [15] phi from print_str to print_str::@1 [phi:print_str->print_str::@1]

View File

@ -1,4 +1,4 @@
// A raster IRQ that opens the top/bottom border.
// A raster IRQ that opens the top/bottom border.
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
@ -6,17 +6,17 @@
.label BORDERCOL = $d020
.label VIC_CONTROL = $d011
.const VIC_RSEL = 8
// VIC II IRQ Status Register
// VIC II IRQ Status Register
.label IRQ_STATUS = $d019
// VIC II IRQ Enable Register
// VIC II IRQ Enable Register
.label IRQ_ENABLE = $d01a
// Bits for the IRQ Status/Enable Registers
// Bits for the IRQ Status/Enable Registers
.const IRQ_RASTER = 1
// CIA#1 Interrupt Status & Control Register
// CIA#1 Interrupt Status & Control Register
.label CIA1_INTERRUPT = $dc0d
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
.const CIA_INTERRUPT_CLEAR = $7f
// The vector used when the KERNAL serves IRQ interrupts
// The vector used when the KERNAL serves IRQ interrupts
.label KERNEL_IRQ = $314
.const WHITE = 1
.const RED = 2
@ -25,19 +25,19 @@ main: {
lda #0
sta GHOST_BYTE
sei
// Disable CIA 1 Timer IRQ
// Disable CIA 1 Timer IRQ
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
// Set raster line to $fa
// Set raster line to $fa
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
lda #$fa
sta RASTER
// Enable Raster Interrupt
// Enable Raster Interrupt
lda #IRQ_RASTER
sta IRQ_ENABLE
// Set the IRQ routine
// Set the IRQ routine
lda #<irq_bottom_1
sta KERNEL_IRQ
lda #>irq_bottom_1
@ -45,18 +45,18 @@ main: {
cli
rts
}
// Interrupt Routine 2
// Interrupt Routine 2
irq_bottom_2: {
lda #WHITE
sta BORDERCOL
// Set screen height back to 25 lines (preparing for the next screen)
// Set screen height back to 25 lines (preparing for the next screen)
lda VIC_CONTROL
ora #VIC_RSEL
sta VIC_CONTROL
// Acknowledge the IRQ
// Acknowledge the IRQ
lda #IRQ_RASTER
sta IRQ_STATUS
// Trigger IRQ 1 at line $fa
// Trigger IRQ 1 at line $fa
lda #$fa
sta RASTER
lda #<irq_bottom_1
@ -67,18 +67,18 @@ irq_bottom_2: {
sta BORDERCOL
jmp $ea31
}
// Interrupt Routine 1
// Interrupt Routine 1
irq_bottom_1: {
lda #WHITE
sta BORDERCOL
// Set screen height to 24 lines - this is done after the border should have started drawing - so it wont start
// Set screen height to 24 lines - this is done after the border should have started drawing - so it wont start
lda VIC_CONTROL
and #$ff^VIC_RSEL
sta VIC_CONTROL
// Acknowledge the IRQ
// Acknowledge the IRQ
lda #IRQ_RASTER
sta IRQ_STATUS
// Trigger IRQ 2 at line $fd
// Trigger IRQ 2 at line $fd
lda #$fd
sta RASTER
lda #<irq_bottom_2

View File

@ -555,7 +555,7 @@ Complete equivalence classes
INITIAL ASM
//SEG0 File Comments
// A raster IRQ that opens the top/bottom border.
// A raster IRQ that opens the top/bottom border.
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -565,17 +565,17 @@ INITIAL ASM
.label BORDERCOL = $d020
.label VIC_CONTROL = $d011
.const VIC_RSEL = 8
// VIC II IRQ Status Register
// VIC II IRQ Status Register
.label IRQ_STATUS = $d019
// VIC II IRQ Enable Register
// VIC II IRQ Enable Register
.label IRQ_ENABLE = $d01a
// Bits for the IRQ Status/Enable Registers
// Bits for the IRQ Status/Enable Registers
.const IRQ_RASTER = 1
// CIA#1 Interrupt Status & Control Register
// CIA#1 Interrupt Status & Control Register
.label CIA1_INTERRUPT = $dc0d
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
.const CIA_INTERRUPT_CLEAR = $7f
// The vector used when the KERNAL serves IRQ interrupts
// The vector used when the KERNAL serves IRQ interrupts
.label KERNEL_IRQ = $314
.const WHITE = 1
.const RED = 2
@ -602,11 +602,11 @@ main: {
//SEG11 asm { sei }
sei
//SEG12 [6] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 -- _deref_pbuc1=vbuc2
// Disable CIA 1 Timer IRQ
// Disable CIA 1 Timer IRQ
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
//SEG13 [7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
// Set raster line to $fa
// Set raster line to $fa
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
@ -614,11 +614,11 @@ main: {
lda #$fa
sta RASTER
//SEG15 [9] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Enable Raster Interrupt
// Enable Raster Interrupt
lda #IRQ_RASTER
sta IRQ_ENABLE
//SEG16 [10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq_bottom_1() -- _deref_pptc1=pprc2
// Set the IRQ routine
// Set the IRQ routine
lda #<irq_bottom_1
sta KERNEL_IRQ
lda #>irq_bottom_1
@ -632,23 +632,23 @@ main: {
rts
}
//SEG20 irq_bottom_2
// Interrupt Routine 2
// Interrupt Routine 2
irq_bottom_2: {
//SEG21 entry interrupt(KERNEL_KEYBOARD)
//SEG22 [13] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2
lda #WHITE
sta BORDERCOL
//SEG23 [14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (const byte) VIC_RSEL#0 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2
// Set screen height back to 25 lines (preparing for the next screen)
// Set screen height back to 25 lines (preparing for the next screen)
lda VIC_CONTROL
ora #VIC_RSEL
sta VIC_CONTROL
//SEG24 [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Acknowledge the IRQ
// Acknowledge the IRQ
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG25 [16] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 -- _deref_pbuc1=vbuc2
// Trigger IRQ 1 at line $fa
// Trigger IRQ 1 at line $fa
lda #$fa
sta RASTER
//SEG26 [17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq_bottom_1() -- _deref_pptc1=pprc2
@ -666,23 +666,23 @@ irq_bottom_2: {
jmp $ea31
}
//SEG30 irq_bottom_1
// Interrupt Routine 1
// Interrupt Routine 1
irq_bottom_1: {
//SEG31 entry interrupt(KERNEL_MIN)
//SEG32 [20] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2
lda #WHITE
sta BORDERCOL
//SEG33 [21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
// Set screen height to 24 lines - this is done after the border should have started drawing - so it wont start
// Set screen height to 24 lines - this is done after the border should have started drawing - so it wont start
lda VIC_CONTROL
and #$ff^VIC_RSEL
sta VIC_CONTROL
//SEG34 [22] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Acknowledge the IRQ
// Acknowledge the IRQ
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG35 [23] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 -- _deref_pbuc1=vbuc2
// Trigger IRQ 2 at line $fd
// Trigger IRQ 2 at line $fd
lda #$fd
sta RASTER
//SEG36 [24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq_bottom_2() -- _deref_pptc1=pprc2
@ -733,7 +733,7 @@ Uplifting [] best 175 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// A raster IRQ that opens the top/bottom border.
// A raster IRQ that opens the top/bottom border.
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -743,17 +743,17 @@ ASSEMBLER BEFORE OPTIMIZATION
.label BORDERCOL = $d020
.label VIC_CONTROL = $d011
.const VIC_RSEL = 8
// VIC II IRQ Status Register
// VIC II IRQ Status Register
.label IRQ_STATUS = $d019
// VIC II IRQ Enable Register
// VIC II IRQ Enable Register
.label IRQ_ENABLE = $d01a
// Bits for the IRQ Status/Enable Registers
// Bits for the IRQ Status/Enable Registers
.const IRQ_RASTER = 1
// CIA#1 Interrupt Status & Control Register
// CIA#1 Interrupt Status & Control Register
.label CIA1_INTERRUPT = $dc0d
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
.const CIA_INTERRUPT_CLEAR = $7f
// The vector used when the KERNAL serves IRQ interrupts
// The vector used when the KERNAL serves IRQ interrupts
.label KERNEL_IRQ = $314
.const WHITE = 1
.const RED = 2
@ -780,11 +780,11 @@ main: {
//SEG11 asm { sei }
sei
//SEG12 [6] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 -- _deref_pbuc1=vbuc2
// Disable CIA 1 Timer IRQ
// Disable CIA 1 Timer IRQ
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
//SEG13 [7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
// Set raster line to $fa
// Set raster line to $fa
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
@ -792,11 +792,11 @@ main: {
lda #$fa
sta RASTER
//SEG15 [9] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Enable Raster Interrupt
// Enable Raster Interrupt
lda #IRQ_RASTER
sta IRQ_ENABLE
//SEG16 [10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq_bottom_1() -- _deref_pptc1=pprc2
// Set the IRQ routine
// Set the IRQ routine
lda #<irq_bottom_1
sta KERNEL_IRQ
lda #>irq_bottom_1
@ -810,23 +810,23 @@ main: {
rts
}
//SEG20 irq_bottom_2
// Interrupt Routine 2
// Interrupt Routine 2
irq_bottom_2: {
//SEG21 entry interrupt(KERNEL_KEYBOARD)
//SEG22 [13] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2
lda #WHITE
sta BORDERCOL
//SEG23 [14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (const byte) VIC_RSEL#0 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2
// Set screen height back to 25 lines (preparing for the next screen)
// Set screen height back to 25 lines (preparing for the next screen)
lda VIC_CONTROL
ora #VIC_RSEL
sta VIC_CONTROL
//SEG24 [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Acknowledge the IRQ
// Acknowledge the IRQ
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG25 [16] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 -- _deref_pbuc1=vbuc2
// Trigger IRQ 1 at line $fa
// Trigger IRQ 1 at line $fa
lda #$fa
sta RASTER
//SEG26 [17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq_bottom_1() -- _deref_pptc1=pprc2
@ -844,23 +844,23 @@ irq_bottom_2: {
jmp $ea31
}
//SEG30 irq_bottom_1
// Interrupt Routine 1
// Interrupt Routine 1
irq_bottom_1: {
//SEG31 entry interrupt(KERNEL_MIN)
//SEG32 [20] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2
lda #WHITE
sta BORDERCOL
//SEG33 [21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
// Set screen height to 24 lines - this is done after the border should have started drawing - so it wont start
// Set screen height to 24 lines - this is done after the border should have started drawing - so it wont start
lda VIC_CONTROL
and #$ff^VIC_RSEL
sta VIC_CONTROL
//SEG34 [22] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Acknowledge the IRQ
// Acknowledge the IRQ
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG35 [23] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 -- _deref_pbuc1=vbuc2
// Trigger IRQ 2 at line $fd
// Trigger IRQ 2 at line $fd
lda #$fd
sta RASTER
//SEG36 [24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq_bottom_2() -- _deref_pptc1=pprc2
@ -1010,7 +1010,7 @@ FINAL ASSEMBLER
Score: 154
//SEG0 File Comments
// A raster IRQ that opens the top/bottom border.
// A raster IRQ that opens the top/bottom border.
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
@ -1020,17 +1020,17 @@ Score: 154
.label BORDERCOL = $d020
.label VIC_CONTROL = $d011
.const VIC_RSEL = 8
// VIC II IRQ Status Register
// VIC II IRQ Status Register
.label IRQ_STATUS = $d019
// VIC II IRQ Enable Register
// VIC II IRQ Enable Register
.label IRQ_ENABLE = $d01a
// Bits for the IRQ Status/Enable Registers
// Bits for the IRQ Status/Enable Registers
.const IRQ_RASTER = 1
// CIA#1 Interrupt Status & Control Register
// CIA#1 Interrupt Status & Control Register
.label CIA1_INTERRUPT = $dc0d
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
.const CIA_INTERRUPT_CLEAR = $7f
// The vector used when the KERNAL serves IRQ interrupts
// The vector used when the KERNAL serves IRQ interrupts
.label KERNEL_IRQ = $314
.const WHITE = 1
.const RED = 2
@ -1049,11 +1049,11 @@ main: {
//SEG11 asm { sei }
sei
//SEG12 [6] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 -- _deref_pbuc1=vbuc2
// Disable CIA 1 Timer IRQ
// Disable CIA 1 Timer IRQ
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
//SEG13 [7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
// Set raster line to $fa
// Set raster line to $fa
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
@ -1061,11 +1061,11 @@ main: {
lda #$fa
sta RASTER
//SEG15 [9] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Enable Raster Interrupt
// Enable Raster Interrupt
lda #IRQ_RASTER
sta IRQ_ENABLE
//SEG16 [10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq_bottom_1() -- _deref_pptc1=pprc2
// Set the IRQ routine
// Set the IRQ routine
lda #<irq_bottom_1
sta KERNEL_IRQ
lda #>irq_bottom_1
@ -1077,23 +1077,23 @@ main: {
rts
}
//SEG20 irq_bottom_2
// Interrupt Routine 2
// Interrupt Routine 2
irq_bottom_2: {
//SEG21 entry interrupt(KERNEL_KEYBOARD)
//SEG22 [13] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2
lda #WHITE
sta BORDERCOL
//SEG23 [14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (const byte) VIC_RSEL#0 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2
// Set screen height back to 25 lines (preparing for the next screen)
// Set screen height back to 25 lines (preparing for the next screen)
lda VIC_CONTROL
ora #VIC_RSEL
sta VIC_CONTROL
//SEG24 [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Acknowledge the IRQ
// Acknowledge the IRQ
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG25 [16] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 -- _deref_pbuc1=vbuc2
// Trigger IRQ 1 at line $fa
// Trigger IRQ 1 at line $fa
lda #$fa
sta RASTER
//SEG26 [17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq_bottom_1() -- _deref_pptc1=pprc2
@ -1109,23 +1109,23 @@ irq_bottom_2: {
jmp $ea31
}
//SEG30 irq_bottom_1
// Interrupt Routine 1
// Interrupt Routine 1
irq_bottom_1: {
//SEG31 entry interrupt(KERNEL_MIN)
//SEG32 [20] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2
lda #WHITE
sta BORDERCOL
//SEG33 [21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
// Set screen height to 24 lines - this is done after the border should have started drawing - so it wont start
// Set screen height to 24 lines - this is done after the border should have started drawing - so it wont start
lda VIC_CONTROL
and #$ff^VIC_RSEL
sta VIC_CONTROL
//SEG34 [22] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Acknowledge the IRQ
// Acknowledge the IRQ
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG35 [23] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 -- _deref_pbuc1=vbuc2
// Trigger IRQ 2 at line $fd
// Trigger IRQ 2 at line $fd
lda #$fd
sta RASTER
//SEG36 [24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq_bottom_2() -- _deref_pptc1=pprc2

View File

@ -1,4 +1,4 @@
// A simple usage of the flexible sprite multiplexer routine
// A simple usage of the flexible sprite multiplexer routine
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
@ -13,12 +13,12 @@
.const VIC_RST8 = $80
.const VIC_DEN = $10
.const VIC_RSEL = 8
// The colors of the C64
// The colors of the C64
.const BLACK = 0
.const GREEN = 5
// The number of sprites in the multiplexer
// The number of sprites in the multiplexer
.const PLEX_COUNT = $20
// Location of screen & sprites
// Location of screen & sprites
.label SCREEN = $400
.label SPRITE = $2000
.label YSIN = $2100
@ -32,7 +32,7 @@ main: {
jsr loop
rts
}
// The raster loop
// The raster loop
loop: {
.label sin_idx = 2
.label plexFreeNextYpos1_return = 9
@ -74,7 +74,7 @@ loop: {
sta plex_show_idx
tax
sta plex_free_next
// Show the sprites
// Show the sprites
b11:
lda #BLACK
sta BORDERCOL
@ -95,8 +95,8 @@ loop: {
sta BORDERCOL
jmp b4
}
// Show the next sprite.
// plexSort() prepares showing the sprites
// Show the next sprite.
// plexSort() prepares showing the sprites
plexShowSprite: {
.label plex_sprite_idx2 = 9
.label xpos_idx = $a
@ -159,15 +159,15 @@ plexShowSprite: {
sta SPRITES_XMSB
jmp b2
}
// Ensure that the indices in PLEX_SORTED_IDX is sorted based on the y-positions in PLEX_YPOS
// Assumes that the positions are nearly sorted already (as each sprite just moves a bit)
// Uses an insertion sort:
// 1. Moves a marker (m) from the start to end of the array. Every time the marker moves forward all elements before the marker are sorted correctly.
// 2a. If the next element after the marker is larger that the current element
// the marker can be moved forwards (as the sorting is correct).
// 2b. If the next element after the marker is smaller than the current element:
// elements before the marker are shifted right one at a time until encountering one smaller than the current one.
// It is then inserted at the spot. Now the marker can move forward.
// Ensure that the indices in PLEX_SORTED_IDX is sorted based on the y-positions in PLEX_YPOS
// Assumes that the positions are nearly sorted already (as each sprite just moves a bit)
// Uses an insertion sort:
// 1. Moves a marker (m) from the start to end of the array. Every time the marker moves forward all elements before the marker are sorted correctly.
// 2a. If the next element after the marker is larger that the current element
// the marker can be moved forwards (as the sorting is correct).
// 2b. If the next element after the marker is smaller than the current element:
// elements before the marker are shifted right one at a time until encountering one smaller than the current one.
// It is then inserted at the spot. Now the marker can move forward.
plexSort: {
.label nxt_idx = 4
.label nxt_y = 5
@ -215,7 +215,7 @@ plexSort: {
bcc b3
jmp b5
}
// Initialize the program
// Initialize the program
init: {
.label xp = 7
lda #VIC_DEN|VIC_RSEL|3
@ -246,7 +246,7 @@ init: {
inx
cpx #PLEX_COUNT-1+1
bne b1
// Enable & initialize sprites
// Enable & initialize sprites
lda #$ff
sta SPRITES_ENABLE
ldx #0
@ -258,7 +258,7 @@ init: {
bne b2
rts
}
// Initialize the multiplexer data structures
// Initialize the multiplexer data structures
plexInit: {
ldx #0
b1:
@ -269,15 +269,15 @@ plexInit: {
bne b1
rts
}
// Contains the Y-position where each sprite is free again. PLEX_FREE_YPOS[s] holds the Y-position where sprite s is free to use again.
// Contains the Y-position where each sprite is free again. PLEX_FREE_YPOS[s] holds the Y-position where sprite s is free to use again.
PLEX_FREE_YPOS: .fill 8, 0
// The x-positions of the multiplexer sprites ($000-$1ff)
// The x-positions of the multiplexer sprites ($000-$1ff)
PLEX_XPOS: .fill 2*PLEX_COUNT, 0
// The y-positions of the multiplexer sprites.
// The y-positions of the multiplexer sprites.
PLEX_YPOS: .fill PLEX_COUNT, 0
// The sprite pointers for the multiplexed sprites
// The sprite pointers for the multiplexed sprites
PLEX_PTR: .fill PLEX_COUNT, 0
// Indexes of the plex-sprites sorted by sprite y-position. Each call to plexSort() will fix the sorting if changes to the Y-positions have ruined it.
// Indexes of the plex-sprites sorted by sprite y-position. Each call to plexSort() will fix the sorting if changes to the Y-positions have ruined it.
PLEX_SORTED_IDX: .fill PLEX_COUNT, 0
.pc = YSIN "YSIN"
.var min = 50

View File

@ -2453,7 +2453,7 @@ Allocated zp ZP_BYTE:32 [ init::$6 ]
INITIAL ASM
//SEG0 File Comments
// A simple usage of the flexible sprite multiplexer routine
// A simple usage of the flexible sprite multiplexer routine
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -2470,12 +2470,12 @@ INITIAL ASM
.const VIC_RST8 = $80
.const VIC_DEN = $10
.const VIC_RSEL = 8
// The colors of the C64
// The colors of the C64
.const BLACK = 0
.const GREEN = 5
// The number of sprites in the multiplexer
// The number of sprites in the multiplexer
.const PLEX_COUNT = $20
// Location of screen & sprites
// Location of screen & sprites
.label SCREEN = $400
.label SPRITE = $2000
.label YSIN = $2100
@ -2525,7 +2525,7 @@ main: {
rts
}
//SEG21 loop
// The raster loop
// The raster loop
loop: {
.label _4 = $12
.label y_idx = 3
@ -2632,7 +2632,7 @@ loop: {
lda #0
sta plex_free_next
jmp b11
// Show the sprites
// Show the sprites
//SEG57 [27] phi from loop::@31 to loop::@11 [phi:loop::@31->loop::@11]
b11_from_b31:
//SEG58 [27] phi (byte) loop::ss#6 = (byte) loop::ss#1 [phi:loop::@31->loop::@11#0] -- register_copy
@ -2688,8 +2688,8 @@ loop: {
jmp b1
}
//SEG79 plexShowSprite
// Show the next sprite.
// plexSort() prepares showing the sprites
// Show the next sprite.
// plexSort() prepares showing the sprites
plexShowSprite: {
.label _3 = $19
.label _4 = $1a
@ -2823,15 +2823,15 @@ plexShowSprite: {
jmp b2
}
//SEG114 plexSort
// Ensure that the indices in PLEX_SORTED_IDX is sorted based on the y-positions in PLEX_YPOS
// Assumes that the positions are nearly sorted already (as each sprite just moves a bit)
// Uses an insertion sort:
// 1. Moves a marker (m) from the start to end of the array. Every time the marker moves forward all elements before the marker are sorted correctly.
// 2a. If the next element after the marker is larger that the current element
// the marker can be moved forwards (as the sorting is correct).
// 2b. If the next element after the marker is smaller than the current element:
// elements before the marker are shifted right one at a time until encountering one smaller than the current one.
// It is then inserted at the spot. Now the marker can move forward.
// Ensure that the indices in PLEX_SORTED_IDX is sorted based on the y-positions in PLEX_YPOS
// Assumes that the positions are nearly sorted already (as each sprite just moves a bit)
// Uses an insertion sort:
// 1. Moves a marker (m) from the start to end of the array. Every time the marker moves forward all elements before the marker are sorted correctly.
// 2a. If the next element after the marker is larger that the current element
// the marker can be moved forwards (as the sorting is correct).
// 2b. If the next element after the marker is smaller than the current element:
// elements before the marker are shifted right one at a time until encountering one smaller than the current one.
// It is then inserted at the spot. Now the marker can move forward.
plexSort: {
.label nxt_idx = $1d
.label nxt_y = $1e
@ -2951,7 +2951,7 @@ plexSort: {
jmp b5
}
//SEG151 init
// Initialize the program
// Initialize the program
init: {
.label _6 = $20
.label xp = $e
@ -3014,7 +3014,7 @@ init: {
//SEG168 init::@3
b3:
//SEG169 [90] *((const byte*) SPRITES_ENABLE#0) ← (byte/word/signed word/dword/signed dword) 255 -- _deref_pbuc1=vbuc2
// Enable & initialize sprites
// Enable & initialize sprites
lda #$ff
sta SPRITES_ENABLE
//SEG170 [91] phi from init::@3 to init::@2 [phi:init::@3->init::@2]
@ -3046,7 +3046,7 @@ init: {
rts
}
//SEG180 plexInit
// Initialize the multiplexer data structures
// Initialize the multiplexer data structures
plexInit: {
.label i = $11
//SEG181 [97] phi from plexInit to plexInit::plexSetScreen1 [phi:plexInit->plexInit::plexSetScreen1]
@ -3082,15 +3082,15 @@ plexInit: {
//SEG192 [102] return
rts
}
// Contains the Y-position where each sprite is free again. PLEX_FREE_YPOS[s] holds the Y-position where sprite s is free to use again.
// Contains the Y-position where each sprite is free again. PLEX_FREE_YPOS[s] holds the Y-position where sprite s is free to use again.
PLEX_FREE_YPOS: .fill 8, 0
// The x-positions of the multiplexer sprites ($000-$1ff)
// The x-positions of the multiplexer sprites ($000-$1ff)
PLEX_XPOS: .fill 2*PLEX_COUNT, 0
// The y-positions of the multiplexer sprites.
// The y-positions of the multiplexer sprites.
PLEX_YPOS: .fill PLEX_COUNT, 0
// The sprite pointers for the multiplexed sprites
// The sprite pointers for the multiplexed sprites
PLEX_PTR: .fill PLEX_COUNT, 0
// Indexes of the plex-sprites sorted by sprite y-position. Each call to plexSort() will fix the sorting if changes to the Y-positions have ruined it.
// Indexes of the plex-sprites sorted by sprite y-position. Each call to plexSort() will fix the sorting if changes to the Y-positions have ruined it.
PLEX_SORTED_IDX: .fill PLEX_COUNT, 0
.pc = YSIN "YSIN"
.var min = 50
@ -3293,7 +3293,7 @@ Allocated (was zp ZP_BYTE:24) zp ZP_BYTE:10 [ plexShowSprite::xpos_idx#0 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// A simple usage of the flexible sprite multiplexer routine
// A simple usage of the flexible sprite multiplexer routine
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -3310,12 +3310,12 @@ ASSEMBLER BEFORE OPTIMIZATION
.const VIC_RST8 = $80
.const VIC_DEN = $10
.const VIC_RSEL = 8
// The colors of the C64
// The colors of the C64
.const BLACK = 0
.const GREEN = 5
// The number of sprites in the multiplexer
// The number of sprites in the multiplexer
.const PLEX_COUNT = $20
// Location of screen & sprites
// Location of screen & sprites
.label SCREEN = $400
.label SPRITE = $2000
.label YSIN = $2100
@ -3364,7 +3364,7 @@ main: {
rts
}
//SEG21 loop
// The raster loop
// The raster loop
loop: {
.label sin_idx = 2
.label plexFreeNextYpos1_return = 9
@ -3460,7 +3460,7 @@ loop: {
lda #0
sta plex_free_next
jmp b11
// Show the sprites
// Show the sprites
//SEG57 [27] phi from loop::@31 to loop::@11 [phi:loop::@31->loop::@11]
b11_from_b31:
//SEG58 [27] phi (byte) loop::ss#6 = (byte) loop::ss#1 [phi:loop::@31->loop::@11#0] -- register_copy
@ -3516,8 +3516,8 @@ loop: {
jmp b1
}
//SEG79 plexShowSprite
// Show the next sprite.
// plexSort() prepares showing the sprites
// Show the next sprite.
// plexSort() prepares showing the sprites
plexShowSprite: {
.label plex_sprite_idx2 = 9
.label xpos_idx = $a
@ -3629,15 +3629,15 @@ plexShowSprite: {
jmp b2
}
//SEG114 plexSort
// Ensure that the indices in PLEX_SORTED_IDX is sorted based on the y-positions in PLEX_YPOS
// Assumes that the positions are nearly sorted already (as each sprite just moves a bit)
// Uses an insertion sort:
// 1. Moves a marker (m) from the start to end of the array. Every time the marker moves forward all elements before the marker are sorted correctly.
// 2a. If the next element after the marker is larger that the current element
// the marker can be moved forwards (as the sorting is correct).
// 2b. If the next element after the marker is smaller than the current element:
// elements before the marker are shifted right one at a time until encountering one smaller than the current one.
// It is then inserted at the spot. Now the marker can move forward.
// Ensure that the indices in PLEX_SORTED_IDX is sorted based on the y-positions in PLEX_YPOS
// Assumes that the positions are nearly sorted already (as each sprite just moves a bit)
// Uses an insertion sort:
// 1. Moves a marker (m) from the start to end of the array. Every time the marker moves forward all elements before the marker are sorted correctly.
// 2a. If the next element after the marker is larger that the current element
// the marker can be moved forwards (as the sorting is correct).
// 2b. If the next element after the marker is smaller than the current element:
// elements before the marker are shifted right one at a time until encountering one smaller than the current one.
// It is then inserted at the spot. Now the marker can move forward.
plexSort: {
.label nxt_idx = 4
.label nxt_y = 5
@ -3744,7 +3744,7 @@ plexSort: {
jmp b5
}
//SEG151 init
// Initialize the program
// Initialize the program
init: {
.label xp = 7
//SEG152 [81] *((const byte*) D011#0) ← (const byte) VIC_DEN#0|(const byte) VIC_RSEL#0|(byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2
@ -3800,7 +3800,7 @@ init: {
//SEG168 init::@3
b3:
//SEG169 [90] *((const byte*) SPRITES_ENABLE#0) ← (byte/word/signed word/dword/signed dword) 255 -- _deref_pbuc1=vbuc2
// Enable & initialize sprites
// Enable & initialize sprites
lda #$ff
sta SPRITES_ENABLE
//SEG170 [91] phi from init::@3 to init::@2 [phi:init::@3->init::@2]
@ -3829,7 +3829,7 @@ init: {
rts
}
//SEG180 plexInit
// Initialize the multiplexer data structures
// Initialize the multiplexer data structures
plexInit: {
//SEG181 [97] phi from plexInit to plexInit::plexSetScreen1 [phi:plexInit->plexInit::plexSetScreen1]
plexSetScreen1_from_plexInit:
@ -3861,15 +3861,15 @@ plexInit: {
//SEG192 [102] return
rts
}
// Contains the Y-position where each sprite is free again. PLEX_FREE_YPOS[s] holds the Y-position where sprite s is free to use again.
// Contains the Y-position where each sprite is free again. PLEX_FREE_YPOS[s] holds the Y-position where sprite s is free to use again.
PLEX_FREE_YPOS: .fill 8, 0
// The x-positions of the multiplexer sprites ($000-$1ff)
// The x-positions of the multiplexer sprites ($000-$1ff)
PLEX_XPOS: .fill 2*PLEX_COUNT, 0
// The y-positions of the multiplexer sprites.
// The y-positions of the multiplexer sprites.
PLEX_YPOS: .fill PLEX_COUNT, 0
// The sprite pointers for the multiplexed sprites
// The sprite pointers for the multiplexed sprites
PLEX_PTR: .fill PLEX_COUNT, 0
// Indexes of the plex-sprites sorted by sprite y-position. Each call to plexSort() will fix the sorting if changes to the Y-positions have ruined it.
// Indexes of the plex-sprites sorted by sprite y-position. Each call to plexSort() will fix the sorting if changes to the Y-positions have ruined it.
PLEX_SORTED_IDX: .fill PLEX_COUNT, 0
.pc = YSIN "YSIN"
.var min = 50
@ -4290,7 +4290,7 @@ FINAL ASSEMBLER
Score: 63460
//SEG0 File Comments
// A simple usage of the flexible sprite multiplexer routine
// A simple usage of the flexible sprite multiplexer routine
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
@ -4307,12 +4307,12 @@ Score: 63460
.const VIC_RST8 = $80
.const VIC_DEN = $10
.const VIC_RSEL = 8
// The colors of the C64
// The colors of the C64
.const BLACK = 0
.const GREEN = 5
// The number of sprites in the multiplexer
// The number of sprites in the multiplexer
.const PLEX_COUNT = $20
// Location of screen & sprites
// Location of screen & sprites
.label SCREEN = $400
.label SPRITE = $2000
.label YSIN = $2100
@ -4345,7 +4345,7 @@ main: {
rts
}
//SEG21 loop
// The raster loop
// The raster loop
loop: {
.label sin_idx = 2
.label plexFreeNextYpos1_return = 9
@ -4422,7 +4422,7 @@ loop: {
tax
//SEG56 [27] phi (byte) plex_free_next#17 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:loop::@8->loop::@11#4] -- vbuz1=vbuc1
sta plex_free_next
// Show the sprites
// Show the sprites
//SEG57 [27] phi from loop::@31 to loop::@11 [phi:loop::@31->loop::@11]
//SEG58 [27] phi (byte) loop::ss#6 = (byte) loop::ss#1 [phi:loop::@31->loop::@11#0] -- register_copy
//SEG59 [27] phi (byte) plex_sprite_msb#44 = (byte) plex_sprite_msb#16 [phi:loop::@31->loop::@11#1] -- register_copy
@ -4466,8 +4466,8 @@ loop: {
jmp b4
}
//SEG79 plexShowSprite
// Show the next sprite.
// plexSort() prepares showing the sprites
// Show the next sprite.
// plexSort() prepares showing the sprites
plexShowSprite: {
.label plex_sprite_idx2 = 9
.label xpos_idx = $a
@ -4565,15 +4565,15 @@ plexShowSprite: {
jmp b2
}
//SEG114 plexSort
// Ensure that the indices in PLEX_SORTED_IDX is sorted based on the y-positions in PLEX_YPOS
// Assumes that the positions are nearly sorted already (as each sprite just moves a bit)
// Uses an insertion sort:
// 1. Moves a marker (m) from the start to end of the array. Every time the marker moves forward all elements before the marker are sorted correctly.
// 2a. If the next element after the marker is larger that the current element
// the marker can be moved forwards (as the sorting is correct).
// 2b. If the next element after the marker is smaller than the current element:
// elements before the marker are shifted right one at a time until encountering one smaller than the current one.
// It is then inserted at the spot. Now the marker can move forward.
// Ensure that the indices in PLEX_SORTED_IDX is sorted based on the y-positions in PLEX_YPOS
// Assumes that the positions are nearly sorted already (as each sprite just moves a bit)
// Uses an insertion sort:
// 1. Moves a marker (m) from the start to end of the array. Every time the marker moves forward all elements before the marker are sorted correctly.
// 2a. If the next element after the marker is larger that the current element
// the marker can be moved forwards (as the sorting is correct).
// 2b. If the next element after the marker is smaller than the current element:
// elements before the marker are shifted right one at a time until encountering one smaller than the current one.
// It is then inserted at the spot. Now the marker can move forward.
plexSort: {
.label nxt_idx = 4
.label nxt_y = 5
@ -4658,7 +4658,7 @@ plexSort: {
jmp b5
}
//SEG151 init
// Initialize the program
// Initialize the program
init: {
.label xp = 7
//SEG152 [81] *((const byte*) D011#0) ← (const byte) VIC_DEN#0|(const byte) VIC_RSEL#0|(byte/signed byte/word/signed word/dword/signed dword) 3 -- _deref_pbuc1=vbuc2
@ -4707,7 +4707,7 @@ init: {
bne b1
//SEG168 init::@3
//SEG169 [90] *((const byte*) SPRITES_ENABLE#0) ← (byte/word/signed word/dword/signed dword) 255 -- _deref_pbuc1=vbuc2
// Enable & initialize sprites
// Enable & initialize sprites
lda #$ff
sta SPRITES_ENABLE
//SEG170 [91] phi from init::@3 to init::@2 [phi:init::@3->init::@2]
@ -4730,7 +4730,7 @@ init: {
rts
}
//SEG180 plexInit
// Initialize the multiplexer data structures
// Initialize the multiplexer data structures
plexInit: {
//SEG181 [97] phi from plexInit to plexInit::plexSetScreen1 [phi:plexInit->plexInit::plexSetScreen1]
//SEG182 plexInit::plexSetScreen1
@ -4753,15 +4753,15 @@ plexInit: {
//SEG192 [102] return
rts
}
// Contains the Y-position where each sprite is free again. PLEX_FREE_YPOS[s] holds the Y-position where sprite s is free to use again.
// Contains the Y-position where each sprite is free again. PLEX_FREE_YPOS[s] holds the Y-position where sprite s is free to use again.
PLEX_FREE_YPOS: .fill 8, 0
// The x-positions of the multiplexer sprites ($000-$1ff)
// The x-positions of the multiplexer sprites ($000-$1ff)
PLEX_XPOS: .fill 2*PLEX_COUNT, 0
// The y-positions of the multiplexer sprites.
// The y-positions of the multiplexer sprites.
PLEX_YPOS: .fill PLEX_COUNT, 0
// The sprite pointers for the multiplexed sprites
// The sprite pointers for the multiplexed sprites
PLEX_PTR: .fill PLEX_COUNT, 0
// Indexes of the plex-sprites sorted by sprite y-position. Each call to plexSort() will fix the sorting if changes to the Y-positions have ruined it.
// Indexes of the plex-sprites sorted by sprite y-position. Each call to plexSort() will fix the sorting if changes to the Y-positions have ruined it.
PLEX_SORTED_IDX: .fill PLEX_COUNT, 0
.pc = YSIN "YSIN"
.var min = 50

View File

@ -1,4 +1,4 @@
// 2D rotattion of 8 sprites
// 2D rotattion of 8 sprites
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
@ -12,14 +12,14 @@
.const GREEN = 5
.const LIGHT_BLUE = $e
.label SCREEN = $400
// Sine and Cosine tables
// Angles: $00=0, $80=PI,$100=2*PI
// Sine/Cosine: signed fixed [-$7f,$7f]
// Sine and Cosine tables
// Angles: $00=0, $80=PI,$100=2*PI
// Sine/Cosine: signed fixed [-$7f,$7f]
.label COS = $2000
// A single sprite
// A single sprite
.label SPRITE = $3000
.label SIN = COS+$40
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
main: {
sei
jsr init
@ -55,7 +55,7 @@ anim: {
ldy i
lda xs,y
sta x
// signed fixed[7.0]
// signed fixed[7.0]
lda ys,y
sta y
ldy angle
@ -95,7 +95,7 @@ anim: {
jsr mulf8s_prepared
asl _12
rol _12+1
// signed fixed[8.8]
// signed fixed[8.8]
lda yr
clc
adc _12
@ -148,8 +148,8 @@ anim: {
sta BORDERCOL
jmp b4
}
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8s_prepare(byte a)
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8s_prepare(byte a)
mulf8s_prepared: {
.label memA = $fd
.label m = 5
@ -173,8 +173,8 @@ mulf8s_prepared: {
b2:
rts
}
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8u_prepare(byte a)
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8u_prepare(byte a)
mulf8u_prepared: {
.label resL = $fe
.label memB = $ff
@ -198,7 +198,7 @@ mulf8u_prepared: {
sta return+1
rts
}
// Prepare for fast multiply with an unsigned byte to a word result
// Prepare for fast multiply with an unsigned byte to a word result
mulf8u_prepare: {
.label memA = $fd
sta memA
@ -225,7 +225,7 @@ init: {
bne b1
rts
}
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
mulf_init: {
.label sqr1_hi = 7
.label sqr = 9
@ -326,27 +326,27 @@ mulf_init: {
lda sqr2_lo
cmp #<mulf_sqr2_lo+$1ff
bne b3
// Set the very last value g(511) = f(256)
// Set the very last value g(511) = f(256)
lda mulf_sqr1_lo+$100
sta mulf_sqr2_lo+$1ff
lda mulf_sqr1_hi+$100
sta mulf_sqr2_hi+$1ff
rts
}
// mulf_sqr tables will contain f(x)=int(x*x/4) and g(x) = f(x-255).
// <f(x) = <(( x * x )/4)
// mulf_sqr tables will contain f(x)=int(x*x/4) and g(x) = f(x-255).
// <f(x) = <(( x * x )/4)
.align $100
mulf_sqr1_lo: .fill $200, 0
// >f(x) = >(( x * x )/4)
// >f(x) = >(( x * x )/4)
.align $100
mulf_sqr1_hi: .fill $200, 0
// <g(x) = <((( x - 255) * ( x - 255 ))/4)
// <g(x) = <((( x - 255) * ( x - 255 ))/4)
.align $100
mulf_sqr2_lo: .fill $200, 0
// >g(x) = >((( x - 255) * ( x - 255 ))/4)
// >g(x) = >((( x - 255) * ( x - 255 ))/4)
.align $100
mulf_sqr2_hi: .fill $200, 0
// Positions to rotate
// Positions to rotate
xs: .byte -$46, -$46, -$46, 0, 0, $46, $46, $46
ys: .byte -$46, 0, $46, -$46, $46, -$46, 0, $46
.pc = COS "COS"

View File

@ -2273,7 +2273,7 @@ Allocated zp ZP_BYTE:75 [ mulf_init::$6 ]
INITIAL ASM
//SEG0 File Comments
// 2D rotattion of 8 sprites
// 2D rotattion of 8 sprites
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -2289,11 +2289,11 @@ INITIAL ASM
.const GREEN = 5
.const LIGHT_BLUE = $e
.label SCREEN = $400
// Sine and Cosine tables
// Angles: $00=0, $80=PI,$100=2*PI
// Sine/Cosine: signed fixed [-$7f,$7f]
// Sine and Cosine tables
// Angles: $00=0, $80=PI,$100=2*PI
// Sine/Cosine: signed fixed [-$7f,$7f]
.label COS = $2000
// A single sprite
// A single sprite
.label SPRITE = $3000
.label SIN = COS+$40
//SEG3 @begin
@ -2302,7 +2302,7 @@ bbegin:
//SEG4 @13
b13:
//SEG5 kickasm(location (const byte*) COS#0) {{ { .var min = -$7fff .var max = $7fff .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte >round(min+(ampl/2)+(ampl/2)*cos(rad)) } } }}
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
jmp b16
//SEG6 @16
b16:
@ -2403,7 +2403,7 @@ anim: {
lda xs,y
sta x
//SEG37 [16] (signed byte) anim::y#0 ← *((const signed byte[8]) ys#0 + (byte) anim::i#10) -- vbsz1=pbsc1_derefidx_vbuz2
// signed fixed[7.0]
// signed fixed[7.0]
ldy i
lda ys,y
sta y
@ -2558,7 +2558,7 @@ anim: {
rol
sta _12+1
//SEG83 [42] (signed word) anim::yr#1 ← (signed word) anim::yr#0 + (signed word~) anim::$12 -- vwsz1=vwsz2_plus_vwsz3
// signed fixed[8.8]
// signed fixed[8.8]
lda yr
clc
adc _12
@ -2656,8 +2656,8 @@ anim: {
jmp b1
}
//SEG109 mulf8s_prepared
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8s_prepare(byte a)
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8s_prepare(byte a)
mulf8s_prepared: {
.label memA = $fd
.label _4 = $41
@ -2750,8 +2750,8 @@ mulf8s_prepared: {
rts
}
//SEG134 mulf8u_prepared
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8u_prepare(byte a)
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8u_prepare(byte a)
mulf8u_prepared: {
.label resL = $fe
.label memB = $ff
@ -2785,7 +2785,7 @@ mulf8u_prepared: {
rts
}
//SEG140 mulf8u_prepare
// Prepare for fast multiply with an unsigned byte to a word result
// Prepare for fast multiply with an unsigned byte to a word result
mulf8u_prepare: {
.label memA = $fd
.label a = 8
@ -2852,7 +2852,7 @@ init: {
rts
}
//SEG161 mulf_init
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
mulf_init: {
.label _2 = $49
.label _5 = $4a
@ -3043,7 +3043,7 @@ mulf_init: {
//SEG214 mulf_init::@8
b8:
//SEG215 [121] *((const byte[512]) mulf_sqr2_lo#0+(word/signed word/dword/signed dword) 511) ← *((const byte[512]) mulf_sqr1_lo#0+(word/signed word/dword/signed dword) 256) -- _deref_pbuc1=_deref_pbuc2
// Set the very last value g(511) = f(256)
// Set the very last value g(511) = f(256)
lda mulf_sqr1_lo+$100
sta mulf_sqr2_lo+$1ff
//SEG216 [122] *((const byte[512]) mulf_sqr2_hi#0+(word/signed word/dword/signed dword) 511) ← *((const byte[512]) mulf_sqr1_hi#0+(word/signed word/dword/signed dword) 256) -- _deref_pbuc1=_deref_pbuc2
@ -3064,20 +3064,20 @@ mulf_init: {
//SEG222 [118] phi (byte) mulf_init::dir#3 = (byte) mulf_init::dir#2 [phi:mulf_init::@12->mulf_init::@4#0] -- register_copy
jmp b4
}
// mulf_sqr tables will contain f(x)=int(x*x/4) and g(x) = f(x-255).
// <f(x) = <(( x * x )/4)
// mulf_sqr tables will contain f(x)=int(x*x/4) and g(x) = f(x-255).
// <f(x) = <(( x * x )/4)
.align $100
mulf_sqr1_lo: .fill $200, 0
// >f(x) = >(( x * x )/4)
// >f(x) = >(( x * x )/4)
.align $100
mulf_sqr1_hi: .fill $200, 0
// <g(x) = <((( x - 255) * ( x - 255 ))/4)
// <g(x) = <((( x - 255) * ( x - 255 ))/4)
.align $100
mulf_sqr2_lo: .fill $200, 0
// >g(x) = >((( x - 255) * ( x - 255 ))/4)
// >g(x) = >((( x - 255) * ( x - 255 ))/4)
.align $100
mulf_sqr2_hi: .fill $200, 0
// Positions to rotate
// Positions to rotate
xs: .byte -$46, -$46, -$46, 0, 0, $46, $46, $46
ys: .byte -$46, 0, $46, -$46, $46, -$46, 0, $46
.pc = COS "COS"
@ -3364,7 +3364,7 @@ Allocated (was zp ZP_BYTE:25) zp ZP_BYTE:12 [ anim::y#0 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// 2D rotattion of 8 sprites
// 2D rotattion of 8 sprites
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
@ -3380,11 +3380,11 @@ ASSEMBLER BEFORE OPTIMIZATION
.const GREEN = 5
.const LIGHT_BLUE = $e
.label SCREEN = $400
// Sine and Cosine tables
// Angles: $00=0, $80=PI,$100=2*PI
// Sine/Cosine: signed fixed [-$7f,$7f]
// Sine and Cosine tables
// Angles: $00=0, $80=PI,$100=2*PI
// Sine/Cosine: signed fixed [-$7f,$7f]
.label COS = $2000
// A single sprite
// A single sprite
.label SPRITE = $3000
.label SIN = COS+$40
//SEG3 @begin
@ -3393,7 +3393,7 @@ bbegin:
//SEG4 @13
b13:
//SEG5 kickasm(location (const byte*) COS#0) {{ { .var min = -$7fff .var max = $7fff .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte >round(min+(ampl/2)+(ampl/2)*cos(rad)) } } }}
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
jmp b16
//SEG6 @16
b16:
@ -3485,7 +3485,7 @@ anim: {
lda xs,y
sta x
//SEG37 [16] (signed byte) anim::y#0 ← *((const signed byte[8]) ys#0 + (byte) anim::i#10) -- vbsz1=pbsc1_derefidx_vbuz2
// signed fixed[7.0]
// signed fixed[7.0]
ldy i
lda ys,y
sta y
@ -3594,7 +3594,7 @@ anim: {
asl _12
rol _12+1
//SEG83 [42] (signed word) anim::yr#1 ← (signed word) anim::yr#0 + (signed word~) anim::$12 -- vwsz1=vwsz1_plus_vwsz2
// signed fixed[8.8]
// signed fixed[8.8]
lda yr
clc
adc _12
@ -3680,8 +3680,8 @@ anim: {
jmp b1
}
//SEG109 mulf8s_prepared
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8s_prepare(byte a)
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8s_prepare(byte a)
mulf8s_prepared: {
.label memA = $fd
.label m = 5
@ -3746,8 +3746,8 @@ mulf8s_prepared: {
rts
}
//SEG134 mulf8u_prepared
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8u_prepare(byte a)
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8u_prepare(byte a)
mulf8u_prepared: {
.label resL = $fe
.label memB = $ff
@ -3779,7 +3779,7 @@ mulf8u_prepared: {
rts
}
//SEG140 mulf8u_prepare
// Prepare for fast multiply with an unsigned byte to a word result
// Prepare for fast multiply with an unsigned byte to a word result
mulf8u_prepare: {
.label memA = $fd
//SEG141 [84] *((const byte*) mulf8u_prepare::memA#0) ← (byte) mulf8u_prepare::a#2 -- _deref_pbuc1=vbuaa
@ -3839,7 +3839,7 @@ init: {
rts
}
//SEG161 mulf_init
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
mulf_init: {
.label sqr1_hi = 7
.label sqr = 9
@ -4014,7 +4014,7 @@ mulf_init: {
//SEG214 mulf_init::@8
b8:
//SEG215 [121] *((const byte[512]) mulf_sqr2_lo#0+(word/signed word/dword/signed dword) 511) ← *((const byte[512]) mulf_sqr1_lo#0+(word/signed word/dword/signed dword) 256) -- _deref_pbuc1=_deref_pbuc2
// Set the very last value g(511) = f(256)
// Set the very last value g(511) = f(256)
lda mulf_sqr1_lo+$100
sta mulf_sqr2_lo+$1ff
//SEG216 [122] *((const byte[512]) mulf_sqr2_hi#0+(word/signed word/dword/signed dword) 511) ← *((const byte[512]) mulf_sqr1_hi#0+(word/signed word/dword/signed dword) 256) -- _deref_pbuc1=_deref_pbuc2
@ -4035,20 +4035,20 @@ mulf_init: {
//SEG222 [118] phi (byte) mulf_init::dir#3 = (byte) mulf_init::dir#2 [phi:mulf_init::@12->mulf_init::@4#0] -- register_copy
jmp b4
}
// mulf_sqr tables will contain f(x)=int(x*x/4) and g(x) = f(x-255).
// <f(x) = <(( x * x )/4)
// mulf_sqr tables will contain f(x)=int(x*x/4) and g(x) = f(x-255).
// <f(x) = <(( x * x )/4)
.align $100
mulf_sqr1_lo: .fill $200, 0
// >f(x) = >(( x * x )/4)
// >f(x) = >(( x * x )/4)
.align $100
mulf_sqr1_hi: .fill $200, 0
// <g(x) = <((( x - 255) * ( x - 255 ))/4)
// <g(x) = <((( x - 255) * ( x - 255 ))/4)
.align $100
mulf_sqr2_lo: .fill $200, 0
// >g(x) = >((( x - 255) * ( x - 255 ))/4)
// >g(x) = >((( x - 255) * ( x - 255 ))/4)
.align $100
mulf_sqr2_hi: .fill $200, 0
// Positions to rotate
// Positions to rotate
xs: .byte -$46, -$46, -$46, 0, 0, $46, $46, $46
ys: .byte -$46, 0, $46, -$46, $46, -$46, 0, $46
.pc = COS "COS"
@ -4525,7 +4525,7 @@ FINAL ASSEMBLER
Score: 34700
//SEG0 File Comments
// 2D rotattion of 8 sprites
// 2D rotattion of 8 sprites
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
@ -4541,17 +4541,17 @@ Score: 34700
.const GREEN = 5
.const LIGHT_BLUE = $e
.label SCREEN = $400
// Sine and Cosine tables
// Angles: $00=0, $80=PI,$100=2*PI
// Sine/Cosine: signed fixed [-$7f,$7f]
// Sine and Cosine tables
// Angles: $00=0, $80=PI,$100=2*PI
// Sine/Cosine: signed fixed [-$7f,$7f]
.label COS = $2000
// A single sprite
// A single sprite
.label SPRITE = $3000
.label SIN = COS+$40
//SEG3 @begin
//SEG4 @13
//SEG5 kickasm(location (const byte*) COS#0) {{ { .var min = -$7fff .var max = $7fff .var ampl = max-min; .for(var i=0;i<$140;i++) { .var rad = i*2*PI/256; .byte >round(min+(ampl/2)+(ampl/2)*cos(rad)) } } }}
// sin(x) = cos(x+PI/2)
// sin(x) = cos(x+PI/2)
//SEG6 @16
//SEG7 kickasm(location (const byte*) SPRITE#0) {{ .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) }}
//SEG8 [3] call main
@ -4619,7 +4619,7 @@ anim: {
lda xs,y
sta x
//SEG37 [16] (signed byte) anim::y#0 ← *((const signed byte[8]) ys#0 + (byte) anim::i#10) -- vbsz1=pbsc1_derefidx_vbuz2
// signed fixed[7.0]
// signed fixed[7.0]
lda ys,y
sta y
//SEG38 anim::mulf8s_prepare1
@ -4705,7 +4705,7 @@ anim: {
asl _12
rol _12+1
//SEG83 [42] (signed word) anim::yr#1 ← (signed word) anim::yr#0 + (signed word~) anim::$12 -- vwsz1=vwsz1_plus_vwsz2
// signed fixed[8.8]
// signed fixed[8.8]
lda yr
clc
adc _12
@ -4784,8 +4784,8 @@ anim: {
jmp b4
}
//SEG109 mulf8s_prepared
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8s_prepare(byte a)
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8s_prepare(byte a)
mulf8s_prepared: {
.label memA = $fd
.label m = 5
@ -4834,8 +4834,8 @@ mulf8s_prepared: {
rts
}
//SEG134 mulf8u_prepared
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8u_prepare(byte a)
// Calculate fast multiply with a prepared unsigned byte to a word result
// The prepared number is set by calling mulf8u_prepare(byte a)
mulf8u_prepared: {
.label resL = $fe
.label memB = $ff
@ -4865,7 +4865,7 @@ mulf8u_prepared: {
rts
}
//SEG140 mulf8u_prepare
// Prepare for fast multiply with an unsigned byte to a word result
// Prepare for fast multiply with an unsigned byte to a word result
mulf8u_prepare: {
.label memA = $fd
//SEG141 [84] *((const byte*) mulf8u_prepare::memA#0) ← (byte) mulf8u_prepare::a#2 -- _deref_pbuc1=vbuaa
@ -4913,7 +4913,7 @@ init: {
rts
}
//SEG161 mulf_init
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
mulf_init: {
.label sqr1_hi = 7
.label sqr = 9
@ -5068,7 +5068,7 @@ mulf_init: {
bne b3
//SEG214 mulf_init::@8
//SEG215 [121] *((const byte[512]) mulf_sqr2_lo#0+(word/signed word/dword/signed dword) 511) ← *((const byte[512]) mulf_sqr1_lo#0+(word/signed word/dword/signed dword) 256) -- _deref_pbuc1=_deref_pbuc2
// Set the very last value g(511) = f(256)
// Set the very last value g(511) = f(256)
lda mulf_sqr1_lo+$100
sta mulf_sqr2_lo+$1ff
//SEG216 [122] *((const byte[512]) mulf_sqr2_hi#0+(word/signed word/dword/signed dword) 511) ← *((const byte[512]) mulf_sqr1_hi#0+(word/signed word/dword/signed dword) 256) -- _deref_pbuc1=_deref_pbuc2
@ -5082,20 +5082,20 @@ mulf_init: {
//SEG221 [118] phi from mulf_init::@12 to mulf_init::@4 [phi:mulf_init::@12->mulf_init::@4]
//SEG222 [118] phi (byte) mulf_init::dir#3 = (byte) mulf_init::dir#2 [phi:mulf_init::@12->mulf_init::@4#0] -- register_copy
}
// mulf_sqr tables will contain f(x)=int(x*x/4) and g(x) = f(x-255).
// <f(x) = <(( x * x )/4)
// mulf_sqr tables will contain f(x)=int(x*x/4) and g(x) = f(x-255).
// <f(x) = <(( x * x )/4)
.align $100
mulf_sqr1_lo: .fill $200, 0
// >f(x) = >(( x * x )/4)
// >f(x) = >(( x * x )/4)
.align $100
mulf_sqr1_hi: .fill $200, 0
// <g(x) = <((( x - 255) * ( x - 255 ))/4)
// <g(x) = <((( x - 255) * ( x - 255 ))/4)
.align $100
mulf_sqr2_lo: .fill $200, 0
// >g(x) = >((( x - 255) * ( x - 255 ))/4)
// >g(x) = >((( x - 255) * ( x - 255 ))/4)
.align $100
mulf_sqr2_hi: .fill $200, 0
// Positions to rotate
// Positions to rotate
xs: .byte -$46, -$46, -$46, 0, 0, $46, $46, $46
ys: .byte -$46, 0, $46, -$46, $46, -$46, 0, $46
.pc = COS "COS"

View File

@ -14,7 +14,7 @@ main: {
lda #>TEXT
sta nxt+1
ldx #7
// Wait for raster
// Wait for raster
b2:
lda RASTER
cmp #$fe
@ -28,14 +28,14 @@ main: {
cpx #$ff
bne b4
ldx #0
// Hard scroll
// Hard scroll
b5:
lda line+1,x
sta line,x
inx
cpx #$27
bne b5
// Render next char
// Render next char
ldy #0
lda (nxt),y
tax

View File

@ -667,7 +667,7 @@ main: {
lda #7
sta scroll
jmp b2
// Wait for raster
// Wait for raster
//SEG16 [6] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
b2_from_b2:
jmp b2
@ -701,7 +701,7 @@ main: {
lda #0
sta i
jmp b5
// Hard scroll
// Hard scroll
//SEG27 [12] phi from main::@5 to main::@5 [phi:main::@5->main::@5]
b5_from_b5:
//SEG28 [12] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@5->main::@5#0] -- register_copy
@ -722,7 +722,7 @@ main: {
//SEG33 main::@10
b10:
//SEG34 [16] (byte) main::c#0 ← *((byte*) main::nxt#9) -- vbuz1=_deref_pbuz2
// Render next char
// Render next char
ldy #0
lda (nxt),y
sta c
@ -906,7 +906,7 @@ main: {
//SEG15 [6] phi (byte) main::scroll#7 = (byte/signed byte/word/signed word/dword/signed dword) 7 [phi:main->main::@2#1] -- vbuxx=vbuc1
ldx #7
jmp b2
// Wait for raster
// Wait for raster
//SEG16 [6] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
b2_from_b2:
jmp b2
@ -938,7 +938,7 @@ main: {
//SEG26 [12] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@8->main::@5#0] -- vbuxx=vbuc1
ldx #0
jmp b5
// Hard scroll
// Hard scroll
//SEG27 [12] phi from main::@5 to main::@5 [phi:main::@5->main::@5]
b5_from_b5:
//SEG28 [12] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@5->main::@5#0] -- register_copy
@ -957,7 +957,7 @@ main: {
//SEG33 main::@10
b10:
//SEG34 [16] (byte) main::c#0 ← *((byte*) main::nxt#9) -- vbuxx=_deref_pbuz1
// Render next char
// Render next char
ldy #0
lda (nxt),y
tax
@ -1206,7 +1206,7 @@ main: {
sta nxt+1
//SEG15 [6] phi (byte) main::scroll#7 = (byte/signed byte/word/signed word/dword/signed dword) 7 [phi:main->main::@2#1] -- vbuxx=vbuc1
ldx #7
// Wait for raster
// Wait for raster
//SEG16 [6] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
//SEG17 main::@2
b2:
@ -1231,7 +1231,7 @@ main: {
//SEG25 [12] phi from main::@8 to main::@5 [phi:main::@8->main::@5]
//SEG26 [12] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@8->main::@5#0] -- vbuxx=vbuc1
ldx #0
// Hard scroll
// Hard scroll
//SEG27 [12] phi from main::@5 to main::@5 [phi:main::@5->main::@5]
//SEG28 [12] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@5->main::@5#0] -- register_copy
//SEG29 main::@5
@ -1246,7 +1246,7 @@ main: {
bne b5
//SEG33 main::@10
//SEG34 [16] (byte) main::c#0 ← *((byte*) main::nxt#9) -- vbuxx=_deref_pbuz1
// Render next char
// Render next char
ldy #0
lda (nxt),y
tax

View File

@ -1,4 +1,4 @@
// An 8x8 char letter scroller
// An 8x8 char letter scroller
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
@ -24,7 +24,7 @@ main: {
lda #1
sta current_bit
ldx #7
// Wait for raster
// Wait for raster
b2:
lda RASTER
cmp #$fe
@ -116,7 +116,7 @@ scroll_bit: {
}
scroll_hard: {
ldx #0
// Hard scroll
// Hard scroll
b1:
lda SCREEN+1,x
sta SCREEN,x
@ -139,7 +139,7 @@ scroll_hard: {
bne b1
rts
}
// Find the next char of the scroll text
// Find the next char of the scroll text
next_char: {
ldy #0
lda (nxt),y
@ -157,7 +157,7 @@ next_char: {
!:
rts
}
// Fill the screen with one char
// Fill the screen with one char
fillscreen: {
.const fill = $20
.label cursor = 3

Some files were not shown because too many files have changed in this diff Show More