mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-27 01:29:37 +00:00
Added support for CPU HUC6280.
This commit is contained in:
parent
ec3120fc1d
commit
517b2af6d5
2
pom.xml
2
pom.xml
@ -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>
|
||||
|
Binary file not shown.
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -20,6 +20,8 @@ void main() {
|
||||
cly
|
||||
csh
|
||||
set
|
||||
tst #1+2,$3+4
|
||||
tst #1+2*3,$7654/2
|
||||
!:
|
||||
rts
|
||||
}
|
||||
|
14
src/test/kc/ducks-array.c
Normal file
14
src/test/kc/ducks-array.c
Normal 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
src/test/kc/ducks-loop211.c
Normal file
22
src/test/kc/ducks-loop211.c
Normal 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
src/test/kc/ducks-total.c
Normal file
157
src/test/kc/ducks-total.c
Normal 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
src/test/kc/pointer-swap.c
Normal file
31
src/test/kc/pointer-swap.c
Normal 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();
|
||||
}
|
@ -26,6 +26,8 @@ main: {
|
||||
cly
|
||||
csh
|
||||
set
|
||||
tst #1+2,3+4
|
||||
tst #1+2*3,$7654/2
|
||||
!:
|
||||
rts
|
||||
// }
|
||||
|
@ -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
|
||||
|
@ -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
src/test/ref/ducks-array.asm
Normal file
45
src/test/ref/ducks-array.asm
Normal 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
src/test/ref/ducks-array.cfg
Normal file
33
src/test/ref/ducks-array.cfg
Normal 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
src/test/ref/ducks-array.log
Normal file
521
src/test/ref/ducks-array.log
Normal 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
src/test/ref/ducks-array.sym
Normal file
10
src/test/ref/ducks-array.sym
Normal 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
src/test/ref/ducks-loop211.asm
Normal file
46
src/test/ref/ducks-loop211.asm
Normal 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
src/test/ref/ducks-loop211.cfg
Normal file
27
src/test/ref/ducks-loop211.cfg
Normal 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
src/test/ref/ducks-loop211.log
Normal file
353
src/test/ref/ducks-loop211.log
Normal 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
src/test/ref/ducks-loop211.sym
Normal file
12
src/test/ref/ducks-loop211.sym
Normal 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 ]
|
2126
src/test/ref/ducks-total.asm
Normal file
2126
src/test/ref/ducks-total.asm
Normal file
File diff suppressed because it is too large
Load Diff
1030
src/test/ref/ducks-total.cfg
Normal file
1030
src/test/ref/ducks-total.cfg
Normal file
File diff suppressed because it is too large
Load Diff
16903
src/test/ref/ducks-total.log
Normal file
16903
src/test/ref/ducks-total.log
Normal file
File diff suppressed because one or more lines are too long
440
src/test/ref/ducks-total.sym
Normal file
440
src/test/ref/ducks-total.sym
Normal 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
src/test/ref/pointer-swap.asm
Normal file
124
src/test/ref/pointer-swap.asm
Normal 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
src/test/ref/pointer-swap.cfg
Normal file
57
src/test/ref/pointer-swap.cfg
Normal 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
|
1019
src/test/ref/pointer-swap.log
Normal file
1019
src/test/ref/pointer-swap.log
Normal file
File diff suppressed because it is too large
Load Diff
43
src/test/ref/pointer-swap.sym
Normal file
43
src/test/ref/pointer-swap.sym
Normal 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 ]
|
Loading…
x
Reference in New Issue
Block a user