mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-05 21:30:52 +00:00
Implemented sinus generator for logo scroller. Added missing fragments and fixed issue when removing an unused block also made some variables unused.
This commit is contained in:
parent
2c0299ee09
commit
5e9b15477a
@ -1,17 +1,17 @@
|
||||
package dk.camelot64.kickc.asm;
|
||||
|
||||
/** Inlined KickAssembler code.
|
||||
* If no cycles/byte size is specified it defaults to 100/100.
|
||||
* */
|
||||
* If no cycles/byte size is specified it defaults to 256/256.
|
||||
*/
|
||||
public class AsmInlineKickAsm implements AsmLine {
|
||||
|
||||
private String kickAsmCode;
|
||||
|
||||
private int index;
|
||||
|
||||
private int bytes = 100;
|
||||
private int bytes = 256;
|
||||
|
||||
private double cycles = 100;
|
||||
private double cycles = 256;
|
||||
|
||||
public AsmInlineKickAsm(String kickAsmCode) {
|
||||
this.kickAsmCode= kickAsmCode;
|
||||
|
@ -0,0 +1,4 @@
|
||||
asl {z1}
|
||||
rol {z1}+1
|
||||
rol {z1}+2
|
||||
rol {z1}+3
|
@ -0,0 +1,12 @@
|
||||
lda {z2}
|
||||
asl
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
rol
|
||||
sta {z1}+1
|
||||
lda {z2}+2
|
||||
rol
|
||||
sta {z1}+2
|
||||
lda {z2}+3
|
||||
rol
|
||||
sta {z1}+3
|
@ -0,0 +1,4 @@
|
||||
lda {z2}+2
|
||||
sta {z1}
|
||||
lda {z2}+3
|
||||
sta {z1}+1
|
@ -0,0 +1,7 @@
|
||||
lda {z1}
|
||||
sec
|
||||
sbc #<{c1}
|
||||
sta {z2}
|
||||
lda {z1}+1
|
||||
sbc #>{c1}
|
||||
sta {z2}+1
|
@ -570,7 +570,8 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
|
||||
@Override
|
||||
public Object visitExprAssignment(KickCParser.ExprAssignmentContext ctx) {
|
||||
LValue lValue = (LValue) visit(ctx.expr(0));
|
||||
Object val = visit(ctx.expr(0));
|
||||
LValue lValue = (LValue) val;
|
||||
if(lValue instanceof VariableRef && ((VariableRef) lValue).isIntermediate()) {
|
||||
// Encountered an intermediate variable. This must be turned into a proper LValue later. Put it into a marker to signify that
|
||||
lValue = new LvalueIntermediate((VariableRef) lValue);
|
||||
|
@ -3,10 +3,15 @@ package dk.camelot64.kickc.passes;
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.Label;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.LValue;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.values.SymbolRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.ListIterator;
|
||||
@ -26,9 +31,18 @@ public class Pass2EliminateUnusedBlocks extends Pass2SsaOptimization {
|
||||
Set<LabelRef> unusedBlocks = new LinkedHashSet<>();
|
||||
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
||||
if(!referencedBlocks.contains(block.getLabel())) {
|
||||
|
||||
|
||||
unusedBlocks.add(block.getLabel());
|
||||
for(Statement stmt : block.getStatements()) {
|
||||
if(stmt instanceof StatementAssignment) {
|
||||
StatementAssignment assignment = (StatementAssignment) stmt;
|
||||
LValue lValue = assignment.getlValue();
|
||||
if(lValue instanceof VariableRef) {
|
||||
getLog().append("Eliminating variable " + lValue.toString(getProgram()) + " and from unused block " + block.getLabel());
|
||||
Variable variable = getScope().getVariable((VariableRef) lValue);
|
||||
variable.getScope().remove(variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for(LabelRef unusedBlock : unusedBlocks) {
|
||||
|
@ -45,6 +45,11 @@ public class TestPrograms {
|
||||
AsmFragmentTemplateUsages.logUsages(log, false, false, false, false, false, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScrollLogo() throws IOException, URISyntaxException {
|
||||
compileAndCompare("scrolllogo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowLogo() throws IOException, URISyntaxException {
|
||||
compileAndCompare("showlogo");
|
||||
|
79
src/test/java/dk/camelot64/kickc/test/kc/scrolllogo.kc
Normal file
79
src/test/java/dk/camelot64/kickc/test/kc/scrolllogo.kc
Normal file
@ -0,0 +1,79 @@
|
||||
import "c64.kc"
|
||||
import "sinus.kc"
|
||||
|
||||
byte* SCREEN = $400;
|
||||
byte* LOGO = $2000;
|
||||
|
||||
const word XSIN_SIZE = 512;
|
||||
|
||||
signed word[512] align($100) xsin;
|
||||
|
||||
void main() {
|
||||
*BORDERCOL = WHITE;
|
||||
*BGCOL = *BGCOL2 = DARK_GREY;
|
||||
*BGCOL3 = BLACK;
|
||||
*D018 = toD018(SCREEN, LOGO);
|
||||
*D016 = VIC_MCM | VIC_CSEL;
|
||||
fill(SCREEN, 1000, BLACK);
|
||||
fill(COLS, 1000, WHITE|8);
|
||||
for(byte ch: 0..239) {
|
||||
SCREEN[ch] = ch;
|
||||
}
|
||||
sin16s_gen2(xsin, XSIN_SIZE, -320, 320);
|
||||
loop();
|
||||
}
|
||||
|
||||
// Generate signed word sinus table - with values in the range min-max.
|
||||
// sintab - the table to generate into
|
||||
// wavelength - the number of sinus points in a total sinus wavelength (the size of the table)
|
||||
void sin16s_gen2(signed word* sintab, word wavelength, signed word min, signed word max) {
|
||||
signed word ampl = max-min;
|
||||
signed word offs = min + ampl>>1; // ampl is always positive so shifting left does not alter the sign
|
||||
// u[4.28] step = PI*2/wavelength
|
||||
dword step = div32u16u(PI2_u4f28, wavelength); // u[4.28]
|
||||
// Iterate over the table
|
||||
dword x = 0; // u[4.28]
|
||||
for( word i=0; i<wavelength; i++) {
|
||||
signed dword ssin = mul16s(sin16s(x), ampl); // The signed sin() only has values [-1/2 ; 1/2] there ampl*sin has the right amplitude
|
||||
*sintab = offs + (signed word)>ssin;
|
||||
sintab = sintab + 2;
|
||||
x = x + step;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
word xsin_idx = 0;
|
||||
|
||||
void loop() {
|
||||
while(true) {
|
||||
while(*RASTER!=$ff) {}
|
||||
signed word xpos = *(xsin+xsin_idx>>1);
|
||||
SCREEN[0] = <xpos;
|
||||
SCREEN[1] = >xpos;
|
||||
xsin_idx += 2;
|
||||
if(xsin_idx==XSIN_SIZE) {
|
||||
xsin_idx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Fill some memory with a value
|
||||
void fill(byte* start, word size, byte val) {
|
||||
byte* end = start + size;
|
||||
for(byte* addr = start; addr!=end; addr++) {
|
||||
*addr = val;
|
||||
}
|
||||
}
|
||||
|
||||
kickasm(resources "logo.png" ) {{
|
||||
.label pc_restore = *
|
||||
.pc = $2000
|
||||
logo:
|
||||
.var logoPic = LoadPicture("logo.png", List().add($444444, $808080, $000000, $ffffff))
|
||||
.for (var y=0; y<6 ; y++)
|
||||
.for (var x=0;x<40; x++)
|
||||
.for(var cp=0; cp<8; cp++)
|
||||
.byte logoPic.getMulticolorByte(x,cp+y*8)
|
||||
.pc = pc_restore
|
||||
}}
|
Loading…
x
Reference in New Issue
Block a user