1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2026-04-22 09:17:00 +00:00

Added support for CPU HUC6280.

This commit is contained in:
jespergravgaard
2022-01-30 21:41:50 +01:00
parent ec3120fc1d
commit 517b2af6d5
41 changed files with 23094 additions and 17 deletions
+1 -1
View File
@@ -79,7 +79,7 @@
<dependency>
<groupId>cml.kickass</groupId>
<artifactId>kickassembler</artifactId>
<version>5.24-65ce02.a</version>
<version>5.24-65ce02.b</version>
</dependency>
<dependency>
<groupId>dk.camelot64.kickass.xexplugin</groupId>
@@ -0,0 +1 @@
0c00040f87c87fb73965e1f53afe7dcc
@@ -0,0 +1 @@
d51578b4523d90c4d5d5e9e3fe2806b42fd4a2ea
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>cml.kickass</groupId>
<artifactId>kickassembler</artifactId>
<version>5.24-65ce02.b</version>
<description>POM was created from install:install-file</description>
</project>
@@ -0,0 +1 @@
a4241896151d8ae9bad33889412751d9
@@ -0,0 +1 @@
3e36d1dbb157f463b0459185f396ce8da6f93ad9
@@ -3,7 +3,7 @@
<groupId>cml.kickass</groupId>
<artifactId>kickassembler</artifactId>
<versioning>
<release>5.24-65ce02.a</release>
<release>5.24-65ce02.b</release>
<versions>
<version>4.19</version>
<version>5.7</version>
@@ -28,7 +28,8 @@
<version>5.22-65ce02.a</version>
<version>5.23-65ce02.a</version>
<version>5.24-65ce02.a</version>
<version>5.24-65ce02.b</version>
</versions>
<lastUpdated>20220123234604</lastUpdated>
<lastUpdated>20220130203320</lastUpdated>
</versioning>
</metadata>
@@ -1 +1 @@
e21df397cfbdfffab5bdf0710903e415
0f43678d3dce50a145dd7e42adc79ca1
@@ -1 +1 @@
e1786fe7f339b0358623f3109c1e3aa3306c9011
2b207a0d7add8d7cd4ebc8a58ddbbbd2e6122739
@@ -165,7 +165,7 @@ ASM_MNEMONIC:
'tsb' | 'wai' | 'cle' | 'see' | 'tsy' | 'lbpl'| 'inz' | 'tys' | 'lbmi'| 'dez' | 'neg' | 'asr' | 'taz' | 'lbvc'| 'tab' | 'map' | 'rtn' | 'lbsr'| 'tza' |
'lbvs'| 'tba' | 'lbra'| 'lbcc'| 'ldz' | 'lbcs'| 'cpz' | 'dew' | 'asw' | 'lbne'| 'phz' | 'inw' | 'row' | 'lbeq'| 'phw' | 'plz' | 'eom' | 'adcq'| 'andq'|
'aslq'| 'asrq'| 'bitq'| 'cpq' | 'deq' | 'eorq'| 'inq' | 'ldq' | 'lsrq'| 'orq' | 'rolq'| 'rorq'| 'sbcq'| 'stq' | 'sxy' | 'st0' | 'st1' | 'st2' | 'say' |
'tma' | 'bsr' | 'tam' | 'csl' | 'cla' | 'clx' | 'cly' | 'csh' | 'set'
'tma' | 'bsr' | 'tam' | 'csl' | 'cla' | 'clx' | 'cly' | 'csh' | 'set' | 'tst'
;
ASM_IMM : '#' ;
@@ -305,6 +305,7 @@ asmParamMode
| ASM_PAR_BEGIN asmExpr ASM_COMMA ASM_NAME ASM_PAR_END #asmModeIdxIndXY
| ASM_PAR_BEGIN asmExpr ASM_PAR_END #asmModeInd
| ASM_PAR_BEGIN ASM_PAR_BEGIN asmExpr ASM_PAR_END ASM_PAR_END #asmModeIndLong
| ASM_IMM asmExpr ASM_COMMA asmExpr #asmModeImmAndAbs
;
asmExpr
@@ -176,7 +176,20 @@ public enum CpuAddressingMode {
* test, and one indicating the signed relative PC offset if the branch is taken. This makes BBRi and BBSi the single
* instructions with two explicit operands.
*/
REZ("zp,rel", "%i %p,%q", 2);
REZ("zp,rel", "%i %p,%q", 2),
/**
* #imm,zp Immediate, zeropage <br>
* IMMEDIATE ADDRESSING, ZEROPAGE — Two parameters, one immediate the other a zeropage address. Only used by HUC6280 TST.
*/
IMMANDZP("#imm,zp", "%i #%p,%q", 3),
/**
* #imm,abs Immediate, absolute <br>
* IMMEDIATE ADDRESSING, ABSOLUTE — Two parameters, one immediate the other an absolute address. Only used by HUC6280 TST.
*/
IMMANDABS("#imm,abs", "%i #%p,%q", 4);
/** The short name of the addressing mode. */
private String name;
@@ -45,6 +45,8 @@ public class CpuHuc6280 extends Cpu65xx {
addOpcode(0xc2,"cly", CpuAddressingMode.NON,2,"Y");
addOpcode(0xd4,"csh", CpuAddressingMode.NON,2,"");
addOpcode(0xf4,"set", CpuAddressingMode.NON,2,"");
addOpcode(0x83,"tst", CpuAddressingMode.IMMANDZP,7,"vnz");
addOpcode(0xA3,"tst", CpuAddressingMode.IMMANDABS,8,"vnz");
}
}
@@ -286,6 +286,11 @@ public class AsmFragmentInstance {
return createAsmInstruction(ctx, ctx.asmExpr(), null, CpuAddressingMode.IMM);
}
@Override
public Object visitAsmModeImmAndAbs(KickCParser.AsmModeImmAndAbsContext ctx) {
return createAsmInstruction(ctx, ctx.asmExpr(0), ctx.asmExpr(1), CpuAddressingMode.IMMANDABS);
}
@Override
public Object visitAsmModeAbsXY(KickCParser.AsmModeAbsXYContext ctx) {
final KickCParser.AsmExprContext indexCtx = ctx.asmExpr(1);
+1 -1
View File
@@ -4,7 +4,7 @@
cp ./repo/cml/kickass/kickassembler/maven-metadata.xml ./repo/cml/kickass/kickassembler/maven-metadata-local.xml
# mvn install:install-file -Dmaven.repo.local=./repo/ -Dfile=/Applications/KickAssembler/KickAss.jar -DgroupId=cml.kickass -DartifactId=kickassembler -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true -Dversion=5.16
mvn install:install-file -Dmaven.repo.local=./repo/ -Dfile=/Users/jespergravgaard/c64/kickassembler65ce02/out/KickAss65CE02.jar -DgroupId=cml.kickass -DartifactId=kickassembler -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true -Dversion=5.24-65ce02.a
mvn install:install-file -Dmaven.repo.local=./repo/ -Dfile=/Users/jespergravgaard/c64/kickassembler65ce02/out/KickAss65CE02.jar -DgroupId=cml.kickass -DartifactId=kickassembler -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true -Dversion=5.24-65ce02.b
# Finalize by making the local metadata official
pushd ./repo/cml/kickass/kickassembler
@@ -9,6 +9,27 @@ import java.io.IOException;
*/
public class TestProgramsFast extends TestPrograms {
@Test
public void testPointerSwap() throws IOException {
compileAndCompare("pointer-swap.c", log());
}
@Test
public void testDucksTotal() throws IOException {
compileAndCompare("ducks-total.c", log());
}
@Test
public void testDucksLoop211() throws IOException {
compileAndCompare("ducks-loop211.c", log());
}
@Test
public void testDucksArray() throws IOException {
compileAndCompare("ducks-array.c", log());
}
@Test
public void testSepaOptimizeProblem1() throws IOException {
compileAndCompare("sepa-optimize-problem-1.c");
+2
View File
@@ -20,6 +20,8 @@ void main() {
cly
csh
set
tst #1+2,$3+4
tst #1+2*3,$7654/2
!:
rts
}
+14
View File
@@ -0,0 +1,14 @@
#include <stdio.h>
unsigned byte points[]={1,2,3,4};
void chrout(volatile char register(A) petscii)
{ asm { jsr $ffd2 }}
void main()
{
chrout(149);
chrout(points[0]);
chrout(points[1]);
chrout(points[2]);
chrout(points[3]);
}
+22
View File
@@ -0,0 +1,22 @@
#include <peekpoke.h>
#include <6502.h>
const unsigned byte brick=230;
void chrout(volatile char petscii)
{
asm {
lda petscii
jsr $ffd2
}
}
void main()
{
char k=1;
do {
POKE(211,k*4);
chrout(brick);
++k;
} while (k<5);
}
+157
View File
@@ -0,0 +1,157 @@
#include <stdio.h>
#include <peekpoke.h>
#include <stdlib.h>
#include <division.h>
unsigned byte j,k,l,m,n=0; // [0..255] 8-bit
unsigned short tu,duck,peephole,y,z,time,score,hiscore=0; // [0..65536] 16-bit
unsigned byte points[]={0,0,0,0};
unsigned byte buffer[]={0,0,0,0};
const unsigned byte down=17,right=29,lock=8,lower=14;
const unsigned byte home=19,reverse_on=18,brick=230;
const unsigned byte green=30,yellow=158,red=28;
const unsigned short c=30720; // for unexpanded. 37888-4096 color for expanded
const unsigned byte ducknumber[]={68,85,67,75,58}; // DUCK:
const unsigned byte chrono[]={84,77,58,57}; // TM:9
const unsigned byte duck_udg[]={14,27,63,31,15,7,15,31,0,0,0,0,0,192,112,188,31,29,30,15,3,1,1,3,206,30,124,248,224,64,64,224,0,0,0,0,0,0,0,0};
// POKE CODES = 0,1,2,3,4; CHROUT CODES = 64, 65, 66, 67, 68 (with previous reverse_off "chrout(146)")
const unsigned byte intro[]="\n\n\nDIFFICULTY\n----------\n\n\n";
const unsigned byte levels[]="1.EASIEST\n\n3.EASY\n\n5.MEDIUM\n\n7.HARD\n\n9.EXPERT\n\n\n\n\n";
const unsigned byte foot[]="PRESS: 1,3,5,7 or 9\n\n";
const unsigned byte game_over[]="\n\n\n\nGAME OVER";
const unsigned byte play_again[]="\n\n\nPlay Again (Y/N)?";
const unsigned byte your_score[]="\n\n\nYour Score: ";
const unsigned byte high_score[]="\n\nHi-Score: ";
void clear_screen(byte n, byte m)
{ for (z=0; z<506; ++z) { POKE(7680+z+c,m); POKE(7680+z,n); } // From 0-->505 (506 bytes). ClearScreen with byte 'n' with color 'm'
gotoxy(0,0); chrout(home); } // Return to home position
void random(byte k, byte n) // Random { k..n }
{ do { m=PEEK(37140); }
while (m<k || m>n); }
void chrout(volatile char petscii)
{ asm { lda petscii jsr $ffd2 }}
void write_score(void) {
if (score>65000) score=0;
for (m=0;m<4;m++) { points[m]='0'; } // (!!) Needed. Possibly a bug
utoa(score,buffer,10);
if (score>9) { points[2]=buffer[0];points[3]=buffer[1]; }
if (score>99) { points[1]=buffer[0];points[2]=buffer[1];points[3]=buffer[2]; }
chrout(yellow);chrout(home);POKE(211,4);
for (m=0;m<4;m++) { chrout(points[m]); }
}
void wait(byte n)
{ for (m=0;m<n;++m) { for (z=0;z<540;++z) {}; } }
void chrono_restart(void)
{ asm {
lda #0
ldy #0
ldx #0
jsr $ffdb }; }
void read_chrono(void) // time (in seconds)
{ asm {
jsr $ffde
sta l
stx m
};
time=div16u8u((m*256)+l,60);
POKE (7701+c,7); POKE(7701,185);
if (time<10) POKE(7701,185-time); // if chrono<10 write time, otherwise write '9'. it avoids '/' symbol. Yellow
}
void main()
{
POKE(36879,8); // border and black paper
chrout(lock); //Lock UpperCase to Lowercase key
chrout(lower); //Put text in Lowercase set
for (m=0; m<40; m++) POKE(7168+m,duck_udg[m]);  // Load udgs. From 0-->39;
do {
clear_screen(32,0); // Clear Screen with spaces & black ink
textcolor(7); cputs(intro); // Yellow ink
textcolor(1); cputs(levels); // White
textcolor(2); cputs(foot); // Red
do { l=PEEK(197); ++l; } while (l>5); // wait for 1-3-5-7-9 keys only
clear_screen(4,0); // with (4=duser defined). Black ink
POKE(36869,255); // Graphic mode
chrout(reverse_on);chrout(red);chrout(down);
//for (z=1;z<23;z++) { POKE(7680+z*22,230);POKE(c+7680+z*22,2); POKE(7679+z*22,230); POKE(c+7679+z*22,2); } // 23 rows * 22 columns (7680 to 8185). 506 positions.
//k=1; do { chrout(brick); POKE(211,20); chrout(brick); ++k; } while (k<23);
//for (k=1;k<22;k++) { chrout(brick); POKE(211,22); chrout(brick); }; // 23 rows * 22 columns (7680 to 8185). 506 positions.
for (k=1;k<22;k++) { chrout(brick); for(n=2;n<22;++n) { chrout(right); }; chrout(brick); }; // 23 rows * 22 columns (7680 to 8185). 506 positions.
chrout(brick); // first brick from last line (#23)
POKE(8185,brick);POKE(8185+c,2); //last brick from last line (#23) to avoid scrolling
chrout(home); z=1; // First position
if (l>1) {
do { // Write differential random bricks depending on 'l' level choosen
random((7-l),26-(3*l)); // Random number is 'm' (interleaves are level-dependent)
if (z+m>505) break;
for (j=1; j<=m; ++j) chrout(right);
chrout(brick); z=z+m+1; }
while (z<506);
}
peephole=7967; // Initial peephole position
POKE(36878,15); // Volume to max
score=0;
tu=1; // Duck #1
chrout(home);chrout(yellow);chrout(80);chrout(84);chrout(83);chrout(58); // Write 'PTS:', yellow
POKE(211,18); // jump to Column 18
for (j=0; j<4; ++j) { chrout(chrono[j]); }; // Write 'TM:9', yellow
write_score(); // Write Score (yellow)
chrout(home);chrout(green);POKE(211,10); // Jump to column 10
for (j=0; j<5; j++) { chrout(ducknumber[j]); }; // Write 'DUCK', green
do {
chrout(home);chrout(green);chrout(reverse_on);
POKE(211,15); // Jump to column 15
if (tu<10) { chrout(48+tu) }; else { chrout(49);chrout(48); } // Write duck number
do { random(0,255); duck=m; random(0,255); duck=m+7701+duck; } // Choose randon Duck position (in 2 parts random+random)
while ((duck>8163) || PEEK(duck)==brick || PEEK(duck+1)==brick || PEEK(duck+22)==brick || PEEK(duck+23)==brick);
time=0;chrono_restart();
while (time<10) // ...until 10 seconds
{ read_chrono();
// Joystick routine
m=PEEK(37151); POKE(37154,127);
n=PEEK(37152); POKE(37154,255);
if ((16&m)==0) y--; // Left
if ((128&n)==0) y++; // Right
if ((4&m)==0) y=y-22; // Up
if ((8&m)==0) y=y+22; // Down
if ((32&m)==0) // FIRE!!
{ POKE(36877,130);
if (peephole!=duck) { score=score-10; write_score(); wait(10); } // We hit the duck!
else { score=score+(12-time)*10; wait(10);time=10; } // We fail!
POKE(36877,0); // Stop sounds
}
if (PEEK(y)!=brick && PEEK(y+1)!=brick && PEEK(y+22)!=brick && PEEK(y+23)!=brick && y>7702 && y<8163)
{ POKE(peephole+c,0); POKE(peephole+c+1,0); POKE(peephole+c+22,0); POKE(peephole+c+23,0); peephole=y; } // Check if peephole touches some bricks
y=peephole;
POKE(peephole,253);POKE(peephole+c,1);POKE(peephole+1,237);POKE(peephole+1+c,1);
POKE(peephole+22,238);POKE(peephole+22+c,1);POKE(peephole+23,240);POKE(peephole+23+c,1); // Clear peephole if there is not bricks contact
wait(5);
POKE(duck,0);POKE(duck+c,7);POKE(duck+1,1);POKE(duck+1+c,7); // Draw duck (udg)
POKE(duck+22,2);POKE(duck+22+c,7);POKE(duck+23,3);POKE(duck+23+c,7);
wait(5);
}
tu++; // Next duck
score=score-10;write_score(); // Substract 10 points if time finishes
POKE(36877,130);wait(20);POKE(36877,0); // Make some noise
POKE(duck+c,0); POKE(duck+1+c,0); POKE(duck+22+c,0); POKE(duck+23+c,0); // Clear previous duck draw
}
while (tu<11); // 10 ducks
clear_screen(4,0); // Clear screen with user-defined spaces & black ink
POKE(36869,240);chrout(lower); // Return to text mode, lowcase
textcolor(7); cputs(game_over); // Yellow
textcolor(2); cputs(your_score); cputs(buffer); // Red
textcolor(3); cputs(high_score); if (score>hiscore) hiscore=score; utoa(hiscore,buffer,10); cputs(buffer); // Cyan
textcolor(1); cputs(play_again); // white
do { j=PEEK(197); } while (j!= 11 && j!=28 ); // Wait for Y or N
} // Y pressed --> start again
while (j==11); // N pressed. Exit game
asm {jsr $FD22}; // Reset the VIC.
}
+31
View File
@@ -0,0 +1,31 @@
byte buffer1[10];
byte buffer2[10];
byte *newbuffer = buffer1;
byte *oldbuffer = buffer2;
byte *tempbuffer;
char* screen = (char*)0x0400;
char hextab[] = "0123456789abcdef"z;
void print() {
screen[0] = hextab[(char)tempbuffer&0x0f];
screen[2] = hextab[(char)newbuffer&0x0f];
screen[4] = hextab[(char)oldbuffer&0x0f];
screen += 40;
}
void swap() {
tempbuffer = newbuffer;
newbuffer = oldbuffer;
oldbuffer = tempbuffer;
print();
}
void main() {
print();
swap();
swap();
swap();
}
+2
View File
@@ -26,6 +26,8 @@ main: {
cly
csh
set
tst #1+2,3+4
tst #1+2*3,$7654/2
!:
rts
// }
+1 -1
View File
@@ -1,7 +1,7 @@
void main()
main: scope:[main] from
asm { sxy st0#$55 st1#$aa sax st2#$be say tma#2 bsr!+ tam#4 csl cla clx cly csh set !: rts }
asm { sxy st0#$55 st1#$aa sax st2#$be say tma#2 bsr!+ tam#4 csl cla clx cly csh set tst#1+2,$3+4 tst#1+2*3,$7654/2 !: rts }
to:main::@return
main::@return: scope:[main] from main
[1] return
+12 -8
View File
@@ -3,7 +3,7 @@ CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
asm { sxy st0#$55 st1#$aa sax st2#$be say tma#2 bsr!+ tam#4 csl cla clx cly csh set !: rts }
asm { sxy st0#$55 st1#$aa sax st2#$be say tma#2 bsr!+ tam#4 csl cla clx cly csh set tst#1+2,$3+4 tst#1+2*3,$7654/2 !: rts }
to:main::@return
main::@return: scope:[main] from main
return
@@ -37,7 +37,7 @@ FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
asm { sxy st0#$55 st1#$aa sax st2#$be say tma#2 bsr!+ tam#4 csl cla clx cly csh set !: rts }
asm { sxy st0#$55 st1#$aa sax st2#$be say tma#2 bsr!+ tam#4 csl cla clx cly csh set tst#1+2,$3+4 tst#1+2*3,$7654/2 !: rts }
to:main::@return
main::@return: scope:[main] from main
[1] return
@@ -50,14 +50,14 @@ void main()
Initial phi equivalence classes
Complete equivalence classes
REGISTER UPLIFT POTENTIAL REGISTERS
Statement asm { sxy st0#$55 st1#$aa sax st2#$be say tma#2 bsr!+ tam#4 csl cla clx cly csh set !: rts } always clobbers reg byte a reg byte x reg byte y
Statement asm { sxy st0#$55 st1#$aa sax st2#$be say tma#2 bsr!+ tam#4 csl cla clx cly csh set tst#1+2,$3+4 tst#1+2*3,$7654/2 !: rts } always clobbers reg byte a reg byte x reg byte y
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope []
Uplifting [main] best 65 combination
Uplifting [] best 65 combination
Uplifting [main] best 81 combination
Uplifting [] best 81 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@@ -76,7 +76,7 @@ ASSEMBLER BEFORE OPTIMIZATION
.segment Code
// main
main: {
// asm { sxy st0#$55 st1#$aa sax st2#$be say tma#2 bsr!+ tam#4 csl cla clx cly csh set !: rts }
// asm { sxy st0#$55 st1#$aa sax st2#$be say tma#2 bsr!+ tam#4 csl cla clx cly csh set tst#1+2,$3+4 tst#1+2*3,$7654/2 !: rts }
sxy
st0 #$55
st1 #$aa
@@ -92,6 +92,8 @@ main: {
cly
csh
set
tst #1+2,3+4
tst #1+2*3,$7654/2
!:
rts
jmp __breturn
@@ -116,7 +118,7 @@ void main()
FINAL ASSEMBLER
Score: 56
Score: 72
// File Comments
// Tests the HUC6280 instructions
@@ -135,7 +137,7 @@ Score: 56
// main
main: {
// asm
// asm { sxy st0#$55 st1#$aa sax st2#$be say tma#2 bsr!+ tam#4 csl cla clx cly csh set !: rts }
// asm { sxy st0#$55 st1#$aa sax st2#$be say tma#2 bsr!+ tam#4 csl cla clx cly csh set tst#1+2,$3+4 tst#1+2*3,$7654/2 !: rts }
sxy
st0 #$55
st1 #$aa
@@ -151,6 +153,8 @@ main: {
cly
csh
set
tst #1+2,3+4
tst #1+2*3,$7654/2
!:
rts
// main::@return
+45
View File
@@ -0,0 +1,45 @@
/// @file
/// Functions for performing input and output.
// Commodore 64 PRG executable file
.file [name="ducks-array.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.segment Code
main: {
// chrout(149)
lda #$95
sta.z chrout.petscii
jsr chrout
// chrout(points[0])
lda points
sta.z chrout.petscii
jsr chrout
// chrout(points[1])
lda points+1
sta.z chrout.petscii
jsr chrout
// chrout(points[2])
lda points+2
sta.z chrout.petscii
jsr chrout
// chrout(points[3])
lda points+3
sta.z chrout.petscii
jsr chrout
// }
rts
}
// void chrout(__zp(2) volatile char petscii)
chrout: {
.label petscii = 2
// asm
jsr $ffd2
// }
rts
}
.segment Data
points: .byte 1, 2, 3, 4
+33
View File
@@ -0,0 +1,33 @@
void main()
main: scope:[main] from
[0] chrout::petscii = $95
[1] call chrout
to:main::@1
main::@1: scope:[main] from main
[2] chrout::petscii = *points
[3] call chrout
to:main::@2
main::@2: scope:[main] from main::@1
[4] chrout::petscii = *(points+1)
[5] call chrout
to:main::@3
main::@3: scope:[main] from main::@2
[6] chrout::petscii = *(points+2)
[7] call chrout
to:main::@4
main::@4: scope:[main] from main::@3
[8] chrout::petscii = *(points+3)
[9] call chrout
to:main::@return
main::@return: scope:[main] from main::@4
[10] return
to:@return
void chrout(volatile char petscii)
chrout: scope:[chrout] from main main::@1 main::@2 main::@3 main::@4
asm { jsr$ffd2 }
to:chrout::@return
chrout::@return: scope:[chrout] from chrout
[12] return
to:@return
+521
View File
@@ -0,0 +1,521 @@
Fixing struct type size struct printf_buffer_number to 12
Fixing struct type size struct printf_buffer_number to 12
Fixing struct type size struct printf_buffer_number to 12
Fixing struct type SIZE_OF struct printf_buffer_number to 12
Fixing struct type SIZE_OF struct printf_buffer_number to 12
Inlined call vicSelectGfxBank::$0 = call toDd00(vicSelectGfxBank::gfx)
Inlined call call __init
Eliminating unused variable with no statement gotoxy::$4
Eliminating unused variable with no statement printf_buffer
CONTROL FLOW GRAPH SSA
void gotoxy(char x , char y)
gotoxy: scope:[gotoxy] from conio_c64_init::@1
gotoxy::x#3 = phi( conio_c64_init::@1/gotoxy::x#1 )
gotoxy::y#2 = phi( conio_c64_init::@1/gotoxy::y#1 )
gotoxy::$0 = gotoxy::y#2 > $19
gotoxy::$1 = ! gotoxy::$0
if(gotoxy::$1) goto gotoxy::@1
to:gotoxy::@2
gotoxy::@1: scope:[gotoxy] from gotoxy gotoxy::@2
gotoxy::x#2 = phi( gotoxy/gotoxy::x#3, gotoxy::@2/gotoxy::x#4 )
gotoxy::$2 = gotoxy::x#2 >= $28
gotoxy::$3 = ! gotoxy::$2
if(gotoxy::$3) goto gotoxy::@return
to:gotoxy::@3
gotoxy::@2: scope:[gotoxy] from gotoxy
gotoxy::x#4 = phi( gotoxy/gotoxy::x#3 )
gotoxy::y#0 = 0
to:gotoxy::@1
gotoxy::@3: scope:[gotoxy] from gotoxy::@1
gotoxy::x#0 = 0
to:gotoxy::@return
gotoxy::@return: scope:[gotoxy] from gotoxy::@1 gotoxy::@3
return
to:@return
void conio_c64_init()
conio_c64_init: scope:[conio_c64_init] from __start::__init1
conio_c64_init::line#0 = *conio_c64_init::BASIC_CURSOR_LINE
conio_c64_init::$0 = conio_c64_init::line#0 >= $19
conio_c64_init::$1 = ! conio_c64_init::$0
if(conio_c64_init::$1) goto conio_c64_init::@1
to:conio_c64_init::@2
conio_c64_init::@1: scope:[conio_c64_init] from conio_c64_init conio_c64_init::@2
conio_c64_init::line#2 = phi( conio_c64_init/conio_c64_init::line#0, conio_c64_init::@2/conio_c64_init::line#1 )
gotoxy::x#1 = 0
gotoxy::y#1 = conio_c64_init::line#2
call gotoxy
to:conio_c64_init::@3
conio_c64_init::@3: scope:[conio_c64_init] from conio_c64_init::@1
to:conio_c64_init::@return
conio_c64_init::@2: scope:[conio_c64_init] from conio_c64_init
conio_c64_init::line#1 = $19-1
to:conio_c64_init::@1
conio_c64_init::@return: scope:[conio_c64_init] from conio_c64_init::@3
return
to:@return
void chrout(volatile char petscii)
chrout: scope:[chrout] from main main::@1 main::@2 main::@3 main::@4
asm { jsr$ffd2 }
to:chrout::@return
chrout::@return: scope:[chrout] from chrout
return
to:@return
void main()
main: scope:[main] from __start::@1
chrout::petscii = $95
call chrout
to:main::@1
main::@1: scope:[main] from main
chrout::petscii = points[0]
call chrout
to:main::@2
main::@2: scope:[main] from main::@1
chrout::petscii = points[1]
call chrout
to:main::@3
main::@3: scope:[main] from main::@2
chrout::petscii = points[2]
call chrout
to:main::@4
main::@4: scope:[main] from main::@3
chrout::petscii = points[3]
call chrout
to:main::@5
main::@5: scope:[main] from main::@4
to:main::@return
main::@return: scope:[main] from main::@5
return
to:@return
void __start()
__start: scope:[__start] from
to:__start::__init1
__start::__init1: scope:[__start] from __start
call conio_c64_init
to:__start::@2
__start::@2: scope:[__start] from __start::__init1
to:__start::@1
__start::@1: scope:[__start] from __start::@2
call main
to:__start::@3
__start::@3: scope:[__start] from __start::@1
to:__start::@return
__start::@return: scope:[__start] from __start::@3
return
to:@return
SYMBOL TABLE SSA
__constant char RADIX::BINARY = 2
__constant char RADIX::DECIMAL = $a
__constant char RADIX::HEXADECIMAL = $10
__constant char RADIX::OCTAL = 8
void __start()
void chrout(volatile char petscii)
__loadstore volatile char chrout::petscii
void conio_c64_init()
bool conio_c64_init::$0
bool conio_c64_init::$1
__constant char * const conio_c64_init::BASIC_CURSOR_LINE = (char *)$d6
char conio_c64_init::line
char conio_c64_init::line#0
char conio_c64_init::line#1
char conio_c64_init::line#2
void gotoxy(char x , char y)
bool gotoxy::$0
bool gotoxy::$1
bool gotoxy::$2
bool gotoxy::$3
char gotoxy::x
char gotoxy::x#0
char gotoxy::x#1
char gotoxy::x#2
char gotoxy::x#3
char gotoxy::x#4
char gotoxy::y
char gotoxy::y#0
char gotoxy::y#1
char gotoxy::y#2
void main()
__constant char points[] = { 1, 2, 3, 4 }
Adding number conversion cast (unumber) $19 in gotoxy::$0 = gotoxy::y#2 > $19
Adding number conversion cast (unumber) $28 in gotoxy::$2 = gotoxy::x#2 >= $28
Adding number conversion cast (unumber) 0 in gotoxy::y#0 = 0
Adding number conversion cast (unumber) 0 in gotoxy::x#0 = 0
Adding number conversion cast (unumber) $19 in conio_c64_init::$0 = conio_c64_init::line#0 >= $19
Adding number conversion cast (unumber) 0 in gotoxy::x#1 = 0
Adding number conversion cast (unumber) $19-1 in conio_c64_init::line#1 = $19-1
Adding number conversion cast (unumber) $95 in chrout::petscii = $95
Adding number conversion cast (unumber) 0 in chrout::petscii = points[0]
Adding number conversion cast (unumber) 1 in chrout::petscii = points[1]
Adding number conversion cast (unumber) 2 in chrout::petscii = points[2]
Adding number conversion cast (unumber) 3 in chrout::petscii = points[3]
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast gotoxy::y#0 = (unumber)0
Inlining cast gotoxy::x#0 = (unumber)0
Inlining cast gotoxy::x#1 = (unumber)0
Inlining cast conio_c64_init::line#1 = (unumber)$19-1
Inlining cast chrout::petscii = (unumber)$95
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 214
Simplifying constant integer cast $19
Simplifying constant integer cast $28
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Simplifying constant integer cast $19
Simplifying constant integer cast 0
Simplifying constant integer cast $95
Simplifying constant integer cast 0
Simplifying constant integer cast 1
Simplifying constant integer cast 2
Simplifying constant integer cast 3
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) $19
Finalized unsigned number type (char) $28
Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 0
Finalized unsigned number type (char) $19
Finalized unsigned number type (char) 0
Finalized unsigned number type (char) $95
Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 1
Finalized unsigned number type (char) 2
Finalized unsigned number type (char) 3
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inversing boolean not [2] gotoxy::$1 = gotoxy::y#2 <= $19 from [1] gotoxy::$0 = gotoxy::y#2 > $19
Inversing boolean not [6] gotoxy::$3 = gotoxy::x#2 < $28 from [5] gotoxy::$2 = gotoxy::x#2 >= $28
Inversing boolean not [14] conio_c64_init::$1 = conio_c64_init::line#0 < $19 from [13] conio_c64_init::$0 = conio_c64_init::line#0 >= $19
Successful SSA optimization Pass2UnaryNotSimplification
Alias gotoxy::x#3 = gotoxy::x#4
Successful SSA optimization Pass2AliasElimination
Alias gotoxy::x#2 = gotoxy::x#3
Successful SSA optimization Pass2AliasElimination
Identical Phi Values gotoxy::y#2 gotoxy::y#1
Identical Phi Values gotoxy::x#2 gotoxy::x#1
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition gotoxy::$1 [2] if(gotoxy::y#1<=$19) goto gotoxy::@1
Simple Condition gotoxy::$3 [4] if(gotoxy::x#1<$28) goto gotoxy::@return
Simple Condition conio_c64_init::$1 [10] if(conio_c64_init::line#0<$19) goto conio_c64_init::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant right-side identified [15] conio_c64_init::line#1 = (unumber)$19-1
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant gotoxy::y#0 = 0
Constant gotoxy::x#0 = 0
Constant gotoxy::x#1 = 0
Constant conio_c64_init::line#1 = (unumber)$19-1
Successful SSA optimization Pass2ConstantIdentification
if() condition always true - replacing block destination [4] if(gotoxy::x#1<$28) goto gotoxy::@return
Successful SSA optimization Pass2ConstantIfs
Rewriting conditional comparison [2] if(gotoxy::y#1<=$19) goto gotoxy::@1
Simplifying expression containing zero points in [21] chrout::petscii = points[0]
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing call to empty/unused procedure [30] call conio_c64_init
Successful SSA optimization PassNEliminateUnusedConstructors
Eliminating variable conio_c64_init::line#0 from unused block conio_c64_init
Eliminating variable conio_c64_init::line#2 from unused block conio_c64_init::@1
Eliminating variable gotoxy::y#1 from unused block conio_c64_init::@1
Removing unused procedure gotoxy
Removing unused procedure block gotoxy
Removing unused procedure block gotoxy::@1
Removing unused procedure block gotoxy::@2
Removing unused procedure block gotoxy::@3
Removing unused procedure block gotoxy::@return
Removing unused procedure conio_c64_init
Removing unused procedure block conio_c64_init
Removing PHI-reference to removed block (conio_c64_init) in block conio_c64_init::@1
Removing unused procedure block conio_c64_init::@1
Removing unused procedure block conio_c64_init::@3
Removing unused procedure block conio_c64_init::@2
Removing unused procedure block conio_c64_init::@return
Successful SSA optimization Pass2EliminateUnusedBlocks
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::__init1
Removing unused procedure block __start::@2
Removing unused procedure block __start::@1
Removing unused procedure block __start::@3
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Consolidated array index constant in *(points+1)
Consolidated array index constant in *(points+2)
Consolidated array index constant in *(points+3)
Successful SSA optimization Pass2ConstantAdditionElimination
Finalized unsigned number type (char) 2
Finalized unsigned number type (char) 8
Finalized unsigned number type (char) $a
Finalized unsigned number type (char) $10
Finalized unsigned number type (char) $b
Finalized unsigned number type (char) $b
Successful SSA optimization PassNFinalizeNumberTypeConversions
Adding NOP phi() at start of main::@5
CALL GRAPH
Calls in [main] to chrout:1 chrout:3 chrout:5 chrout:7 chrout:9
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block label main::@5
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] chrout::petscii = $95
[1] call chrout
to:main::@1
main::@1: scope:[main] from main
[2] chrout::petscii = *points
[3] call chrout
to:main::@2
main::@2: scope:[main] from main::@1
[4] chrout::petscii = *(points+1)
[5] call chrout
to:main::@3
main::@3: scope:[main] from main::@2
[6] chrout::petscii = *(points+2)
[7] call chrout
to:main::@4
main::@4: scope:[main] from main::@3
[8] chrout::petscii = *(points+3)
[9] call chrout
to:main::@return
main::@return: scope:[main] from main::@4
[10] return
to:@return
void chrout(volatile char petscii)
chrout: scope:[chrout] from main main::@1 main::@2 main::@3 main::@4
asm { jsr$ffd2 }
to:chrout::@return
chrout::@return: scope:[chrout] from chrout
[12] return
to:@return
VARIABLE REGISTER WEIGHTS
void chrout(volatile char petscii)
__loadstore volatile char chrout::petscii // 100.0
void main()
Initial phi equivalence classes
Added variable chrout::petscii to live range equivalence class [ chrout::petscii ]
Complete equivalence classes
[ chrout::petscii ]
Allocated zp[1]:2 [ chrout::petscii ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] chrout::petscii = $95 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [2] chrout::petscii = *points [ ] ( [ ] { } ) always clobbers reg byte a
Statement [4] chrout::petscii = *(points+1) [ ] ( [ ] { } ) always clobbers reg byte a
Statement [6] chrout::petscii = *(points+2) [ ] ( [ ] { } ) always clobbers reg byte a
Statement [8] chrout::petscii = *(points+3) [ ] ( [ ] { } ) always clobbers reg byte a
Statement asm { jsr$ffd2 } always clobbers reg byte a reg byte x reg byte y
Potential registers zp[1]:2 [ chrout::petscii ] : zp[1]:2 ,
REGISTER UPLIFT SCOPES
Uplift Scope [chrout] 100: zp[1]:2 [ chrout::petscii ]
Uplift Scope [RADIX]
Uplift Scope [MOS6526_CIA]
Uplift Scope [MOS6569_VICII]
Uplift Scope [MOS6581_SID]
Uplift Scope [printf_format_number]
Uplift Scope [printf_buffer_number]
Uplift Scope [printf_format_string]
Uplift Scope [main]
Uplift Scope []
Uplifting [chrout] best 99 combination zp[1]:2 [ chrout::petscii ]
Uplifting [RADIX] best 99 combination
Uplifting [MOS6526_CIA] best 99 combination
Uplifting [MOS6569_VICII] best 99 combination
Uplifting [MOS6581_SID] best 99 combination
Uplifting [printf_format_number] best 99 combination
Uplifting [printf_buffer_number] best 99 combination
Uplifting [printf_format_string] best 99 combination
Uplifting [main] best 99 combination
Uplifting [] best 99 combination
Attempting to uplift remaining variables inzp[1]:2 [ chrout::petscii ]
Uplifting [chrout] best 99 combination zp[1]:2 [ chrout::petscii ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
/// @file
/// Functions for performing input and output.
// Upstart
// Commodore 64 PRG executable file
.file [name="ducks-array.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.segment Code
// main
main: {
// [0] chrout::petscii = $95 -- vbuz1=vbuc1
lda #$95
sta.z chrout.petscii
// [1] call chrout
jsr chrout
jmp __b1
// main::@1
__b1:
// [2] chrout::petscii = *points -- vbuz1=_deref_pbuc1
lda points
sta.z chrout.petscii
// [3] call chrout
jsr chrout
jmp __b2
// main::@2
__b2:
// [4] chrout::petscii = *(points+1) -- vbuz1=_deref_pbuc1
lda points+1
sta.z chrout.petscii
// [5] call chrout
jsr chrout
jmp __b3
// main::@3
__b3:
// [6] chrout::petscii = *(points+2) -- vbuz1=_deref_pbuc1
lda points+2
sta.z chrout.petscii
// [7] call chrout
jsr chrout
jmp __b4
// main::@4
__b4:
// [8] chrout::petscii = *(points+3) -- vbuz1=_deref_pbuc1
lda points+3
sta.z chrout.petscii
// [9] call chrout
jsr chrout
jmp __breturn
// main::@return
__breturn:
// [10] return
rts
}
// chrout
// void chrout(__zp(2) volatile char petscii)
chrout: {
.label petscii = 2
// asm { jsr$ffd2 }
jsr $ffd2
jmp __breturn
// chrout::@return
__breturn:
// [12] return
rts
}
// File Data
.segment Data
points: .byte 1, 2, 3, 4
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __b3
Removing instruction jmp __b4
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __b1:
Removing instruction __b2:
Removing instruction __b3:
Removing instruction __b4:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
__constant char RADIX::BINARY = 2
__constant char RADIX::DECIMAL = $a
__constant char RADIX::HEXADECIMAL = $10
__constant char RADIX::OCTAL = 8
void chrout(volatile char petscii)
__loadstore volatile char chrout::petscii // zp[1]:2 100.0
void main()
__constant char points[] = { 1, 2, 3, 4 }
zp[1]:2 [ chrout::petscii ]
FINAL ASSEMBLER
Score: 81
// File Comments
/// @file
/// Functions for performing input and output.
// Upstart
// Commodore 64 PRG executable file
.file [name="ducks-array.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.segment Code
// main
main: {
// chrout(149)
// [0] chrout::petscii = $95 -- vbuz1=vbuc1
lda #$95
sta.z chrout.petscii
// [1] call chrout
jsr chrout
// main::@1
// chrout(points[0])
// [2] chrout::petscii = *points -- vbuz1=_deref_pbuc1
lda points
sta.z chrout.petscii
// [3] call chrout
jsr chrout
// main::@2
// chrout(points[1])
// [4] chrout::petscii = *(points+1) -- vbuz1=_deref_pbuc1
lda points+1
sta.z chrout.petscii
// [5] call chrout
jsr chrout
// main::@3
// chrout(points[2])
// [6] chrout::petscii = *(points+2) -- vbuz1=_deref_pbuc1
lda points+2
sta.z chrout.petscii
// [7] call chrout
jsr chrout
// main::@4
// chrout(points[3])
// [8] chrout::petscii = *(points+3) -- vbuz1=_deref_pbuc1
lda points+3
sta.z chrout.petscii
// [9] call chrout
jsr chrout
// main::@return
// }
// [10] return
rts
}
// chrout
// void chrout(__zp(2) volatile char petscii)
chrout: {
.label petscii = 2
// asm
// asm { jsr$ffd2 }
jsr $ffd2
// chrout::@return
// }
// [12] return
rts
}
// File Data
.segment Data
points: .byte 1, 2, 3, 4
+10
View File
@@ -0,0 +1,10 @@
__constant char RADIX::BINARY = 2
__constant char RADIX::DECIMAL = $a
__constant char RADIX::HEXADECIMAL = $10
__constant char RADIX::OCTAL = 8
void chrout(volatile char petscii)
__loadstore volatile char chrout::petscii // zp[1]:2 100.0
void main()
__constant char points[] = { 1, 2, 3, 4 }
zp[1]:2 [ chrout::petscii ]
+46
View File
@@ -0,0 +1,46 @@
/// @file
/// PEEK and POKE macros for those who want to write BASIC code in C
///
/// Based on https://github.com/cc65/cc65/blob/master/include/peekpoke.h
// Commodore 64 PRG executable file
.file [name="ducks-loop211.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.const brick = $e6
.segment Code
main: {
.label k = 2
lda #1
sta.z k
__b1:
// POKE
lda.z k
asl
asl
sta.z $d3
// chrout(brick)
lda #brick
sta.z chrout.petscii
jsr chrout
// ++k;
inc.z k
// while (k<5)
lda.z k
cmp #5
bcc __b1
// }
rts
}
// void chrout(__zp(3) volatile char petscii)
chrout: {
.label petscii = 3
// asm
lda petscii
jsr $ffd2
// }
rts
}
+27
View File
@@ -0,0 +1,27 @@
void main()
main: scope:[main] from
[0] phi()
to:main::@1
main::@1: scope:[main] from main main::@2
[1] main::k#2 = phi( main/1, main::@2/main::k#1 )
[2] main::$0 = main::k#2 << 2
[3] *((char *) 211) = main::$0
[4] chrout::petscii = brick
[5] call chrout
to:main::@2
main::@2: scope:[main] from main::@1
[6] main::k#1 = ++ main::k#2
[7] if(main::k#1<5) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@2
[8] return
to:@return
void chrout(volatile char petscii)
chrout: scope:[chrout] from main::@1
asm { ldapetscii jsr$ffd2 }
to:chrout::@return
chrout::@return: scope:[chrout] from chrout
[10] return
to:@return
+353
View File
@@ -0,0 +1,353 @@
CONTROL FLOW GRAPH SSA
void chrout(volatile char petscii)
chrout: scope:[chrout] from main::@1
asm { ldapetscii jsr$ffd2 }
to:chrout::@return
chrout::@return: scope:[chrout] from chrout
return
to:@return
void main()
main: scope:[main] from __start
main::k#0 = 1
to:main::@1
main::@1: scope:[main] from main main::@2
main::k#2 = phi( main/main::k#0, main::@2/main::k#1 )
main::$0 = main::k#2 * 4
*((char *)$d3) = main::$0
chrout::petscii = brick
call chrout
to:main::@2
main::@2: scope:[main] from main::@1
main::k#3 = phi( main::@1/main::k#2 )
main::k#1 = ++ main::k#3
main::$2 = main::k#1 < 5
if(main::$2) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@2
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
void __start()
__constant const char brick = $e6
void chrout(volatile char petscii)
__loadstore volatile char chrout::petscii
void main()
number main::$0
bool main::$2
char main::k
char main::k#0
char main::k#1
char main::k#2
char main::k#3
Adding number conversion cast (unumber) 4 in main::$0 = main::k#2 * 4
Adding number conversion cast (unumber) main::$0 in main::$0 = main::k#2 * (unumber)4
Adding number conversion cast (unumber) 5 in main::$2 = main::k#1 < 5
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast 4
Simplifying constant pointer cast (char *) 211
Simplifying constant integer cast 5
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 4
Finalized unsigned number type (char) 5
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inferred type updated to char in main::$0 = main::k#2 * 4
Alias main::k#2 = main::k#3
Successful SSA optimization Pass2AliasElimination
Simple Condition main::$2 [10] if(main::k#1<5) goto main::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant main::k#0 = 1
Successful SSA optimization Pass2ConstantIdentification
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Rewriting multiplication to use shift [3] main::$0 = main::k#2 * 4
Successful SSA optimization Pass2MultiplyToShiftRewriting
Inlining constant with var siblings main::k#0
Constant inlined main::k#0 = 1
Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting main::@3(between main::@2 and main::@1)
Adding NOP phi() at start of main
CALL GRAPH
Calls in [main] to chrout:5
Created 1 initial phi equivalence classes
Coalesced [9] main::k#4 = main::k#1
Coalesced down to 1 phi equivalence classes
Culled Empty Block label main::@3
Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
to:main::@1
main::@1: scope:[main] from main main::@2
[1] main::k#2 = phi( main/1, main::@2/main::k#1 )
[2] main::$0 = main::k#2 << 2
[3] *((char *) 211) = main::$0
[4] chrout::petscii = brick
[5] call chrout
to:main::@2
main::@2: scope:[main] from main::@1
[6] main::k#1 = ++ main::k#2
[7] if(main::k#1<5) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@2
[8] return
to:@return
void chrout(volatile char petscii)
chrout: scope:[chrout] from main::@1
asm { ldapetscii jsr$ffd2 }
to:chrout::@return
chrout::@return: scope:[chrout] from chrout
[10] return
to:@return
VARIABLE REGISTER WEIGHTS
void chrout(volatile char petscii)
__loadstore volatile char chrout::petscii // 11.0
void main()
char main::$0 // 22.0
char main::k
char main::k#1 // 16.5
char main::k#2 // 6.6000000000000005
Initial phi equivalence classes
[ main::k#2 main::k#1 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable chrout::petscii to live range equivalence class [ chrout::petscii ]
Complete equivalence classes
[ main::k#2 main::k#1 ]
[ main::$0 ]
[ chrout::petscii ]
Allocated zp[1]:2 [ main::k#2 main::k#1 ]
Allocated zp[1]:3 [ main::$0 ]
Allocated zp[1]:4 [ chrout::petscii ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [2] main::$0 = main::k#2 << 2 [ main::k#2 main::$0 ] ( [ main::k#2 main::$0 ] { } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::k#2 main::k#1 ]
Statement [4] chrout::petscii = brick [ main::k#2 chrout::petscii ] ( [ main::k#2 chrout::petscii ] { } ) always clobbers reg byte a
Statement asm { ldapetscii jsr$ffd2 } always clobbers reg byte a reg byte x reg byte y
Removing always clobbered register reg byte x as potential for zp[1]:2 [ main::k#2 main::k#1 ]
Removing always clobbered register reg byte y as potential for zp[1]:2 [ main::k#2 main::k#1 ]
Statement [2] main::$0 = main::k#2 << 2 [ main::k#2 main::$0 ] ( [ main::k#2 main::$0 ] { } ) always clobbers reg byte a
Statement [4] chrout::petscii = brick [ main::k#2 chrout::petscii ] ( [ main::k#2 chrout::petscii ] { } ) always clobbers reg byte a
Statement [7] if(main::k#1<5) goto main::@1 [ main::k#1 ] ( [ main::k#1 ] { } ) always clobbers reg byte a
Statement asm { ldapetscii jsr$ffd2 } always clobbers reg byte a reg byte x reg byte y
Potential registers zp[1]:2 [ main::k#2 main::k#1 ] : zp[1]:2 ,
Potential registers zp[1]:3 [ main::$0 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ chrout::petscii ] : zp[1]:4 ,
REGISTER UPLIFT SCOPES
Uplift Scope [main] 23.1: zp[1]:2 [ main::k#2 main::k#1 ] 22: zp[1]:3 [ main::$0 ]
Uplift Scope [chrout] 11: zp[1]:4 [ chrout::petscii ]
Uplift Scope []
Uplifting [main] best 530 combination zp[1]:2 [ main::k#2 main::k#1 ] reg byte a [ main::$0 ]
Uplifting [chrout] best 530 combination zp[1]:4 [ chrout::petscii ]
Uplifting [] best 530 combination
Attempting to uplift remaining variables inzp[1]:2 [ main::k#2 main::k#1 ]
Uplifting [main] best 530 combination zp[1]:2 [ main::k#2 main::k#1 ]
Attempting to uplift remaining variables inzp[1]:4 [ chrout::petscii ]
Uplifting [chrout] best 530 combination zp[1]:4 [ chrout::petscii ]
Allocated (was zp[1]:4) zp[1]:3 [ chrout::petscii ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
/// @file
/// PEEK and POKE macros for those who want to write BASIC code in C
///
/// Based on https://github.com/cc65/cc65/blob/master/include/peekpoke.h
// Upstart
// Commodore 64 PRG executable file
.file [name="ducks-loop211.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const brick = $e6
.segment Code
// main
main: {
.label k = 2
// [1] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
// [1] phi main::k#2 = 1 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #1
sta.z k
jmp __b1
// [1] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
__b1_from___b2:
// [1] phi main::k#2 = main::k#1 [phi:main::@2->main::@1#0] -- register_copy
jmp __b1
// main::@1
__b1:
// [2] main::$0 = main::k#2 << 2 -- vbuaa=vbuz1_rol_2
lda.z k
asl
asl
// [3] *((char *) 211) = main::$0 -- _deref_pbuc1=vbuaa
sta.z $d3
// [4] chrout::petscii = brick -- vbuz1=vbuc1
lda #brick
sta.z chrout.petscii
// [5] call chrout
jsr chrout
jmp __b2
// main::@2
__b2:
// [6] main::k#1 = ++ main::k#2 -- vbuz1=_inc_vbuz1
inc.z k
// [7] if(main::k#1<5) goto main::@1 -- vbuz1_lt_vbuc1_then_la1
lda.z k
cmp #5
bcc __b1_from___b2
jmp __breturn
// main::@return
__breturn:
// [8] return
rts
}
// chrout
// void chrout(__zp(3) volatile char petscii)
chrout: {
.label petscii = 3
// asm { ldapetscii jsr$ffd2 }
lda petscii
jsr $ffd2
jmp __breturn
// chrout::@return
__breturn:
// [10] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label __b1_from___b2 with __b1
Removing instruction __b1_from___b2:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1_from_main:
Removing instruction __b2:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Removing instruction jmp __b1
Succesful ASM optimization Pass5NextJumpElimination
FINAL SYMBOL TABLE
__constant const char brick = $e6
void chrout(volatile char petscii)
__loadstore volatile char chrout::petscii // zp[1]:3 11.0
void main()
char main::$0 // reg byte a 22.0
char main::k
char main::k#1 // k zp[1]:2 16.5
char main::k#2 // k zp[1]:2 6.6000000000000005
zp[1]:2 [ main::k#2 main::k#1 ]
reg byte a [ main::$0 ]
zp[1]:3 [ chrout::petscii ]
FINAL ASSEMBLER
Score: 407
// File Comments
/// @file
/// PEEK and POKE macros for those who want to write BASIC code in C
///
/// Based on https://github.com/cc65/cc65/blob/master/include/peekpoke.h
// Upstart
// Commodore 64 PRG executable file
.file [name="ducks-loop211.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const brick = $e6
.segment Code
// main
main: {
.label k = 2
// [1] phi from main to main::@1 [phi:main->main::@1]
// [1] phi main::k#2 = 1 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #1
sta.z k
// [1] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
// [1] phi main::k#2 = main::k#1 [phi:main::@2->main::@1#0] -- register_copy
// main::@1
__b1:
// POKE
// [2] main::$0 = main::k#2 << 2 -- vbuaa=vbuz1_rol_2
lda.z k
asl
asl
// [3] *((char *) 211) = main::$0 -- _deref_pbuc1=vbuaa
sta.z $d3
// chrout(brick)
// [4] chrout::petscii = brick -- vbuz1=vbuc1
lda #brick
sta.z chrout.petscii
// [5] call chrout
jsr chrout
// main::@2
// ++k;
// [6] main::k#1 = ++ main::k#2 -- vbuz1=_inc_vbuz1
inc.z k
// while (k<5)
// [7] if(main::k#1<5) goto main::@1 -- vbuz1_lt_vbuc1_then_la1
lda.z k
cmp #5
bcc __b1
// main::@return
// }
// [8] return
rts
}
// chrout
// void chrout(__zp(3) volatile char petscii)
chrout: {
.label petscii = 3
// asm
// asm { ldapetscii jsr$ffd2 }
lda petscii
jsr $ffd2
// chrout::@return
// }
// [10] return
rts
}
// File Data
+12
View File
@@ -0,0 +1,12 @@
__constant const char brick = $e6
void chrout(volatile char petscii)
__loadstore volatile char chrout::petscii // zp[1]:3 11.0
void main()
char main::$0 // reg byte a 22.0
char main::k
char main::k#1 // k zp[1]:2 16.5
char main::k#2 // k zp[1]:2 6.6000000000000005
zp[1]:2 [ main::k#2 main::k#1 ]
reg byte a [ main::$0 ]
zp[1]:3 [ chrout::petscii ]
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+440
View File
@@ -0,0 +1,440 @@
__constant char * const COLORRAM = (char *) 55296
__constant char * const DEFAULT_SCREEN = (char *) 1024
__constant char DIGITS[] = "0123456789abcdef"z
__constant const char LIGHT_BLUE = $e
__constant char RADIX::BINARY = 2
__constant char RADIX::DECIMAL = $a
__constant char RADIX::HEXADECIMAL = $10
__constant char RADIX::OCTAL = 8
__constant unsigned int RADIX_DECIMAL_VALUES[] = { $2710, $3e8, $64, $a }
void __start()
__constant const char brick = $e6
__constant char buffer[] = { 0, 0, 0, 0 }
__constant const unsigned int c = $7800
__constant const char chrono[] = { $54, $4d, $3a, $39 }
void chrono_restart()
void chrout(volatile char petscii)
__loadstore volatile char chrout::petscii // zp[1]:24 3.0310104636363637E7
void clear_screen(char n , char m)
unsigned int clear_screen::$4 // zp[2]:35 100001.0
unsigned int clear_screen::$5 // zp[2]:9 66667.33333333333
char clear_screen::m
char clear_screen::n
char clear_screen::n#5 // n zp[1]:8 12500.125
void conio_c64_init()
__constant char * const conio_c64_init::BASIC_CURSOR_LINE = (char *) 214
char conio_c64_init::line
char conio_c64_init::line#0 // line zp[1]:76 11.0
char conio_c64_init::line#2 // line zp[1]:76 22.0
__loadstore char conio_cursor_x // zp[1]:39 200133.45333333334
__loadstore char conio_cursor_y // zp[1]:29 3516593.4945054944
__loadstore char *conio_line_color // zp[2]:30 2662771.1807228914
__loadstore char *conio_line_text // zp[2]:32 2600117.7411764706
__loadstore char conio_textcolor // zp[1]:34 1629048.4677419355
void cputc(char c)
char cputc::c
char cputc::c#0 // c zp[1]:2 1050001.5
void cputln()
void cputs(const char *s)
char cputs::c
char cputs::c#1 // c zp[1]:2 100001.0
const char *cputs::s
const char *cputs::s#0 // s zp[2]:5 50000.5
const char *cputs::s#10 // s zp[2]:5 150502.0
const char *cputs::s#11 // s zp[2]:5 1001.0
void cscroll()
unsigned int div16u8u(unsigned int dividend , char divisor)
unsigned int div16u8u::dividend
unsigned int div16u8u::dividend#0 // dividend zp[2]:35 420000.60000000003
char div16u8u::divisor
__constant char div16u8u::divisor#0 = $3c // divisor
unsigned int div16u8u::quotient
char div16u8u::quotient_hi
char div16u8u::quotient_hi#0 // quotient_hi zp[1]:2 333333.6666666667
char div16u8u::quotient_lo
char div16u8u::quotient_lo#0 // quotient_lo zp[1]:16 2000002.0
unsigned int div16u8u::return
unsigned int div16u8u::return#0 // return zp[2]:18 366667.3333333334
unsigned int div16u8u::return#2 // return_1 zp[2]:48 9166.833333333332
char divr8u(char dividend , char divisor , char rem)
char divr8u::$1 // zp[1]:17 2.00000000002E11
char divr8u::dividend
char divr8u::dividend#0 // dividend zp[1]:3 2.500000000025E10
char divr8u::dividend#1 // dividend zp[1]:3 2000002.0
char divr8u::dividend#2 // dividend zp[1]:3 1000001.0
char divr8u::dividend#3 // dividend zp[1]:3 5.0001666667333336E10
char divr8u::dividend#5 // dividend zp[1]:3 1.2000003E7
char divr8u::divisor
char divr8u::i
char divr8u::i#1 // i zp[1]:7 1.500000000015E11
char divr8u::i#2 // i zp[1]:7 1.6666666666833334E10
char divr8u::quotient
char divr8u::quotient#1 // quotient zp[1]:16 1.500000000015E11
char divr8u::quotient#2 // quotient zp[1]:16 1.00000000001E11
char divr8u::quotient#3 // quotient zp[1]:16 2.8571428571714287E10
char divr8u::rem
char divr8u::rem#0 // rem zp[1]:15 1.00000000001E11
char divr8u::rem#1 // rem zp[1]:15 2.00000000002E11
char divr8u::rem#10 // rem zp[1]:15 1.1000002E7
char divr8u::rem#11 // rem zp[1]:15 2.702711801846847E9
char divr8u::rem#2 // rem zp[1]:15 2.00000000002E11
char divr8u::rem#4 // rem zp[1]:15 2000002.0
char divr8u::rem#5 // rem zp[1]:15 2.00010000003E11
char divr8u::rem#6 // rem zp[1]:15 1.00000000001E11
char divr8u::return
char divr8u::return#0 // return zp[1]:16 5.000033333416667E10
char divr8u::return#2 // return zp[1]:16 2000002.0
char divr8u::return#3 // return zp[1]:16 2000002.0
__constant const char down = $11
unsigned int duck
unsigned int duck#0 // duck zp[2]:22 6.6666667333333336E7
unsigned int duck#1 // duck zp[2]:22 4237745.88135593
__constant const char duck_udg[] = { $e, $1b, $3f, $1f, $f, 7, $f, $1f, 0, 0, 0, 0, 0, $c0, $70, $bc, $1f, $1d, $1e, $f, 3, 1, 1, 3, $ce, $1e, $7c, $f8, $e0, $40, $40, $e0, 0, 0, 0, 0, 0, 0, 0, 0 }
__constant const char ducknumber[] = { $44, $55, $43, $4b, $3a }
__constant const char foot[] = "PRESS: 1,3,5,7 or 9
"
__constant const char game_over[] = "
GAME OVER"
void gotoxy(char x , char y)
char *gotoxy::$5 // zp[2]:72 20002.0
char *gotoxy::$6 // zp[2]:44 20002.0
unsigned int gotoxy::$7 // zp[2]:44 15001.5
unsigned int gotoxy::$8 // zp[2]:70 20002.0
unsigned int gotoxy::$9 // zp[2]:44 20002.0
unsigned int gotoxy::line_offset
unsigned int gotoxy::line_offset#0 // line_offset zp[2]:44 10001.0
char gotoxy::x
char gotoxy::y
char gotoxy::y#2 // y zp[1]:76 22.0
char gotoxy::y#4 // y zp[1]:76 6671.0
char gotoxy::y#5 // y zp[1]:76 6667.333333333333
__constant const char green = $1e
__constant const char high_score[] = "
Hi-Score: "
unsigned int hiscore
unsigned int hiscore#110 // hiscore_1 zp[2]:108 1.1744186046511627
unsigned int hiscore#123 // hiscore_1 zp[2]:108 202.0
unsigned int hiscore#124 // hiscore zp[2]:42 202.0
unsigned int hiscore#19 // hiscore zp[2]:42 31.076923076923077
__constant const char home = $13
__constant const char intro[] = "
DIFFICULTY
----------
"
char j
char j#11 // j zp[1]:50 7500.75
char j#13 // j_1 zp[1]:85 1001.0
char j#16 // j_2 zp[1]:86 1001.0
char j#19 // j_3 zp[1]:104 1034.6666666666667
char j#2 // j zp[1]:50 20002.0
char j#3 // j_1 zp[1]:85 2002.0
char j#5 // j_2 zp[1]:86 2002.0
char k
char k#1 // k zp[1]:99 2002.0
char k#101 // k zp[1]:99 273.0
__loadstore volatile char l // zp[1]:107 455.79148936170213
__constant const char levels[] = "1.EASIEST
3.EASY
5.MEDIUM
7.HARD
9.EXPERT
"
__constant const char lock = 8
__constant const char lower = $e
__loadstore volatile char m // zp[1]:4 3.8961039106499544E16
void main()
unsigned int main::$104 // zp[2]:93 2500.25
unsigned int main::$107 // zp[2]:95 2500.25
unsigned int main::$110 // zp[2]:97 2500.25
unsigned int main::$119 // zp[2]:74 6667.333333333333
unsigned int main::$120 // zp[2]:81 10001.0
unsigned int main::$122 // zp[2]:83 10001.0
unsigned int main::$124 // zp[2]:74 10001.0
unsigned int main::$125 // zp[2]:77 10001.0
unsigned int main::$127 // zp[2]:58 10001.0
unsigned int main::$128 // zp[2]:58 10001.0
unsigned int main::$130 // zp[2]:60 10001.0
unsigned int main::$131 // zp[2]:60 10001.0
unsigned int main::$133 // zp[2]:62 10001.0
unsigned int main::$134 // zp[2]:62 10001.0
unsigned int main::$136 // zp[2]:79 10001.0
unsigned int main::$138 // zp[2]:64 10001.0
unsigned int main::$139 // zp[2]:64 10001.0
unsigned int main::$141 // zp[2]:66 10001.0
unsigned int main::$142 // zp[2]:66 10001.0
unsigned int main::$144 // zp[2]:68 10001.0
unsigned int main::$145 // zp[2]:68 10001.0
unsigned int main::$150 // zp[2]:105 1001.0
unsigned int main::$151 // zp[2]:87 2002.0
unsigned int main::$152 // zp[2]:87 1001.0
unsigned int main::$153 // zp[2]:89 2002.0
unsigned int main::$154 // zp[2]:89 1001.0
unsigned int main::$155 // zp[2]:91 2002.0
unsigned int main::$156 // zp[2]:91 1001.0
char main::$177 // zp[1]:8 2002.0
unsigned int main::$179 // zp[2]:56 20002.0
unsigned int main::$180 // zp[2]:46 20002.0
char main::$26 // zp[1]:8 2002.0
unsigned int main::$29 // zp[2]:5 2002.0
unsigned int main::$3 // zp[2]:112 101.0
unsigned int main::$35 // zp[2]:102 2002.0
unsigned int main::$57 // zp[2]:100 2002.0
unsigned int main::$61 // zp[2]:13 2.00000002E8
unsigned int main::$66 // zp[2]:11 2.00000002E7
unsigned int main::$69 // zp[2]:25 2.00000002E7
unsigned int main::$72 // zp[2]:27 2.00000002E7
char main::$78 // zp[1]:16 20002.0
char main::$81 // zp[1]:7 20002.0
char main::$84 // zp[1]:3 20002.0
char main::$88 // zp[1]:54 20002.0
char main::$92 // zp[1]:55 20002.0
unsigned int main::$96 // zp[2]:46 15001.5
unsigned int main::$97 // zp[2]:46 20002.0
void * memcpy(void *destination , void *source , unsigned int num)
void *memcpy::destination
void *memcpy::destination#2 // destination zp[2]:11
char *memcpy::dst
char *memcpy::dst#1 // dst zp[2]:11 1.000000000001E12
char *memcpy::dst#2 // dst zp[2]:11 1.0003333333346667E12
char *memcpy::dst#4 // dst zp[2]:11 2.000000002E9
unsigned int memcpy::num
void *memcpy::return
void *memcpy::source
void *memcpy::source#2 // source zp[2]:13
char *memcpy::src
char *memcpy::src#1 // src zp[2]:13 2.000000000002E12
char *memcpy::src#2 // src zp[2]:13 1.00025000000125E12
char *memcpy::src#4 // src zp[2]:13 1.000000001E9
char *memcpy::src_end
char *memcpy::src_end#0 // src_end zp[2]:9 1.2512500000025E11
void * memset(void *str , char c , unsigned int num)
char memset::c
char memset::c#1 // c zp[1]:16 2.00000002E8
char memset::c#4 // c zp[1]:16 1.4287142857171426E11
char *memset::dst
char *memset::dst#1 // dst zp[2]:11 2.000000000002E12
char *memset::dst#2 // dst zp[2]:11 1.3336666666683335E12
char *memset::dst#4 // dst zp[2]:11 2.000000002E9
char *memset::end
char *memset::end#0 // end zp[2]:18 1.668333333336667E11
unsigned int memset::num
void *memset::return
void *memset::str
void *memset::str#3 // str zp[2]:11
char n
char n#1 // n zp[1]:51 20002.0
char n#101 // n zp[1]:51 4429.142857142857
char n#109 // n zp[1]:51 7.769230769230769
char n#14 // n zp[1]:51 344.8620689655172
char n#20 // n zp[1]:51 220.07272727272726
char n#52 // n zp[1]:51 93.84375
char n#89 // n zp[1]:51 35.644067796610166
unsigned int peephole
unsigned int peephole#12 // peephole zp[2]:52 617.7352941176471
unsigned int peephole#52 // peephole zp[2]:52 62.5625
__constant const char play_again[] = "
Play Again (Y/N)?"
__constant char points[] = { 0, 0, 0, 0 }
void random(char k , char n)
char random::$3 // zp[1]:2 5.5E17
char random::k
char random::k#0 // k zp[1]:3 500.5
char random::k#4 // k zp[1]:3 2.00000000000000192E17
char random::n
char random::n#0 // n zp[1]:8 2002.0
char random::n#4 // n zp[1]:8 2.00000000000002E16
void read_chrono()
unsigned int read_chrono::$0 // zp[2]:35 200002.0
unsigned int read_chrono::$5 // zp[2]:9 200002.0
__constant const char red = $1c
char rem8u
char rem8u#127 // rem8u zp[1]:15 11.6
char rem8u#25 // rem8u zp[1]:15 220.07272727272726
char rem8u#48 // rem8u zp[1]:15 93.84375
__constant const char reverse_on = $12
__constant const char right = $1d
unsigned int score
unsigned int score#13 // score zp[2]:42 70334.66666666666
unsigned int score#19 // score zp[2]:42 1272.9090909090908
unsigned int score#38 // score zp[2]:42 3843.0654205607475
unsigned int score#4 // score zp[2]:42 2002.0
unsigned int score#43 // score zp[2]:42 566.0943396226415
unsigned int score#6 // score zp[2]:42 20002.0
unsigned int score#8 // score zp[2]:42 10001.0
unsigned int score#81 // score zp[2]:42 15001.5
char textcolor(char color)
char textcolor::color
char textcolor::color#7 // color zp[1]:8 1001.0
char textcolor::old
char textcolor::return
unsigned int time
unsigned int time#11 // time zp[2]:48 20002.0
unsigned int time#17 // time zp[2]:48 566.0943396226415
unsigned int time#38 // time zp[2]:48 10001.0
unsigned int tu
unsigned int tu#1 // tu zp[2]:110 166.83333333333334
unsigned int tu#13 // tu zp[2]:110 32.032
void utoa(unsigned int value , char *buffer , char radix)
char utoa::$10 // zp[1]:17 2.0000000002E10
char utoa::$11 // zp[1]:2 2000002.0
char *utoa::buffer
char *utoa::buffer#10 // buffer zp[2]:13 2.857285714714286E9
char *utoa::buffer#15 // buffer zp[2]:13 1.50000000015E10
char *utoa::buffer#3 // buffer zp[2]:13 2000002.0
char *utoa::buffer#4 // buffer zp[2]:13 2.0000000002E10
char utoa::digit
char utoa::digit#1 // digit zp[1]:3 2.0000000002E10
char utoa::digit#2 // digit zp[1]:3 2.857142857428571E9
unsigned int utoa::digit_value
unsigned int utoa::digit_value#0 // digit_value zp[2]:9 6.0000000006E9
unsigned int *utoa::digit_values
char utoa::max_digits
char utoa::radix
char utoa::started
char utoa::started#2 // started zp[1]:16 5.0000000005E9
char utoa::started#4 // started zp[1]:16 1.0000000001E10
unsigned int utoa::value
unsigned int utoa::value#0 // value zp[2]:5 1.0000000001E10
unsigned int utoa::value#1 // value zp[2]:5 200002.0
unsigned int utoa::value#10 // value zp[2]:5 1100103.0
unsigned int utoa::value#2 // value zp[2]:5 202.0
unsigned int utoa::value#3 // value zp[2]:5 5.714428572142858E9
unsigned int utoa::value#7 // value zp[2]:5 1.50000000015E10
unsigned int utoa_append(char *buffer , unsigned int value , unsigned int sub)
char *utoa_append::buffer
char *utoa_append::buffer#0 // buffer zp[2]:13 1.375000000025E10
char utoa_append::digit
char utoa_append::digit#1 // digit zp[1]:7 1.0E16
char utoa_append::digit#2 // digit zp[1]:7 1.000005E16
unsigned int utoa_append::return
unsigned int utoa_append::return#0 // return zp[2]:5 2.0000000002E10
unsigned int utoa_append::sub
unsigned int utoa_append::sub#0 // sub zp[2]:9 3.333335E15
unsigned int utoa_append::value
unsigned int utoa_append::value#0 // value zp[2]:5 3.6666666667333336E10
unsigned int utoa_append::value#1 // value zp[2]:5 2.0E16
unsigned int utoa_append::value#2 // value zp[2]:5 5.000018333333334E15
void wait(char n)
char wait::n
char wait::n#6 // n zp[1]:3 1.25000000125E8
void write_score()
unsigned int y
unsigned int y#0 // y zp[2]:40 20002.0
unsigned int y#1 // y zp[2]:40 20002.0
unsigned int y#10 // y zp[2]:40 13334.666666666666
unsigned int y#11 // y zp[2]:40 13334.666666666666
unsigned int y#114 // y zp[2]:40 11.6
unsigned int y#12 // y zp[2]:40 13334.666666666666
unsigned int y#13 // y zp[2]:40 2285.9428571428575
unsigned int y#130 // y zp[2]:40 20002.0
unsigned int y#141 // y_1 zp[2]:52 20002.0
unsigned int y#18 // y zp[2]:40 509.61904761904765
unsigned int y#2 // y zp[2]:40 20002.0
unsigned int y#3 // y zp[2]:40 20002.0
unsigned int y#35 // y_1 zp[2]:52 2353.1764705882347
unsigned int y#49 // y zp[2]:40 93.84375
__constant const char yellow = $9e
__constant const char your_score[] = "
Your Score: "
unsigned int z
unsigned int z#1 // z zp[2]:37 200002.0
unsigned int z#100 // z_1 zp[2]:20 1050.15
unsigned int z#102 // z_1 zp[2]:20 93.84375
unsigned int z#128 // z_1 zp[2]:20 93.84375
unsigned int z#2 // z zp[2]:37 66667.33333333333
unsigned int z#23 // z_1 zp[2]:20 1.0333333334666666E10
unsigned int z#25 // z_1 zp[2]:20 2.564438476923077E7
unsigned int z#28 // z_1 zp[2]:20 266.93333333333334
unsigned int z#4 // z_1 zp[2]:20 2.0000000002E10
unsigned int z#48 // z_1 zp[2]:20 857.2285714285714
unsigned int z#53 // z_1 zp[2]:20 70503.0
unsigned int z#9 // z_1 zp[2]:20 2002.0
zp[1]:76 [ conio_c64_init::line#2 conio_c64_init::line#0 gotoxy::y#5 gotoxy::y#4 gotoxy::y#2 ]
zp[2]:108 [ hiscore#110 hiscore#123 ]
zp[1]:99 [ k#101 k#1 ]
zp[1]:85 [ j#13 j#3 ]
zp[1]:86 [ j#16 j#5 ]
zp[2]:110 [ tu#13 tu#1 ]
zp[2]:52 [ peephole#52 peephole#12 y#35 y#141 ]
zp[1]:51 [ n#52 n#89 n#109 n#20 n#101 n#14 n#1 ]
zp[2]:48 [ time#11 time#17 time#38 div16u8u::return#2 ]
zp[2]:40 [ y#13 y#12 y#11 y#10 y#0 y#49 y#114 y#18 y#130 y#1 y#2 y#3 ]
zp[2]:42 [ score#81 hiscore#19 hiscore#124 score#19 score#43 score#38 score#8 score#13 score#4 score#6 ]
zp[1]:50 [ j#11 j#2 ]
zp[2]:37 [ z#2 z#1 ]
zp[1]:8 [ random::n#4 random::n#0 main::$26 main::$177 textcolor::color#7 clear_screen::n#5 ]
zp[2]:20 [ z#53 z#48 z#100 z#102 z#128 z#28 z#9 z#25 z#23 z#4 ]
zp[1]:15 [ divr8u::rem#5 divr8u::rem#10 divr8u::rem#4 rem8u#48 rem8u#127 rem8u#25 divr8u::rem#11 divr8u::rem#6 divr8u::rem#0 divr8u::rem#1 divr8u::rem#2 ]
zp[1]:39 [ conio_cursor_x ]
zp[1]:29 [ conio_cursor_y ]
zp[2]:32 [ conio_line_text ]
zp[2]:30 [ conio_line_color ]
zp[1]:34 [ conio_textcolor ]
zp[1]:107 [ l ]
zp[1]:4 [ m ]
zp[1]:24 [ chrout::petscii ]
zp[2]:5 [ main::$29 utoa::value#3 utoa::value#7 utoa::value#10 utoa::value#2 utoa::value#1 utoa::value#0 utoa_append::value#2 utoa_append::value#0 utoa_append::value#1 utoa_append::return#0 cputs::s#10 cputs::s#11 cputs::s#0 ]
zp[2]:22 [ duck#0 duck#1 ]
zp[2]:13 [ main::$61 memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 utoa::buffer#10 utoa::buffer#15 utoa::buffer#4 utoa::buffer#3 utoa_append::buffer#0 ]
zp[2]:11 [ main::$66 memset::str#3 memset::dst#2 memset::dst#4 memset::dst#1 memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
zp[2]:25 [ main::$69 ]
zp[2]:27 [ main::$72 ]
zp[2]:105 [ main::$150 ]
zp[2]:87 [ main::$151 main::$152 ]
zp[2]:89 [ main::$153 main::$154 ]
zp[2]:91 [ main::$155 main::$156 ]
zp[1]:104 [ j#19 ]
zp[1]:16 [ main::$78 memset::c#4 memset::c#1 divr8u::quotient#3 divr8u::return#0 divr8u::quotient#1 divr8u::quotient#2 divr8u::return#2 divr8u::return#3 div16u8u::quotient_lo#0 utoa::started#2 utoa::started#4 ]
zp[1]:7 [ main::$81 divr8u::i#2 divr8u::i#1 utoa_append::digit#2 utoa_append::digit#1 ]
zp[1]:3 [ main::$84 divr8u::dividend#3 divr8u::dividend#5 divr8u::dividend#1 divr8u::dividend#2 divr8u::dividend#0 utoa::digit#2 utoa::digit#1 wait::n#6 random::k#4 random::k#0 ]
zp[1]:54 [ main::$88 ]
zp[1]:55 [ main::$92 ]
zp[2]:46 [ main::$96 main::$180 main::$97 ]
zp[2]:56 [ main::$179 ]
zp[2]:93 [ main::$104 ]
zp[2]:95 [ main::$107 ]
zp[2]:97 [ main::$110 ]
zp[2]:77 [ main::$125 ]
zp[2]:58 [ main::$127 main::$128 ]
zp[2]:60 [ main::$130 main::$131 ]
zp[2]:62 [ main::$133 main::$134 ]
zp[2]:79 [ main::$136 ]
zp[2]:64 [ main::$138 main::$139 ]
zp[2]:66 [ main::$141 main::$142 ]
zp[2]:68 [ main::$144 main::$145 ]
zp[2]:74 [ main::$119 main::$124 ]
zp[2]:81 [ main::$120 ]
zp[2]:83 [ main::$122 ]
zp[2]:100 [ main::$57 ]
zp[2]:102 [ main::$35 ]
zp[2]:112 [ main::$3 ]
zp[2]:44 [ gotoxy::$7 gotoxy::$9 gotoxy::line_offset#0 gotoxy::$6 ]
zp[2]:70 [ gotoxy::$8 ]
zp[2]:72 [ gotoxy::$5 ]
zp[2]:35 [ read_chrono::$0 div16u8u::dividend#0 clear_screen::$4 ]
zp[1]:2 [ div16u8u::quotient_hi#0 utoa::$11 random::$3 cputs::c#1 cputc::c#0 ]
zp[1]:17 [ divr8u::$1 utoa::$10 ]
zp[2]:9 [ memcpy::src_end#0 read_chrono::$5 utoa::digit_value#0 utoa_append::sub#0 clear_screen::$5 ]
zp[2]:18 [ memset::end#0 div16u8u::return#0 ]
+124
View File
@@ -0,0 +1,124 @@
// Commodore 64 PRG executable file
.file [name="pointer-swap.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.label screen = 2
.label tempbuffer = $c
.label newbuffer = $a
.label tempbuffer_1 = 6
.label newbuffer_1 = 8
.label oldbuffer = 4
.segment Code
main: {
// print()
lda #<buffer2
sta.z oldbuffer
lda #>buffer2
sta.z oldbuffer+1
lda #<buffer1
sta.z newbuffer_1
lda #>buffer1
sta.z newbuffer_1+1
lda #<$400
sta.z screen
lda #>$400
sta.z screen+1
lda #<0
sta.z tempbuffer_1
sta.z tempbuffer_1+1
jsr print
// swap()
lda #<buffer2
sta.z newbuffer
lda #>buffer2
sta.z newbuffer+1
lda #<buffer1
sta.z tempbuffer
lda #>buffer1
sta.z tempbuffer+1
jsr swap
lda.z newbuffer
sta.z tempbuffer
lda.z newbuffer+1
sta.z tempbuffer+1
lda.z tempbuffer
sta.z newbuffer
lda.z tempbuffer+1
sta.z newbuffer+1
// swap()
jsr swap
lda.z newbuffer
sta.z tempbuffer
lda.z newbuffer+1
sta.z tempbuffer+1
lda.z tempbuffer
sta.z newbuffer
lda.z tempbuffer+1
sta.z newbuffer+1
// swap()
jsr swap
// }
rts
}
print: {
// (char)tempbuffer&0x0f
lda.z tempbuffer_1
and #$f
// screen[0] = hextab[(char)tempbuffer&0x0f]
tay
lda hextab,y
ldy #0
sta (screen),y
// (char)newbuffer&0x0f
lda.z newbuffer_1
and #$f
// screen[2] = hextab[(char)newbuffer&0x0f]
tay
lda hextab,y
ldy #2
sta (screen),y
// (char)oldbuffer&0x0f
lda.z oldbuffer
and #$f
// screen[4] = hextab[(char)oldbuffer&0x0f]
tay
lda hextab,y
ldy #4
sta (screen),y
// screen += 40
lda #$28
clc
adc.z screen
sta.z screen
bcc !+
inc.z screen+1
!:
// }
rts
}
swap: {
lda.z tempbuffer
sta.z tempbuffer_1
lda.z tempbuffer+1
sta.z tempbuffer_1+1
lda.z newbuffer
sta.z newbuffer_1
lda.z newbuffer+1
sta.z newbuffer_1+1
lda.z tempbuffer
sta.z oldbuffer
lda.z tempbuffer+1
sta.z oldbuffer+1
// print()
jsr print
// }
rts
}
.segment Data
buffer1: .fill $a, 0
buffer2: .fill $a, 0
hextab: .text "0123456789abcdef"
+57
View File
@@ -0,0 +1,57 @@
void main()
main: scope:[main] from
[0] phi()
[1] call print
to:main::@1
main::@1: scope:[main] from main
[2] phi()
[3] call swap
to:main::@2
main::@2: scope:[main] from main::@1
[4] tempbuffer#22 = newbuffer#0
[5] newbuffer#23 = tempbuffer#0
[6] call swap
to:main::@3
main::@3: scope:[main] from main::@2
[7] tempbuffer#23 = newbuffer#0
[8] newbuffer#24 = tempbuffer#0
[9] call swap
to:main::@return
main::@return: scope:[main] from main::@3
[10] return
to:@return
void print()
print: scope:[print] from main swap
[11] oldbuffer#9 = phi( main/buffer2, swap/oldbuffer#22 )
[11] newbuffer#9 = phi( main/buffer1, swap/newbuffer#22 )
[11] screen#12 = phi( main/(char *) 1024, swap/screen#0 )
[11] tempbuffer#9 = phi( main/(char *) 0, swap/tempbuffer#21 )
[12] print::$3 = (char)tempbuffer#9
[13] print::$0 = print::$3 & $f
[14] *screen#12 = hextab[print::$0]
[15] print::$4 = (char)newbuffer#9
[16] print::$1 = print::$4 & $f
[17] screen#12[2] = hextab[print::$1]
[18] print::$5 = (char)oldbuffer#9
[19] print::$2 = print::$5 & $f
[20] screen#12[4] = hextab[print::$2]
[21] screen#0 = screen#12 + $28
to:print::@return
print::@return: scope:[print] from print
[22] return
to:@return
void swap()
swap: scope:[swap] from main::@1 main::@2 main::@3
[23] newbuffer#0 = phi( main::@1/buffer2, main::@2/newbuffer#23, main::@3/newbuffer#24 )
[23] tempbuffer#0 = phi( main::@1/buffer1, main::@2/tempbuffer#22, main::@3/tempbuffer#23 )
[24] tempbuffer#21 = tempbuffer#0
[25] newbuffer#22 = newbuffer#0
[26] oldbuffer#22 = tempbuffer#0
[27] call print
to:swap::@return
swap::@return: scope:[swap] from swap
[28] return
to:@return
File diff suppressed because it is too large Load Diff
+43
View File
@@ -0,0 +1,43 @@
__constant char buffer1[$a] = { fill( $a, 0) }
__constant char buffer2[$a] = { fill( $a, 0) }
__constant char hextab[] = "0123456789abcdef"z
void main()
char *newbuffer
char *newbuffer#0 // newbuffer zp[2]:10 2.375
char *newbuffer#22 // newbuffer_1 zp[2]:8 11.0
char *newbuffer#23 // newbuffer zp[2]:10 4.0
char *newbuffer#24 // newbuffer zp[2]:10 4.0
char *newbuffer#9 // newbuffer_1 zp[2]:8 2.75
char *oldbuffer
char *oldbuffer#22 // oldbuffer zp[2]:4 22.0
char *oldbuffer#9 // oldbuffer zp[2]:4 1.5714285714285714
void print()
char print::$0 // reg byte a 202.0
char print::$1 // reg byte a 202.0
char print::$2 // reg byte a 202.0
char print::$3 // reg byte a 202.0
char print::$4 // reg byte a 202.0
char print::$5 // reg byte a 202.0
char *screen
char *screen#0 // screen zp[2]:2 7.0
char *screen#12 // screen zp[2]:2 41.5
void swap()
char *tempbuffer
char *tempbuffer#0 // tempbuffer zp[2]:12 3.0
char *tempbuffer#21 // tempbuffer_1 zp[2]:6 7.333333333333333
char *tempbuffer#22 // tempbuffer zp[2]:12 2.0
char *tempbuffer#23 // tempbuffer zp[2]:12 2.0
char *tempbuffer#9 // tempbuffer_1 zp[2]:6 11.0
zp[2]:6 [ tempbuffer#9 tempbuffer#21 ]
zp[2]:2 [ screen#12 screen#0 ]
zp[2]:8 [ newbuffer#9 newbuffer#22 ]
zp[2]:4 [ oldbuffer#9 oldbuffer#22 ]
zp[2]:12 [ tempbuffer#0 tempbuffer#22 tempbuffer#23 ]
zp[2]:10 [ newbuffer#0 newbuffer#23 newbuffer#24 ]
reg byte a [ print::$3 ]
reg byte a [ print::$0 ]
reg byte a [ print::$4 ]
reg byte a [ print::$1 ]
reg byte a [ print::$5 ]
reg byte a [ print::$2 ]