mirror of https://gitlab.com/camelot/kickc.git
Added cruncher plug-in and example programs. Closes #603
This commit is contained in:
parent
2dd2697ba1
commit
c36da71ecd
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: se.triad.kickass:kickass-cruncher-plugins:2.0">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
66
NOTICE.txt
66
NOTICE.txt
|
@ -1,23 +1,77 @@
|
||||||
3rd Party Licenses
|
3rd Party Licenses
|
||||||
- Toiletrensdyr SID is redistributed by personal permission from Søren Lund
|
|
||||||
- KickAssembler is redistributed by personal permission from Mads Nielsen
|
- KickAssembler is redistributed by personal permission from Mads Nielsen
|
||||||
- KickAssembler65CE02 is a modified version of KickAssembler by myself (Jesper Gravgaard)
|
- KickAssembler65CE02 is a modified version of KickAssembler by myself (Jesper Gravgaard)
|
||||||
|
- Toiletrensdyr SID is redistributed by personal permission from Søren Lund
|
||||||
|
- kickass-cruncher-plugins by P-a Bäckström is redistributed under MIT License
|
||||||
|
- kickass-plugin-atari-xex by myself (Jesper Gravgaard) is redistributed under MIT License
|
||||||
- ANTLR4 is redistributed under BSD License
|
- ANTLR4 is redistributed under BSD License
|
||||||
- PICOCLI is redistributed under Apache License 2.0
|
- PICOCLI is redistributed under Apache License 2.0
|
||||||
- JAVAX.JSON JSR 374 (JSON Processing) Default Provider and API is is redistributed under COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.1
|
- JAVAX.JSON JSR 374 (JSON Processing) Default Provider and API is is redistributed under COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.1
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
Toiletrensdyr - https://csdb.dk/sid/?id=54859
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
KickAssembler - https://theweb.dk/KickAssembler/
|
KickAssembler - https://theweb.dk/KickAssembler/
|
||||||
|
Created by Mads Nielsen
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
KickAssembler65CE02 - https://gitlab.com/jespergravgaard/kickassembler65ce02
|
KickAssembler65CE02 - https://gitlab.com/jespergravgaard/kickassembler65ce02
|
||||||
|
KickAssembler created by Mads Nielsen - modified by Jesper Gravgaard
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|
|
||||||
|
-------------------------------------------------
|
||||||
|
Toiletrensdyr - https://csdb.dk/sid/?id=54859
|
||||||
|
Created by Søren Lund
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
-------------------------------------------------
|
||||||
|
kickass-cruncher-plugins - KickAss Cruncher Plugins - https://github.com/p-a/kickass-cruncher-plugins
|
||||||
|
-------------------------------------------------
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013 P-a Bäckström
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
-------------------------------------------------
|
||||||
|
kickass-plugin-atari-xex - Kick Assembler Atari XEX Format Plugin - https://gitlab.com/jespergravgaard/kickass-plugin-atari-xex
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 Jesper Balman Gravgaard
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
ANTLR4 - http://www.antlr.org/
|
ANTLR4 - http://www.antlr.org/
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|
|
|
@ -27,5 +27,6 @@
|
||||||
<orderEntry type="library" name="Maven: org.glassfish:javax.json:1.1.4" level="project" />
|
<orderEntry type="library" name="Maven: org.glassfish:javax.json:1.1.4" level="project" />
|
||||||
<orderEntry type="library" name="Maven: cml.kickass:kickassembler:5.16-65ce02.i" level="project" />
|
<orderEntry type="library" name="Maven: cml.kickass:kickassembler:5.16-65ce02.i" level="project" />
|
||||||
<orderEntry type="library" name="Maven: dk.camelot64.kickass.xexplugin:kickassxexformat:1.3" level="project" />
|
<orderEntry type="library" name="Maven: dk.camelot64.kickass.xexplugin:kickassxexformat:1.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: se.triad.kickass:kickass-cruncher-plugins:2.0" level="project" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
5
pom.xml
5
pom.xml
|
@ -66,6 +66,11 @@
|
||||||
<artifactId>kickassxexformat</artifactId>
|
<artifactId>kickassxexformat</artifactId>
|
||||||
<version>1.3</version>
|
<version>1.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>se.triad.kickass</groupId>
|
||||||
|
<artifactId>kickass-cruncher-plugins</artifactId>
|
||||||
|
<version>2.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
|
||||||
|
#Wed Dec 30 19:02:11 CET 2020
|
||||||
|
kickass-cruncher-plugins-2.0.jar>=
|
||||||
|
kickass-cruncher-plugins-2.0.pom>=
|
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
447c4814f5ec16eb83c11beb3b01d31e
|
|
@ -0,0 +1 @@
|
||||||
|
6bf3f7ab6484422cab660080f9c52e32fd1a3494
|
|
@ -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>se.triad.kickass</groupId>
|
||||||
|
<artifactId>kickass-cruncher-plugins</artifactId>
|
||||||
|
<version>2.0</version>
|
||||||
|
<description>POM was created from install:install-file</description>
|
||||||
|
</project>
|
|
@ -0,0 +1 @@
|
||||||
|
8df79d73d4bb320c097875441b02c73f
|
|
@ -0,0 +1 @@
|
||||||
|
0a9df4151d0ac74eb6faba472ed7f0aa7fb1f330
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<metadata>
|
||||||
|
<groupId>se.triad.kickass</groupId>
|
||||||
|
<artifactId>kickass-cruncher-plugins</artifactId>
|
||||||
|
<versioning>
|
||||||
|
<release>2.0</release>
|
||||||
|
<versions>
|
||||||
|
<version>2.0</version>
|
||||||
|
</versions>
|
||||||
|
<lastUpdated>20201230180211</lastUpdated>
|
||||||
|
</versioning>
|
||||||
|
</metadata>
|
|
@ -0,0 +1 @@
|
||||||
|
ab025b6956bb8dc32185f8a6e084762d
|
|
@ -0,0 +1 @@
|
||||||
|
22b621912e62295723e7aa4e9614b2032ac4377b
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Prepare by making the "official" metadata local
|
||||||
|
cp ./repo/se/triad/kickass/kickass-cruncher-plugins/maven-metadata.xml ./repo/se/triad/kickass/kickass-cruncher-plugins/maven-metadata-local.xml
|
||||||
|
|
||||||
|
mvn install:install-file -Dmaven.repo.local=./repo/ -Dfile=/Users/jespergravgaard/c64/cruncher-plugins/releases/kickass-cruncher-plugins-2.0/kickass-cruncher-plugins-2.0.jar -DgroupId=se.triad.kickass -DartifactId=kickass-cruncher-plugins -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true -Dversion=2.0
|
||||||
|
|
||||||
|
# Finalize by making the local metadata official
|
||||||
|
pushd ./repo/se/triad/kickass/kickass-cruncher-plugins/
|
||||||
|
mv maven-metadata-local.xml maven-metadata.xml
|
||||||
|
mv maven-metadata-local.xml.md5 maven-metadata.xml.md5
|
||||||
|
mv maven-metadata-local.xml.sha1 maven-metadata.xml.sha1
|
||||||
|
popd
|
||||||
|
|
||||||
|
# Remove stuff that Maven adds, that we don't need
|
||||||
|
rm -rf ./repo/classworlds
|
||||||
|
rm -rf ./repo/junit
|
||||||
|
rm -rf ./repo/org
|
|
@ -3388,6 +3388,16 @@ public class TestPrograms {
|
||||||
compileAndCompare("examples/music/music_irq.c");
|
compileAndCompare("examples/music/music_irq.c");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCrunchingExomizer() throws IOException, URISyntaxException {
|
||||||
|
compileAndCompare("examples/crunching/test-exomizer.c");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCrunchingByteboozer() throws IOException, URISyntaxException {
|
||||||
|
compileAndCompare("examples/crunching/test-byteboozer.c");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMusic() throws IOException, URISyntaxException {
|
public void testMusic() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("examples/music/music.c");
|
compileAndCompare("examples/music/music.c");
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
// ByteBoozer decruncher
|
||||||
|
// https://github.com/p-a/kickass-cruncher-plugins
|
||||||
|
|
||||||
|
// Decrunch crunched data using ByteBoozer
|
||||||
|
// - crunched: Pointer to the start of the crunched data
|
||||||
|
void byteboozer_decrunch(char* crunched) {
|
||||||
|
asm {
|
||||||
|
ldy crunched
|
||||||
|
ldx crunched+1
|
||||||
|
jsr b2.Decrunch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The byteboozer decruncher
|
||||||
|
export char BYTEBOOZER[] = kickasm(resource "byteboozer_decrunch.asm") {{
|
||||||
|
.const B2_ZP_BASE = $fc
|
||||||
|
#import "byteboozer_decrunch.asm"
|
||||||
|
}};
|
|
@ -0,0 +1,6 @@
|
||||||
|
// ByteBoozer decruncher
|
||||||
|
// https://github.com/p-a/kickass-cruncher-plugins
|
||||||
|
|
||||||
|
// Decrunch crunched data using ByteBoozer
|
||||||
|
// - crunched: Pointer to the start of the crunched data
|
||||||
|
void byteboozer_decrunch(char* crunched);
|
|
@ -0,0 +1,182 @@
|
||||||
|
// ByteBoozer Decruncher /HCL May.2003
|
||||||
|
// B2 Decruncher December 2014
|
||||||
|
|
||||||
|
.importonce
|
||||||
|
.filenamespace b2
|
||||||
|
|
||||||
|
// You must set .const B2_ZP_BASE prior the import of this file
|
||||||
|
.if (B2_ZP_BASE > $ff) {
|
||||||
|
.error "B2_ZP_BASE must be in zeropage. Was $" + toHexString(B2_ZP_BASE,4)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.label zp_base = B2_ZP_BASE
|
||||||
|
.label bits = zp_base
|
||||||
|
.label put = zp_base + 2
|
||||||
|
|
||||||
|
.macro @B2_DECRUNCH(addr) {
|
||||||
|
ldy #<addr
|
||||||
|
ldx #>addr
|
||||||
|
jsr b2.Decrunch
|
||||||
|
}
|
||||||
|
|
||||||
|
.macro GetNextBit() {
|
||||||
|
asl bits
|
||||||
|
bne DgEnd
|
||||||
|
jsr GetNewBits
|
||||||
|
DgEnd:
|
||||||
|
}
|
||||||
|
|
||||||
|
.macro GetLen() {
|
||||||
|
lda #1
|
||||||
|
GlLoop:
|
||||||
|
:GetNextBit()
|
||||||
|
bcc GlEnd
|
||||||
|
:GetNextBit()
|
||||||
|
rol
|
||||||
|
bpl GlLoop
|
||||||
|
GlEnd:
|
||||||
|
}
|
||||||
|
|
||||||
|
Decrunch:
|
||||||
|
sty Get1+1
|
||||||
|
sty Get2+1
|
||||||
|
sty Get3+1
|
||||||
|
stx Get1+2
|
||||||
|
stx Get2+2
|
||||||
|
stx Get3+2
|
||||||
|
|
||||||
|
ldx #0
|
||||||
|
jsr GetNewBits
|
||||||
|
sty put-1,x
|
||||||
|
cpx #2
|
||||||
|
bcc *-7
|
||||||
|
lda #$80
|
||||||
|
sta bits
|
||||||
|
DLoop:
|
||||||
|
:GetNextBit()
|
||||||
|
bcs Match
|
||||||
|
Literal:
|
||||||
|
// Literal run.. get length.
|
||||||
|
:GetLen()
|
||||||
|
sta LLen+1
|
||||||
|
|
||||||
|
ldy #0
|
||||||
|
LLoop:
|
||||||
|
Get3:
|
||||||
|
lda $feed,x
|
||||||
|
inx
|
||||||
|
bne *+5
|
||||||
|
jsr GnbInc
|
||||||
|
L1: sta (put),y
|
||||||
|
iny
|
||||||
|
LLen:
|
||||||
|
cpy #0
|
||||||
|
bne LLoop
|
||||||
|
|
||||||
|
clc
|
||||||
|
tya
|
||||||
|
adc put
|
||||||
|
sta put
|
||||||
|
bcc *+4
|
||||||
|
inc put+1
|
||||||
|
|
||||||
|
iny
|
||||||
|
beq DLoop
|
||||||
|
|
||||||
|
// Has to continue with a match..
|
||||||
|
|
||||||
|
Match:
|
||||||
|
// Match.. get length.
|
||||||
|
:GetLen()
|
||||||
|
sta MLen+1
|
||||||
|
|
||||||
|
// Length 255 -> EOF
|
||||||
|
cmp #$ff
|
||||||
|
beq End
|
||||||
|
|
||||||
|
// Get num bits
|
||||||
|
cmp #2
|
||||||
|
lda #0
|
||||||
|
rol
|
||||||
|
:GetNextBit()
|
||||||
|
rol
|
||||||
|
:GetNextBit()
|
||||||
|
rol
|
||||||
|
tay
|
||||||
|
lda Tab,y
|
||||||
|
beq M8
|
||||||
|
|
||||||
|
// Get bits < 8
|
||||||
|
M_1:
|
||||||
|
:GetNextBit()
|
||||||
|
rol
|
||||||
|
bcs M_1
|
||||||
|
bmi MShort
|
||||||
|
M8:
|
||||||
|
// Get byte
|
||||||
|
eor #$ff
|
||||||
|
tay
|
||||||
|
Get2:
|
||||||
|
lda $feed,x
|
||||||
|
inx
|
||||||
|
bne *+5
|
||||||
|
jsr GnbInc
|
||||||
|
jmp Mdone
|
||||||
|
MShort:
|
||||||
|
ldy #$ff
|
||||||
|
Mdone:
|
||||||
|
//clc
|
||||||
|
adc put
|
||||||
|
sta MLda+1
|
||||||
|
tya
|
||||||
|
adc put+1
|
||||||
|
sta MLda+2
|
||||||
|
|
||||||
|
ldy #$ff
|
||||||
|
MLoop:
|
||||||
|
iny
|
||||||
|
MLda:
|
||||||
|
lda $beef,y
|
||||||
|
sta (put),y
|
||||||
|
MLen:
|
||||||
|
cpy #0
|
||||||
|
bne MLoop
|
||||||
|
|
||||||
|
//sec
|
||||||
|
tya
|
||||||
|
adc put
|
||||||
|
sta put
|
||||||
|
bcc *+4
|
||||||
|
inc put+1
|
||||||
|
|
||||||
|
jmp DLoop
|
||||||
|
|
||||||
|
End:
|
||||||
|
rts
|
||||||
|
|
||||||
|
GetNewBits:
|
||||||
|
Get1:
|
||||||
|
ldy $feed,x
|
||||||
|
sty bits
|
||||||
|
rol bits
|
||||||
|
inx
|
||||||
|
bne GnbEnd
|
||||||
|
GnbInc:
|
||||||
|
inc Get1+2
|
||||||
|
inc Get2+2
|
||||||
|
inc Get3+2
|
||||||
|
GnbEnd:
|
||||||
|
rts
|
||||||
|
|
||||||
|
Tab:
|
||||||
|
// Short offsets
|
||||||
|
.byte %11011111 // 3
|
||||||
|
.byte %11111011 // 6
|
||||||
|
.byte %00000000 // 8
|
||||||
|
.byte %10000000 // 10
|
||||||
|
// Long offsets
|
||||||
|
.byte %11101111 // 4
|
||||||
|
.byte %11111101 // 7
|
||||||
|
.byte %10000000 // 10
|
||||||
|
.byte %11110000 // 13
|
|
@ -0,0 +1,9 @@
|
||||||
|
// Commodore 64 PRG executable file - with the cruncher plugin enabled
|
||||||
|
.plugin "se.triad.kickass.CruncherPlugins"
|
||||||
|
.file [name="%O", type="prg", segments="Program"]
|
||||||
|
.segmentdef Program [segments="Basic, Code, Data"]
|
||||||
|
.segmentdef Basic [start=$0801]
|
||||||
|
.segmentdef Code [start=%P]
|
||||||
|
.segmentdef Data [startAfter="Code"]
|
||||||
|
.segment Basic
|
||||||
|
:BasicUpstart(%E)
|
|
@ -0,0 +1,354 @@
|
||||||
|
.importonce
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copyright (c) 2002 - 2005 Magnus Lind.
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
// In no event will the authors be held liable for any damages arising from
|
||||||
|
// the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented// you must not
|
||||||
|
// claim that you wrote the original software. If you use this software in a
|
||||||
|
// product, an acknowledgment in the product documentation would be
|
||||||
|
// appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any distribution.
|
||||||
|
//
|
||||||
|
// 4. The names of this software and/or it's copyright holders may not be
|
||||||
|
// used to endorse or promote products derived from this software without
|
||||||
|
// specific prior written permission.
|
||||||
|
//
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// The decruncher jsr:s to the get_crunched_byte address when it wants to
|
||||||
|
// read a crunched byte. This subroutine has to preserve x and y register
|
||||||
|
// and must not modify the state of the carry flag.
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// this function is the heart of the decruncher.
|
||||||
|
// It initializes the decruncher zeropage locations and precalculates the
|
||||||
|
// decrunch tables and decrunches the data
|
||||||
|
// This function will not change the interrupt status bit and it will not
|
||||||
|
// modify the memory configuration.
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// if literal sequences is not used (the data was crunched with the -c
|
||||||
|
// flag) then the following line can be uncommented for shorter code.
|
||||||
|
|
||||||
|
|
||||||
|
// KICKASMIFIED BY RUK / TRIAD 2012 -
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// zero page addresses used - define in EXO_ZP_BASE
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
.macro EXO_DECRUNCH(end_addr){
|
||||||
|
lda #<end_addr
|
||||||
|
sta exodecr.zp_getb_lo
|
||||||
|
lda #>end_addr
|
||||||
|
sta exodecr.zp_getb_hi
|
||||||
|
jsr exodecr.decrunch
|
||||||
|
}
|
||||||
|
|
||||||
|
.namespace exodecr {
|
||||||
|
|
||||||
|
.label zp_len_lo = EXO_ZP_BASE
|
||||||
|
|
||||||
|
.label zp_src_lo = zp_len_lo + 1
|
||||||
|
.label zp_src_hi = zp_src_lo + 1
|
||||||
|
|
||||||
|
.label zp_bits_hi = zp_src_hi + 1
|
||||||
|
|
||||||
|
.label zp_bitbuf = zp_bits_hi + 1
|
||||||
|
.label zp_dest_lo = zp_bitbuf + 1 // dest addr lo
|
||||||
|
.label zp_dest_hi = zp_bitbuf + 2 // dest addr hi
|
||||||
|
|
||||||
|
.label zp_getb_lo = zp_dest_hi + 1
|
||||||
|
.label zp_getb_hi = zp_getb_lo + 1
|
||||||
|
|
||||||
|
.label tabl_bi = EXO_DECRUNCH_TABLE
|
||||||
|
.label tabl_lo = EXO_DECRUNCH_TABLE + 52
|
||||||
|
.label tabl_hi = EXO_DECRUNCH_TABLE + 104
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// no code below this comment has to be modified in order to generate
|
||||||
|
// a working decruncher of this source file.
|
||||||
|
// However, you may want to relocate the tables last in the file to a
|
||||||
|
// more suitable address.
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// jsr this label to decrunch, it will in turn init the tables and
|
||||||
|
// call the decruncher
|
||||||
|
// no constraints on register content, however the
|
||||||
|
// decimal flag has to be #0 (it almost always is, otherwise do a cld)
|
||||||
|
|
||||||
|
.pseudocommand get_crunched_byte {
|
||||||
|
|
||||||
|
sty tmpy
|
||||||
|
|
||||||
|
lda zp_getb_lo
|
||||||
|
bne !+
|
||||||
|
dec zp_getb_hi
|
||||||
|
!:
|
||||||
|
dec zp_getb_lo
|
||||||
|
|
||||||
|
ldy #0
|
||||||
|
lda (zp_getb_lo),y
|
||||||
|
|
||||||
|
ldy #00
|
||||||
|
.label tmpy = * - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
decrunch:
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// init zeropage, x and y regs. (12 bytes)
|
||||||
|
//
|
||||||
|
ldy #0
|
||||||
|
ldx #3
|
||||||
|
init_zp:
|
||||||
|
:get_crunched_byte
|
||||||
|
sta zp_bitbuf - 1,x
|
||||||
|
dex
|
||||||
|
bne init_zp
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// calculate tables (50 bytes)
|
||||||
|
// x and y must be #0 when entering
|
||||||
|
//
|
||||||
|
nextone:
|
||||||
|
inx
|
||||||
|
tya
|
||||||
|
and #$0f
|
||||||
|
beq shortcut // starta p<EFBFBD> ny sekvens
|
||||||
|
|
||||||
|
txa // this clears reg a
|
||||||
|
lsr // and sets the carry flag
|
||||||
|
ldx tabl_bi-1,y
|
||||||
|
rolle:
|
||||||
|
rol
|
||||||
|
rol zp_bits_hi
|
||||||
|
dex
|
||||||
|
bpl rolle // c = 0 after this (rol zp_bits_hi)
|
||||||
|
|
||||||
|
adc tabl_lo-1,y
|
||||||
|
tax
|
||||||
|
|
||||||
|
lda zp_bits_hi
|
||||||
|
adc tabl_hi-1,y
|
||||||
|
shortcut:
|
||||||
|
sta tabl_hi,y
|
||||||
|
txa
|
||||||
|
sta tabl_lo,y
|
||||||
|
|
||||||
|
ldx #4
|
||||||
|
jsr get_bits // clears x-reg.
|
||||||
|
sta tabl_bi,y
|
||||||
|
iny
|
||||||
|
cpy #52
|
||||||
|
bne nextone
|
||||||
|
ldy #0
|
||||||
|
beq begin
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// get bits (29 bytes)
|
||||||
|
//
|
||||||
|
// args:
|
||||||
|
// x = number of bits to get
|
||||||
|
// returns:
|
||||||
|
// a = #bits_lo
|
||||||
|
// x = #0
|
||||||
|
// c = 0
|
||||||
|
// z = 1
|
||||||
|
// zp_bits_hi = #bits_hi
|
||||||
|
// notes:
|
||||||
|
// y is untouched
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
get_bits:
|
||||||
|
lda #$00
|
||||||
|
sta zp_bits_hi
|
||||||
|
cpx #$01
|
||||||
|
bcc bits_done
|
||||||
|
bits_next:
|
||||||
|
lsr zp_bitbuf
|
||||||
|
bne ok
|
||||||
|
pha
|
||||||
|
literal_get_byte:
|
||||||
|
:get_crunched_byte
|
||||||
|
bcc literal_byte_gotten
|
||||||
|
ror
|
||||||
|
sta zp_bitbuf
|
||||||
|
pla
|
||||||
|
ok:
|
||||||
|
rol
|
||||||
|
rol zp_bits_hi
|
||||||
|
dex
|
||||||
|
bne bits_next
|
||||||
|
bits_done:
|
||||||
|
rts
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// main copy loop (18(16) bytes)
|
||||||
|
//
|
||||||
|
copy_next_hi:
|
||||||
|
dex
|
||||||
|
dec zp_dest_hi
|
||||||
|
dec zp_src_hi
|
||||||
|
copy_next:
|
||||||
|
dey
|
||||||
|
.if (EXO_LITERAL_SEQUENCES_USED) {
|
||||||
|
bcc literal_get_byte
|
||||||
|
}
|
||||||
|
lda (zp_src_lo),y
|
||||||
|
literal_byte_gotten:
|
||||||
|
sta (zp_dest_lo),y
|
||||||
|
copy_start:
|
||||||
|
tya
|
||||||
|
bne copy_next
|
||||||
|
begin:
|
||||||
|
txa
|
||||||
|
bne copy_next_hi
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// decruncher entry point, needs calculated tables (21(13) bytes)
|
||||||
|
// x and y must be #0 when entering
|
||||||
|
//
|
||||||
|
.if (EXO_LITERAL_SEQUENCES_USED){
|
||||||
|
inx
|
||||||
|
jsr get_bits
|
||||||
|
tay
|
||||||
|
bne literal_start1
|
||||||
|
} else {
|
||||||
|
dey
|
||||||
|
}
|
||||||
|
|
||||||
|
begin2:
|
||||||
|
inx
|
||||||
|
jsr bits_next
|
||||||
|
lsr
|
||||||
|
iny
|
||||||
|
bcc begin2
|
||||||
|
.if (!EXO_LITERAL_SEQUENCES_USED){
|
||||||
|
beq literal_start
|
||||||
|
}
|
||||||
|
cpy #$11
|
||||||
|
|
||||||
|
.label literal_start1 = * + 9
|
||||||
|
.if (EXO_LITERAL_SEQUENCES_USED){
|
||||||
|
bcc sequence_start
|
||||||
|
beq bits_done
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// literal sequence handling (13(2) bytes)
|
||||||
|
|
||||||
|
ldx #$10
|
||||||
|
jsr get_bits
|
||||||
|
literal_start1_real:
|
||||||
|
sta <zp_len_lo
|
||||||
|
ldx <zp_bits_hi
|
||||||
|
ldy #0
|
||||||
|
bcc literal_start
|
||||||
|
sequence_start:
|
||||||
|
} else {
|
||||||
|
bcs bits_done
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// calulate length of sequence (zp_len) (11 bytes)
|
||||||
|
//
|
||||||
|
ldx tabl_bi - 1,y
|
||||||
|
jsr get_bits
|
||||||
|
adc tabl_lo - 1,y // we have now calculated zp_len_lo
|
||||||
|
sta zp_len_lo
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// now do the hibyte of the sequence length calculation (6 bytes)
|
||||||
|
lda zp_bits_hi
|
||||||
|
adc tabl_hi - 1,y // c = 0 after this.
|
||||||
|
pha
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// here we decide what offset table to use (20 bytes)
|
||||||
|
// x is 0 here
|
||||||
|
//
|
||||||
|
bne nots123
|
||||||
|
ldy zp_len_lo
|
||||||
|
cpy #$04
|
||||||
|
bcc size123
|
||||||
|
nots123:
|
||||||
|
ldy #$03
|
||||||
|
size123:
|
||||||
|
ldx tabl_bit - 1,y
|
||||||
|
jsr get_bits
|
||||||
|
adc tabl_off - 1,y // c = 0 after this.
|
||||||
|
tay // 1 <= y <= 52 here
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Here we do the dest_lo -= len_lo subtraction to prepare zp_dest
|
||||||
|
// but we do it backwards: a - b == (b - a - 1) ^ ~0 (C-syntax)
|
||||||
|
// (16(16) bytes)
|
||||||
|
lda zp_len_lo
|
||||||
|
literal_start: // literal enters here with y = 0, c = 1
|
||||||
|
sbc zp_dest_lo
|
||||||
|
bcc noborrow
|
||||||
|
dec zp_dest_hi
|
||||||
|
noborrow:
|
||||||
|
eor #$ff
|
||||||
|
sta zp_dest_lo
|
||||||
|
cpy #$01 // y < 1 then literal
|
||||||
|
.if (EXO_LITERAL_SEQUENCES_USED){
|
||||||
|
bcc pre_copy
|
||||||
|
} else {
|
||||||
|
bcc literal_get_byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// calulate absolute offset (zp_src) (27 bytes)
|
||||||
|
//
|
||||||
|
ldx tabl_bi,y
|
||||||
|
jsr get_bits//
|
||||||
|
adc tabl_lo,y
|
||||||
|
bcc skipcarry
|
||||||
|
inc zp_bits_hi
|
||||||
|
clc
|
||||||
|
skipcarry:
|
||||||
|
adc zp_dest_lo
|
||||||
|
sta zp_src_lo
|
||||||
|
lda zp_bits_hi
|
||||||
|
adc tabl_hi,y
|
||||||
|
adc zp_dest_hi
|
||||||
|
sta zp_src_hi
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// prepare for copy loop (8(6) bytes)
|
||||||
|
//
|
||||||
|
pla
|
||||||
|
tax
|
||||||
|
.label pre_copy = * + 1
|
||||||
|
.if(EXO_LITERAL_SEQUENCES_USED){
|
||||||
|
sec
|
||||||
|
pre_copy_real:
|
||||||
|
ldy <zp_len_lo
|
||||||
|
jmp copy_start
|
||||||
|
} else {
|
||||||
|
ldy <zp_len_lo
|
||||||
|
jmp copy_start
|
||||||
|
}
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// two small static tables (6(6) bytes)
|
||||||
|
//
|
||||||
|
tabl_bit:
|
||||||
|
.byte 2,4,4
|
||||||
|
tabl_off:
|
||||||
|
.byte 48,32,16
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// end of decruncher
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
end_of_decrunch:
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// this 156 byte table area may be relocated. It may also be clobbered
|
||||||
|
// by other data between decrunches.
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
//decrunch_table: - please define somewhere
|
||||||
|
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,36 @@
|
||||||
|
// Example showing how to crunch and decrunch part of a file using the KickAss Cruncher Plugins
|
||||||
|
// ByteBoozer example
|
||||||
|
// https://github.com/p-a/kickass-cruncher-plugins
|
||||||
|
|
||||||
|
#pragma target(c64)
|
||||||
|
#pragma link("crunching.ld")
|
||||||
|
#include <c64.h>
|
||||||
|
#include "byteboozer.h"
|
||||||
|
|
||||||
|
// Address to decrunch the sprite to
|
||||||
|
char * const SPRITE = 0x2000;
|
||||||
|
|
||||||
|
// The sprite pointers
|
||||||
|
char * const SPRITES_PTR = DEFAULT_SCREEN+OFFSET_SPRITE_PTRS;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// Decrunch sprite file into memory
|
||||||
|
byteboozer_decrunch(CRUNCHED_SPRITE);
|
||||||
|
// Show the loaded sprite on screen
|
||||||
|
VICII->SPRITES_ENABLE = %00000001;
|
||||||
|
SPRITES_PTR[0] = toSpritePtr(SPRITE);
|
||||||
|
SPRITES_COLOR[0] = GREEN;
|
||||||
|
SPRITES_XPOS[0] = 0x15;
|
||||||
|
SPRITES_YPOS[0] = 0x33;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array with crunched data created using inline kickasm
|
||||||
|
export char CRUNCHED_SPRITE[] = kickasm(uses SPRITE, resource "sprite.png") {{
|
||||||
|
.modify B2() {
|
||||||
|
.pc = SPRITE
|
||||||
|
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||||
|
.for (var y=0; y<21; y++)
|
||||||
|
.for (var x=0;x<3; x++)
|
||||||
|
.byte pic.getSinglecolorByte(x,y)
|
||||||
|
}
|
||||||
|
}};
|
|
@ -0,0 +1,46 @@
|
||||||
|
// Example showing how to crunch and decrunch part of a file using the KickAss Cruncher Plugins
|
||||||
|
// Exomizer Example
|
||||||
|
// https://github.com/p-a/kickass-cruncher-plugins
|
||||||
|
|
||||||
|
#pragma target(c64)
|
||||||
|
#pragma link("crunching.ld")
|
||||||
|
#include <c64.h>
|
||||||
|
|
||||||
|
// Address to decrunch the sprite to
|
||||||
|
char * const SPRITE = 0x2000;
|
||||||
|
|
||||||
|
char * const SPRITES_PTR = DEFAULT_SCREEN+OFFSET_SPRITE_PTRS;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// Decrunch sprite file into memory
|
||||||
|
kickasm {{
|
||||||
|
:EXO_DECRUNCH(CRUNCHED_SPRITE_END)
|
||||||
|
}}
|
||||||
|
// Show the loaded sprite on screen
|
||||||
|
VICII->SPRITES_ENABLE = %00000001;
|
||||||
|
SPRITES_PTR[0] = toSpritePtr(SPRITE);
|
||||||
|
SPRITES_COLOR[0] = GREEN;
|
||||||
|
SPRITES_XPOS[0] = 0x15;
|
||||||
|
SPRITES_YPOS[0] = 0x33;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The exomizer decruncher
|
||||||
|
export char EXOMIZER[] = kickasm(resource "exomizer_decrunch.asm") {{
|
||||||
|
.const EXO_LITERAL_SEQUENCES_USED = true
|
||||||
|
.const EXO_ZP_BASE = $02
|
||||||
|
.const EXO_DECRUNCH_TABLE = $0200
|
||||||
|
#import "exomizer_decrunch.asm"
|
||||||
|
}};
|
||||||
|
|
||||||
|
// Array with crunched data created using inline kickasm
|
||||||
|
export char CRUNCHED_SPRITE[] = kickasm(uses SPRITE, resource "sprite.png") {{
|
||||||
|
.modify MemExomizer(false, true) {
|
||||||
|
.pc = SPRITE
|
||||||
|
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||||
|
.for (var y=0; y<21; y++)
|
||||||
|
.for (var x=0;x<3; x++)
|
||||||
|
.byte pic.getSinglecolorByte(x,y)
|
||||||
|
}
|
||||||
|
CRUNCHED_SPRITE_END:
|
||||||
|
}};
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
// Example showing how to crunch and decrunch part of a file using the KickAss Cruncher Plugins
|
||||||
|
// ByteBoozer example
|
||||||
|
// https://github.com/p-a/kickass-cruncher-plugins
|
||||||
|
// Commodore 64 PRG executable file - with the cruncher plugin enabled
|
||||||
|
.plugin "se.triad.kickass.CruncherPlugins"
|
||||||
|
.file [name="test-byteboozer.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)
|
||||||
|
// The offset of the sprite pointers from the screen start address
|
||||||
|
.const OFFSET_SPRITE_PTRS = $3f8
|
||||||
|
.const GREEN = 5
|
||||||
|
.const OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
|
||||||
|
.label SPRITES_XPOS = $d000
|
||||||
|
.label SPRITES_YPOS = $d001
|
||||||
|
.label SPRITES_COLOR = $d027
|
||||||
|
// The VIC-II MOS 6567/6569
|
||||||
|
.label VICII = $d000
|
||||||
|
// Default address of screen character matrix
|
||||||
|
.label DEFAULT_SCREEN = $400
|
||||||
|
// Address to decrunch the sprite to
|
||||||
|
.label SPRITE = $2000
|
||||||
|
// The sprite pointers
|
||||||
|
.label SPRITES_PTR = DEFAULT_SCREEN+OFFSET_SPRITE_PTRS
|
||||||
|
.segment Code
|
||||||
|
main: {
|
||||||
|
.const toSpritePtr1_return = SPRITE/$40
|
||||||
|
// byteboozer_decrunch(CRUNCHED_SPRITE)
|
||||||
|
lda #<CRUNCHED_SPRITE
|
||||||
|
sta.z byteboozer_decrunch.crunched
|
||||||
|
lda #>CRUNCHED_SPRITE
|
||||||
|
sta.z byteboozer_decrunch.crunched+1
|
||||||
|
// Decrunch sprite file into memory
|
||||||
|
jsr byteboozer_decrunch
|
||||||
|
// VICII->SPRITES_ENABLE = %00000001
|
||||||
|
// Show the loaded sprite on screen
|
||||||
|
lda #1
|
||||||
|
sta VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE
|
||||||
|
// SPRITES_PTR[0] = toSpritePtr(SPRITE)
|
||||||
|
lda #toSpritePtr1_return
|
||||||
|
sta SPRITES_PTR
|
||||||
|
// SPRITES_COLOR[0] = GREEN
|
||||||
|
lda #GREEN
|
||||||
|
sta SPRITES_COLOR
|
||||||
|
// SPRITES_XPOS[0] = 0x15
|
||||||
|
lda #$15
|
||||||
|
sta SPRITES_XPOS
|
||||||
|
// SPRITES_YPOS[0] = 0x33
|
||||||
|
lda #$33
|
||||||
|
sta SPRITES_YPOS
|
||||||
|
// }
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// Decrunch crunched data using ByteBoozer
|
||||||
|
// - crunched: Pointer to the start of the crunched data
|
||||||
|
// byteboozer_decrunch(byte* zp(2) crunched)
|
||||||
|
byteboozer_decrunch: {
|
||||||
|
.label crunched = 2
|
||||||
|
// asm
|
||||||
|
ldy crunched
|
||||||
|
ldx crunched+1
|
||||||
|
jsr b2.Decrunch
|
||||||
|
// }
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
.segment Data
|
||||||
|
// The byteboozer decruncher
|
||||||
|
BYTEBOOZER:
|
||||||
|
.const B2_ZP_BASE = $fc
|
||||||
|
#import "byteboozer_decrunch.asm"
|
||||||
|
|
||||||
|
// Array with crunched data created using inline kickasm
|
||||||
|
CRUNCHED_SPRITE:
|
||||||
|
.modify B2() {
|
||||||
|
.pc = SPRITE
|
||||||
|
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||||
|
.for (var y=0; y<21; y++)
|
||||||
|
.for (var x=0;x<3; x++)
|
||||||
|
.byte pic.getSinglecolorByte(x,y)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
void main()
|
||||||
|
main: scope:[main] from
|
||||||
|
[0] byteboozer_decrunch::crunched = CRUNCHED_SPRITE
|
||||||
|
[1] call byteboozer_decrunch
|
||||||
|
to:main::@2
|
||||||
|
main::@2: scope:[main] from main
|
||||||
|
[2] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1
|
||||||
|
to:main::toSpritePtr1
|
||||||
|
main::toSpritePtr1: scope:[main] from main::@2
|
||||||
|
[3] phi()
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main::toSpritePtr1
|
||||||
|
[4] *SPRITES_PTR = main::toSpritePtr1_return#0
|
||||||
|
[5] *SPRITES_COLOR = GREEN
|
||||||
|
[6] *SPRITES_XPOS = $15
|
||||||
|
[7] *SPRITES_YPOS = $33
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@1
|
||||||
|
[8] return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
void byteboozer_decrunch(volatile byte* byteboozer_decrunch::crunched)
|
||||||
|
byteboozer_decrunch: scope:[byteboozer_decrunch] from main
|
||||||
|
asm { ldycrunched ldxcrunched+1 jsrb2.Decrunch }
|
||||||
|
to:byteboozer_decrunch::@return
|
||||||
|
byteboozer_decrunch::@return: scope:[byteboozer_decrunch] from byteboozer_decrunch
|
||||||
|
[10] return
|
||||||
|
to:@return
|
|
@ -0,0 +1,508 @@
|
||||||
|
Loading link script "crunching.ld"
|
||||||
|
Resolved forward reference CRUNCHED_SPRITE to CRUNCHED_SPRITE
|
||||||
|
Setting inferred volatile on symbol affected by address-of: byteboozer_decrunch::crunched in asm { ldycrunched ldxcrunched+1 jsrb2.Decrunch }
|
||||||
|
Inlined call vicSelectGfxBank::$0 = call toDd00 vicSelectGfxBank::gfx
|
||||||
|
Inlined call main::$1 = call toSpritePtr SPRITE
|
||||||
|
|
||||||
|
CONTROL FLOW GRAPH SSA
|
||||||
|
|
||||||
|
void byteboozer_decrunch(volatile byte* byteboozer_decrunch::crunched)
|
||||||
|
byteboozer_decrunch: scope:[byteboozer_decrunch] from main
|
||||||
|
asm { ldycrunched ldxcrunched+1 jsrb2.Decrunch }
|
||||||
|
to:byteboozer_decrunch::@return
|
||||||
|
byteboozer_decrunch::@return: scope:[byteboozer_decrunch] from byteboozer_decrunch
|
||||||
|
return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
void main()
|
||||||
|
main: scope:[main] from __start
|
||||||
|
byteboozer_decrunch::crunched = CRUNCHED_SPRITE
|
||||||
|
call byteboozer_decrunch
|
||||||
|
to:main::@2
|
||||||
|
main::@2: scope:[main] from main
|
||||||
|
*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1
|
||||||
|
main::toSpritePtr1_sprite#0 = SPRITE
|
||||||
|
to:main::toSpritePtr1
|
||||||
|
main::toSpritePtr1: scope:[main] from main::@2
|
||||||
|
main::toSpritePtr1_sprite#1 = phi( main::@2/main::toSpritePtr1_sprite#0 )
|
||||||
|
main::toSpritePtr1_$1 = (word)main::toSpritePtr1_sprite#1
|
||||||
|
main::toSpritePtr1_$0 = main::toSpritePtr1_$1 / $40
|
||||||
|
main::toSpritePtr1_return#0 = (byte)main::toSpritePtr1_$0
|
||||||
|
to:main::toSpritePtr1_@return
|
||||||
|
main::toSpritePtr1_@return: scope:[main] from main::toSpritePtr1
|
||||||
|
main::toSpritePtr1_return#2 = phi( main::toSpritePtr1/main::toSpritePtr1_return#0 )
|
||||||
|
main::toSpritePtr1_return#1 = main::toSpritePtr1_return#2
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main::toSpritePtr1_@return
|
||||||
|
main::toSpritePtr1_return#3 = phi( main::toSpritePtr1_@return/main::toSpritePtr1_return#1 )
|
||||||
|
main::$1 = main::toSpritePtr1_return#3
|
||||||
|
SPRITES_PTR[0] = main::$1
|
||||||
|
SPRITES_COLOR[0] = GREEN
|
||||||
|
SPRITES_XPOS[0] = $15
|
||||||
|
SPRITES_YPOS[0] = $33
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@1
|
||||||
|
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
|
||||||
|
const byte* BYTEBOOZER[] = kickasm {{ .const B2_ZP_BASE = $fc
|
||||||
|
#import "byteboozer_decrunch.asm"
|
||||||
|
}}
|
||||||
|
const byte* CRUNCHED_SPRITE[] = kickasm( uses SPRITE) {{ .modify B2() {
|
||||||
|
.pc = SPRITE
|
||||||
|
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||||
|
.for (var y=0; y<21; y++)
|
||||||
|
.for (var x=0;x<3; x++)
|
||||||
|
.byte pic.getSinglecolorByte(x,y)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
const nomodify byte* DEFAULT_SCREEN = (byte*)$400
|
||||||
|
const nomodify byte GREEN = 5
|
||||||
|
const nomodify word OFFSET_SPRITE_PTRS = $3f8
|
||||||
|
const byte OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
|
||||||
|
const nomodify byte* SPRITE = (byte*)$2000
|
||||||
|
const nomodify byte* SPRITES_COLOR = (byte*)$d027
|
||||||
|
const nomodify byte* SPRITES_PTR = DEFAULT_SCREEN+OFFSET_SPRITE_PTRS
|
||||||
|
const nomodify byte* SPRITES_XPOS = (byte*)$d000
|
||||||
|
const nomodify byte* SPRITES_YPOS = (byte*)$d001
|
||||||
|
const nomodify struct MOS6569_VICII* VICII = (struct MOS6569_VICII*)$d000
|
||||||
|
void __start()
|
||||||
|
void byteboozer_decrunch(volatile byte* byteboozer_decrunch::crunched)
|
||||||
|
volatile byte* byteboozer_decrunch::crunched loadstore
|
||||||
|
void main()
|
||||||
|
byte~ main::$1
|
||||||
|
number~ main::toSpritePtr1_$0
|
||||||
|
word~ main::toSpritePtr1_$1
|
||||||
|
byte main::toSpritePtr1_return
|
||||||
|
byte main::toSpritePtr1_return#0
|
||||||
|
byte main::toSpritePtr1_return#1
|
||||||
|
byte main::toSpritePtr1_return#2
|
||||||
|
byte main::toSpritePtr1_return#3
|
||||||
|
byte* main::toSpritePtr1_sprite
|
||||||
|
byte* main::toSpritePtr1_sprite#0
|
||||||
|
byte* main::toSpritePtr1_sprite#1
|
||||||
|
|
||||||
|
Adding number conversion cast (unumber) 1 in *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1
|
||||||
|
Adding number conversion cast (unumber) $40 in main::toSpritePtr1_$0 = main::toSpritePtr1_$1 / $40
|
||||||
|
Adding number conversion cast (unumber) main::toSpritePtr1_$0 in main::toSpritePtr1_$0 = main::toSpritePtr1_$1 / (unumber)$40
|
||||||
|
Adding number conversion cast (unumber) 0 in SPRITES_PTR[0] = main::$1
|
||||||
|
Adding number conversion cast (unumber) 0 in SPRITES_COLOR[0] = GREEN
|
||||||
|
Adding number conversion cast (unumber) $15 in SPRITES_XPOS[0] = $15
|
||||||
|
Adding number conversion cast (unumber) 0 in SPRITES_XPOS[0] = ((unumber)) $15
|
||||||
|
Adding number conversion cast (unumber) $33 in SPRITES_YPOS[0] = $33
|
||||||
|
Adding number conversion cast (unumber) 0 in SPRITES_YPOS[0] = ((unumber)) $33
|
||||||
|
Successful SSA optimization PassNAddNumberTypeConversions
|
||||||
|
Inlining cast *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = (unumber)1
|
||||||
|
Inlining cast SPRITES_XPOS[(unumber)0] = (unumber)$15
|
||||||
|
Inlining cast SPRITES_YPOS[(unumber)0] = (unumber)$33
|
||||||
|
Successful SSA optimization Pass2InlineCast
|
||||||
|
Simplifying constant pointer cast (byte*) 53248
|
||||||
|
Simplifying constant pointer cast (byte*) 53249
|
||||||
|
Simplifying constant pointer cast (byte*) 53287
|
||||||
|
Simplifying constant pointer cast (struct MOS6569_VICII*) 53248
|
||||||
|
Simplifying constant pointer cast (byte*) 1024
|
||||||
|
Simplifying constant pointer cast (byte*) 8192
|
||||||
|
Simplifying constant integer cast 1
|
||||||
|
Simplifying constant integer cast $40
|
||||||
|
Simplifying constant integer cast 0
|
||||||
|
Simplifying constant integer cast 0
|
||||||
|
Simplifying constant integer cast $15
|
||||||
|
Simplifying constant integer cast 0
|
||||||
|
Simplifying constant integer cast $33
|
||||||
|
Simplifying constant integer cast 0
|
||||||
|
Successful SSA optimization PassNCastSimplification
|
||||||
|
Finalized unsigned number type (byte) 1
|
||||||
|
Finalized unsigned number type (byte) $40
|
||||||
|
Finalized unsigned number type (byte) 0
|
||||||
|
Finalized unsigned number type (byte) 0
|
||||||
|
Finalized unsigned number type (byte) $15
|
||||||
|
Finalized unsigned number type (byte) 0
|
||||||
|
Finalized unsigned number type (byte) $33
|
||||||
|
Finalized unsigned number type (byte) 0
|
||||||
|
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||||
|
Inferred type updated to word in main::toSpritePtr1_$0 = main::toSpritePtr1_$1 / $40
|
||||||
|
Alias main::toSpritePtr1_sprite#0 = main::toSpritePtr1_sprite#1
|
||||||
|
Alias main::toSpritePtr1_return#0 = main::toSpritePtr1_return#2 main::toSpritePtr1_return#1 main::toSpritePtr1_return#3 main::$1
|
||||||
|
Successful SSA optimization Pass2AliasElimination
|
||||||
|
Constant main::toSpritePtr1_sprite#0 = SPRITE
|
||||||
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
|
Constant main::toSpritePtr1_$1 = (word)main::toSpritePtr1_sprite#0
|
||||||
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
|
Simplifying expression containing zero SPRITES_PTR in [9] SPRITES_PTR[0] = main::toSpritePtr1_return#0
|
||||||
|
Simplifying expression containing zero SPRITES_COLOR in [10] SPRITES_COLOR[0] = GREEN
|
||||||
|
Simplifying expression containing zero SPRITES_XPOS in [11] SPRITES_XPOS[0] = $15
|
||||||
|
Simplifying expression containing zero SPRITES_YPOS in [12] SPRITES_YPOS[0] = $33
|
||||||
|
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||||
|
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
|
||||||
|
Constant right-side identified [5] main::toSpritePtr1_$0 = main::toSpritePtr1_$1 / $40
|
||||||
|
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||||
|
Constant main::toSpritePtr1_$0 = main::toSpritePtr1_$1/$40
|
||||||
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
|
Constant main::toSpritePtr1_return#0 = (byte)main::toSpritePtr1_$0
|
||||||
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
|
Constant inlined main::toSpritePtr1_sprite#0 = SPRITE
|
||||||
|
Constant inlined main::toSpritePtr1_$1 = (word)SPRITE
|
||||||
|
Constant inlined main::toSpritePtr1_$0 = (word)SPRITE/$40
|
||||||
|
Successful SSA optimization Pass2ConstantInlining
|
||||||
|
Adding NOP phi() at start of main::toSpritePtr1
|
||||||
|
Adding NOP phi() at start of main::toSpritePtr1_@return
|
||||||
|
CALL GRAPH
|
||||||
|
Calls in [main] to byteboozer_decrunch:1
|
||||||
|
|
||||||
|
Created 0 initial phi equivalence classes
|
||||||
|
Coalesced down to 0 phi equivalence classes
|
||||||
|
Culled Empty Block label main::toSpritePtr1_@return
|
||||||
|
Adding NOP phi() at start of main::toSpritePtr1
|
||||||
|
|
||||||
|
FINAL CONTROL FLOW GRAPH
|
||||||
|
|
||||||
|
void main()
|
||||||
|
main: scope:[main] from
|
||||||
|
[0] byteboozer_decrunch::crunched = CRUNCHED_SPRITE
|
||||||
|
[1] call byteboozer_decrunch
|
||||||
|
to:main::@2
|
||||||
|
main::@2: scope:[main] from main
|
||||||
|
[2] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1
|
||||||
|
to:main::toSpritePtr1
|
||||||
|
main::toSpritePtr1: scope:[main] from main::@2
|
||||||
|
[3] phi()
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main::toSpritePtr1
|
||||||
|
[4] *SPRITES_PTR = main::toSpritePtr1_return#0
|
||||||
|
[5] *SPRITES_COLOR = GREEN
|
||||||
|
[6] *SPRITES_XPOS = $15
|
||||||
|
[7] *SPRITES_YPOS = $33
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@1
|
||||||
|
[8] return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
void byteboozer_decrunch(volatile byte* byteboozer_decrunch::crunched)
|
||||||
|
byteboozer_decrunch: scope:[byteboozer_decrunch] from main
|
||||||
|
asm { ldycrunched ldxcrunched+1 jsrb2.Decrunch }
|
||||||
|
to:byteboozer_decrunch::@return
|
||||||
|
byteboozer_decrunch::@return: scope:[byteboozer_decrunch] from byteboozer_decrunch
|
||||||
|
[10] return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
|
||||||
|
VARIABLE REGISTER WEIGHTS
|
||||||
|
void byteboozer_decrunch(volatile byte* byteboozer_decrunch::crunched)
|
||||||
|
volatile byte* byteboozer_decrunch::crunched loadstore 2.0
|
||||||
|
void main()
|
||||||
|
byte main::toSpritePtr1_return
|
||||||
|
byte* main::toSpritePtr1_sprite
|
||||||
|
|
||||||
|
Initial phi equivalence classes
|
||||||
|
Added variable byteboozer_decrunch::crunched to live range equivalence class [ byteboozer_decrunch::crunched ]
|
||||||
|
Complete equivalence classes
|
||||||
|
[ byteboozer_decrunch::crunched ]
|
||||||
|
Allocated zp[2]:2 [ byteboozer_decrunch::crunched ]
|
||||||
|
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||||
|
Statement [0] byteboozer_decrunch::crunched = CRUNCHED_SPRITE [ byteboozer_decrunch::crunched ] ( [ byteboozer_decrunch::crunched ] { } ) always clobbers reg byte a
|
||||||
|
Statement [2] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1 [ ] ( [ ] { } ) always clobbers reg byte a
|
||||||
|
Statement [4] *SPRITES_PTR = main::toSpritePtr1_return#0 [ ] ( [ ] { } ) always clobbers reg byte a
|
||||||
|
Statement [5] *SPRITES_COLOR = GREEN [ ] ( [ ] { } ) always clobbers reg byte a
|
||||||
|
Statement [6] *SPRITES_XPOS = $15 [ ] ( [ ] { } ) always clobbers reg byte a
|
||||||
|
Statement [7] *SPRITES_YPOS = $33 [ ] ( [ ] { } ) always clobbers reg byte a
|
||||||
|
Statement asm { ldycrunched ldxcrunched+1 jsrb2.Decrunch } always clobbers reg byte a reg byte x reg byte y
|
||||||
|
Potential registers zp[2]:2 [ byteboozer_decrunch::crunched ] : zp[2]:2 ,
|
||||||
|
|
||||||
|
REGISTER UPLIFT SCOPES
|
||||||
|
Uplift Scope [byteboozer_decrunch] 2: zp[2]:2 [ byteboozer_decrunch::crunched ]
|
||||||
|
Uplift Scope [MOS6526_CIA]
|
||||||
|
Uplift Scope [MOS6569_VICII]
|
||||||
|
Uplift Scope [MOS6581_SID]
|
||||||
|
Uplift Scope [main]
|
||||||
|
Uplift Scope []
|
||||||
|
|
||||||
|
Uplifting [byteboozer_decrunch] best 114 combination zp[2]:2 [ byteboozer_decrunch::crunched ]
|
||||||
|
Uplifting [MOS6526_CIA] best 114 combination
|
||||||
|
Uplifting [MOS6569_VICII] best 114 combination
|
||||||
|
Uplifting [MOS6581_SID] best 114 combination
|
||||||
|
Uplifting [main] best 114 combination
|
||||||
|
Uplifting [] best 114 combination
|
||||||
|
|
||||||
|
ASSEMBLER BEFORE OPTIMIZATION
|
||||||
|
// File Comments
|
||||||
|
// Example showing how to crunch and decrunch part of a file using the KickAss Cruncher Plugins
|
||||||
|
// ByteBoozer example
|
||||||
|
// https://github.com/p-a/kickass-cruncher-plugins
|
||||||
|
// Upstart
|
||||||
|
// Commodore 64 PRG executable file - with the cruncher plugin enabled
|
||||||
|
.plugin "se.triad.kickass.CruncherPlugins"
|
||||||
|
.file [name="test-byteboozer.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
|
||||||
|
// The offset of the sprite pointers from the screen start address
|
||||||
|
.const OFFSET_SPRITE_PTRS = $3f8
|
||||||
|
.const GREEN = 5
|
||||||
|
.const OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
|
||||||
|
.label SPRITES_XPOS = $d000
|
||||||
|
.label SPRITES_YPOS = $d001
|
||||||
|
.label SPRITES_COLOR = $d027
|
||||||
|
// The VIC-II MOS 6567/6569
|
||||||
|
.label VICII = $d000
|
||||||
|
// Default address of screen character matrix
|
||||||
|
.label DEFAULT_SCREEN = $400
|
||||||
|
// Address to decrunch the sprite to
|
||||||
|
.label SPRITE = $2000
|
||||||
|
// The sprite pointers
|
||||||
|
.label SPRITES_PTR = DEFAULT_SCREEN+OFFSET_SPRITE_PTRS
|
||||||
|
.segment Code
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
.const toSpritePtr1_return = SPRITE/$40
|
||||||
|
// [0] byteboozer_decrunch::crunched = CRUNCHED_SPRITE -- pbuz1=pbuc1
|
||||||
|
lda #<CRUNCHED_SPRITE
|
||||||
|
sta.z byteboozer_decrunch.crunched
|
||||||
|
lda #>CRUNCHED_SPRITE
|
||||||
|
sta.z byteboozer_decrunch.crunched+1
|
||||||
|
// [1] call byteboozer_decrunch
|
||||||
|
// Decrunch sprite file into memory
|
||||||
|
jsr byteboozer_decrunch
|
||||||
|
jmp __b2
|
||||||
|
// main::@2
|
||||||
|
__b2:
|
||||||
|
// [2] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1 -- _deref_pbuc1=vbuc2
|
||||||
|
// Show the loaded sprite on screen
|
||||||
|
lda #1
|
||||||
|
sta VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE
|
||||||
|
// [3] phi from main::@2 to main::toSpritePtr1 [phi:main::@2->main::toSpritePtr1]
|
||||||
|
toSpritePtr1_from___b2:
|
||||||
|
jmp toSpritePtr1
|
||||||
|
// main::toSpritePtr1
|
||||||
|
toSpritePtr1:
|
||||||
|
jmp __b1
|
||||||
|
// main::@1
|
||||||
|
__b1:
|
||||||
|
// [4] *SPRITES_PTR = main::toSpritePtr1_return#0 -- _deref_pbuc1=vbuc2
|
||||||
|
lda #toSpritePtr1_return
|
||||||
|
sta SPRITES_PTR
|
||||||
|
// [5] *SPRITES_COLOR = GREEN -- _deref_pbuc1=vbuc2
|
||||||
|
lda #GREEN
|
||||||
|
sta SPRITES_COLOR
|
||||||
|
// [6] *SPRITES_XPOS = $15 -- _deref_pbuc1=vbuc2
|
||||||
|
lda #$15
|
||||||
|
sta SPRITES_XPOS
|
||||||
|
// [7] *SPRITES_YPOS = $33 -- _deref_pbuc1=vbuc2
|
||||||
|
lda #$33
|
||||||
|
sta SPRITES_YPOS
|
||||||
|
jmp __breturn
|
||||||
|
// main::@return
|
||||||
|
__breturn:
|
||||||
|
// [8] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// byteboozer_decrunch
|
||||||
|
// Decrunch crunched data using ByteBoozer
|
||||||
|
// - crunched: Pointer to the start of the crunched data
|
||||||
|
// byteboozer_decrunch(byte* zp(2) crunched)
|
||||||
|
byteboozer_decrunch: {
|
||||||
|
.label crunched = 2
|
||||||
|
// asm { ldycrunched ldxcrunched+1 jsrb2.Decrunch }
|
||||||
|
ldy crunched
|
||||||
|
ldx crunched+1
|
||||||
|
jsr b2.Decrunch
|
||||||
|
jmp __breturn
|
||||||
|
// byteboozer_decrunch::@return
|
||||||
|
__breturn:
|
||||||
|
// [10] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
.segment Data
|
||||||
|
// The byteboozer decruncher
|
||||||
|
BYTEBOOZER:
|
||||||
|
.const B2_ZP_BASE = $fc
|
||||||
|
#import "byteboozer_decrunch.asm"
|
||||||
|
|
||||||
|
// Array with crunched data created using inline kickasm
|
||||||
|
CRUNCHED_SPRITE:
|
||||||
|
.modify B2() {
|
||||||
|
.pc = SPRITE
|
||||||
|
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||||
|
.for (var y=0; y<21; y++)
|
||||||
|
.for (var x=0;x<3; x++)
|
||||||
|
.byte pic.getSinglecolorByte(x,y)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ASSEMBLER OPTIMIZATIONS
|
||||||
|
Removing instruction jmp __b2
|
||||||
|
Removing instruction jmp toSpritePtr1
|
||||||
|
Removing instruction jmp __b1
|
||||||
|
Removing instruction jmp __breturn
|
||||||
|
Removing instruction jmp __breturn
|
||||||
|
Succesful ASM optimization Pass5NextJumpElimination
|
||||||
|
Removing instruction toSpritePtr1_from___b2:
|
||||||
|
Removing instruction toSpritePtr1:
|
||||||
|
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||||
|
Removing instruction __b2:
|
||||||
|
Removing instruction __b1:
|
||||||
|
Removing instruction __breturn:
|
||||||
|
Removing instruction __breturn:
|
||||||
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||||
|
|
||||||
|
FINAL SYMBOL TABLE
|
||||||
|
const byte* BYTEBOOZER[] = kickasm {{ .const B2_ZP_BASE = $fc
|
||||||
|
#import "byteboozer_decrunch.asm"
|
||||||
|
}}
|
||||||
|
const byte* CRUNCHED_SPRITE[] = kickasm( uses SPRITE) {{ .modify B2() {
|
||||||
|
.pc = SPRITE
|
||||||
|
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||||
|
.for (var y=0; y<21; y++)
|
||||||
|
.for (var x=0;x<3; x++)
|
||||||
|
.byte pic.getSinglecolorByte(x,y)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
const nomodify byte* DEFAULT_SCREEN = (byte*) 1024
|
||||||
|
const nomodify byte GREEN = 5
|
||||||
|
const nomodify word OFFSET_SPRITE_PTRS = $3f8
|
||||||
|
const byte OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
|
||||||
|
const nomodify byte* SPRITE = (byte*) 8192
|
||||||
|
const nomodify byte* SPRITES_COLOR = (byte*) 53287
|
||||||
|
const nomodify byte* SPRITES_PTR = DEFAULT_SCREEN+OFFSET_SPRITE_PTRS
|
||||||
|
const nomodify byte* SPRITES_XPOS = (byte*) 53248
|
||||||
|
const nomodify byte* SPRITES_YPOS = (byte*) 53249
|
||||||
|
const nomodify struct MOS6569_VICII* VICII = (struct MOS6569_VICII*) 53248
|
||||||
|
void byteboozer_decrunch(volatile byte* byteboozer_decrunch::crunched)
|
||||||
|
volatile byte* byteboozer_decrunch::crunched loadstore zp[2]:2 2.0
|
||||||
|
void main()
|
||||||
|
byte main::toSpritePtr1_return
|
||||||
|
const byte main::toSpritePtr1_return#0 toSpritePtr1_return = (byte)(word)SPRITE/$40
|
||||||
|
byte* main::toSpritePtr1_sprite
|
||||||
|
|
||||||
|
zp[2]:2 [ byteboozer_decrunch::crunched ]
|
||||||
|
|
||||||
|
|
||||||
|
FINAL ASSEMBLER
|
||||||
|
Score: 72
|
||||||
|
|
||||||
|
// File Comments
|
||||||
|
// Example showing how to crunch and decrunch part of a file using the KickAss Cruncher Plugins
|
||||||
|
// ByteBoozer example
|
||||||
|
// https://github.com/p-a/kickass-cruncher-plugins
|
||||||
|
// Upstart
|
||||||
|
// Commodore 64 PRG executable file - with the cruncher plugin enabled
|
||||||
|
.plugin "se.triad.kickass.CruncherPlugins"
|
||||||
|
.file [name="test-byteboozer.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
|
||||||
|
// The offset of the sprite pointers from the screen start address
|
||||||
|
.const OFFSET_SPRITE_PTRS = $3f8
|
||||||
|
.const GREEN = 5
|
||||||
|
.const OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
|
||||||
|
.label SPRITES_XPOS = $d000
|
||||||
|
.label SPRITES_YPOS = $d001
|
||||||
|
.label SPRITES_COLOR = $d027
|
||||||
|
// The VIC-II MOS 6567/6569
|
||||||
|
.label VICII = $d000
|
||||||
|
// Default address of screen character matrix
|
||||||
|
.label DEFAULT_SCREEN = $400
|
||||||
|
// Address to decrunch the sprite to
|
||||||
|
.label SPRITE = $2000
|
||||||
|
// The sprite pointers
|
||||||
|
.label SPRITES_PTR = DEFAULT_SCREEN+OFFSET_SPRITE_PTRS
|
||||||
|
.segment Code
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
.const toSpritePtr1_return = SPRITE/$40
|
||||||
|
// byteboozer_decrunch(CRUNCHED_SPRITE)
|
||||||
|
// [0] byteboozer_decrunch::crunched = CRUNCHED_SPRITE -- pbuz1=pbuc1
|
||||||
|
lda #<CRUNCHED_SPRITE
|
||||||
|
sta.z byteboozer_decrunch.crunched
|
||||||
|
lda #>CRUNCHED_SPRITE
|
||||||
|
sta.z byteboozer_decrunch.crunched+1
|
||||||
|
// [1] call byteboozer_decrunch
|
||||||
|
// Decrunch sprite file into memory
|
||||||
|
jsr byteboozer_decrunch
|
||||||
|
// main::@2
|
||||||
|
// VICII->SPRITES_ENABLE = %00000001
|
||||||
|
// [2] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1 -- _deref_pbuc1=vbuc2
|
||||||
|
// Show the loaded sprite on screen
|
||||||
|
lda #1
|
||||||
|
sta VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE
|
||||||
|
// [3] phi from main::@2 to main::toSpritePtr1 [phi:main::@2->main::toSpritePtr1]
|
||||||
|
// main::toSpritePtr1
|
||||||
|
// main::@1
|
||||||
|
// SPRITES_PTR[0] = toSpritePtr(SPRITE)
|
||||||
|
// [4] *SPRITES_PTR = main::toSpritePtr1_return#0 -- _deref_pbuc1=vbuc2
|
||||||
|
lda #toSpritePtr1_return
|
||||||
|
sta SPRITES_PTR
|
||||||
|
// SPRITES_COLOR[0] = GREEN
|
||||||
|
// [5] *SPRITES_COLOR = GREEN -- _deref_pbuc1=vbuc2
|
||||||
|
lda #GREEN
|
||||||
|
sta SPRITES_COLOR
|
||||||
|
// SPRITES_XPOS[0] = 0x15
|
||||||
|
// [6] *SPRITES_XPOS = $15 -- _deref_pbuc1=vbuc2
|
||||||
|
lda #$15
|
||||||
|
sta SPRITES_XPOS
|
||||||
|
// SPRITES_YPOS[0] = 0x33
|
||||||
|
// [7] *SPRITES_YPOS = $33 -- _deref_pbuc1=vbuc2
|
||||||
|
lda #$33
|
||||||
|
sta SPRITES_YPOS
|
||||||
|
// main::@return
|
||||||
|
// }
|
||||||
|
// [8] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// byteboozer_decrunch
|
||||||
|
// Decrunch crunched data using ByteBoozer
|
||||||
|
// - crunched: Pointer to the start of the crunched data
|
||||||
|
// byteboozer_decrunch(byte* zp(2) crunched)
|
||||||
|
byteboozer_decrunch: {
|
||||||
|
.label crunched = 2
|
||||||
|
// asm
|
||||||
|
// asm { ldycrunched ldxcrunched+1 jsrb2.Decrunch }
|
||||||
|
ldy crunched
|
||||||
|
ldx crunched+1
|
||||||
|
jsr b2.Decrunch
|
||||||
|
// byteboozer_decrunch::@return
|
||||||
|
// }
|
||||||
|
// [10] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
.segment Data
|
||||||
|
// The byteboozer decruncher
|
||||||
|
BYTEBOOZER:
|
||||||
|
.const B2_ZP_BASE = $fc
|
||||||
|
#import "byteboozer_decrunch.asm"
|
||||||
|
|
||||||
|
// Array with crunched data created using inline kickasm
|
||||||
|
CRUNCHED_SPRITE:
|
||||||
|
.modify B2() {
|
||||||
|
.pc = SPRITE
|
||||||
|
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||||
|
.for (var y=0; y<21; y++)
|
||||||
|
.for (var x=0;x<3; x++)
|
||||||
|
.byte pic.getSinglecolorByte(x,y)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
const byte* BYTEBOOZER[] = kickasm {{ .const B2_ZP_BASE = $fc
|
||||||
|
#import "byteboozer_decrunch.asm"
|
||||||
|
}}
|
||||||
|
const byte* CRUNCHED_SPRITE[] = kickasm( uses SPRITE) {{ .modify B2() {
|
||||||
|
.pc = SPRITE
|
||||||
|
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||||
|
.for (var y=0; y<21; y++)
|
||||||
|
.for (var x=0;x<3; x++)
|
||||||
|
.byte pic.getSinglecolorByte(x,y)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
const nomodify byte* DEFAULT_SCREEN = (byte*) 1024
|
||||||
|
const nomodify byte GREEN = 5
|
||||||
|
const nomodify word OFFSET_SPRITE_PTRS = $3f8
|
||||||
|
const byte OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
|
||||||
|
const nomodify byte* SPRITE = (byte*) 8192
|
||||||
|
const nomodify byte* SPRITES_COLOR = (byte*) 53287
|
||||||
|
const nomodify byte* SPRITES_PTR = DEFAULT_SCREEN+OFFSET_SPRITE_PTRS
|
||||||
|
const nomodify byte* SPRITES_XPOS = (byte*) 53248
|
||||||
|
const nomodify byte* SPRITES_YPOS = (byte*) 53249
|
||||||
|
const nomodify struct MOS6569_VICII* VICII = (struct MOS6569_VICII*) 53248
|
||||||
|
void byteboozer_decrunch(volatile byte* byteboozer_decrunch::crunched)
|
||||||
|
volatile byte* byteboozer_decrunch::crunched loadstore zp[2]:2 2.0
|
||||||
|
void main()
|
||||||
|
byte main::toSpritePtr1_return
|
||||||
|
const byte main::toSpritePtr1_return#0 toSpritePtr1_return = (byte)(word)SPRITE/$40
|
||||||
|
byte* main::toSpritePtr1_sprite
|
||||||
|
|
||||||
|
zp[2]:2 [ byteboozer_decrunch::crunched ]
|
|
@ -0,0 +1,71 @@
|
||||||
|
// Example showing how to crunch and decrunch part of a file using the KickAss Cruncher Plugins
|
||||||
|
// Exomizer Example
|
||||||
|
// https://github.com/p-a/kickass-cruncher-plugins
|
||||||
|
// Commodore 64 PRG executable file - with the cruncher plugin enabled
|
||||||
|
.plugin "se.triad.kickass.CruncherPlugins"
|
||||||
|
.file [name="test-exomizer.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)
|
||||||
|
// The offset of the sprite pointers from the screen start address
|
||||||
|
.const OFFSET_SPRITE_PTRS = $3f8
|
||||||
|
.const GREEN = 5
|
||||||
|
.const OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
|
||||||
|
.label SPRITES_XPOS = $d000
|
||||||
|
.label SPRITES_YPOS = $d001
|
||||||
|
.label SPRITES_COLOR = $d027
|
||||||
|
// The VIC-II MOS 6567/6569
|
||||||
|
.label VICII = $d000
|
||||||
|
// Default address of screen character matrix
|
||||||
|
.label DEFAULT_SCREEN = $400
|
||||||
|
// Address to decrunch the sprite to
|
||||||
|
.label SPRITE = $2000
|
||||||
|
.label SPRITES_PTR = DEFAULT_SCREEN+OFFSET_SPRITE_PTRS
|
||||||
|
.segment Code
|
||||||
|
main: {
|
||||||
|
.const toSpritePtr1_return = SPRITE/$40
|
||||||
|
// kickasm
|
||||||
|
// Decrunch sprite file into memory
|
||||||
|
:EXO_DECRUNCH(CRUNCHED_SPRITE_END)
|
||||||
|
|
||||||
|
// VICII->SPRITES_ENABLE = %00000001
|
||||||
|
// Show the loaded sprite on screen
|
||||||
|
lda #1
|
||||||
|
sta VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE
|
||||||
|
// SPRITES_PTR[0] = toSpritePtr(SPRITE)
|
||||||
|
lda #toSpritePtr1_return
|
||||||
|
sta SPRITES_PTR
|
||||||
|
// SPRITES_COLOR[0] = GREEN
|
||||||
|
lda #GREEN
|
||||||
|
sta SPRITES_COLOR
|
||||||
|
// SPRITES_XPOS[0] = 0x15
|
||||||
|
lda #$15
|
||||||
|
sta SPRITES_XPOS
|
||||||
|
// SPRITES_YPOS[0] = 0x33
|
||||||
|
lda #$33
|
||||||
|
sta SPRITES_YPOS
|
||||||
|
// }
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
.segment Data
|
||||||
|
// The exomizer decruncher
|
||||||
|
EXOMIZER:
|
||||||
|
.const EXO_LITERAL_SEQUENCES_USED = true
|
||||||
|
.const EXO_ZP_BASE = $02
|
||||||
|
.const EXO_DECRUNCH_TABLE = $0200
|
||||||
|
#import "exomizer_decrunch.asm"
|
||||||
|
|
||||||
|
// Array with crunched data created using inline kickasm
|
||||||
|
CRUNCHED_SPRITE:
|
||||||
|
.modify MemExomizer(false, true) {
|
||||||
|
.pc = SPRITE
|
||||||
|
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||||
|
.for (var y=0; y<21; y++)
|
||||||
|
.for (var x=0;x<3; x++)
|
||||||
|
.byte pic.getSinglecolorByte(x,y)
|
||||||
|
}
|
||||||
|
CRUNCHED_SPRITE_END:
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
|
||||||
|
void main()
|
||||||
|
main: scope:[main] from
|
||||||
|
kickasm() {{ :EXO_DECRUNCH(CRUNCHED_SPRITE_END)
|
||||||
|
}}
|
||||||
|
[1] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1
|
||||||
|
to:main::toSpritePtr1
|
||||||
|
main::toSpritePtr1: scope:[main] from main
|
||||||
|
[2] phi()
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main::toSpritePtr1
|
||||||
|
[3] *SPRITES_PTR = main::toSpritePtr1_return#0
|
||||||
|
[4] *SPRITES_COLOR = GREEN
|
||||||
|
[5] *SPRITES_XPOS = $15
|
||||||
|
[6] *SPRITES_YPOS = $33
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@1
|
||||||
|
[7] return
|
||||||
|
to:@return
|
|
@ -0,0 +1,432 @@
|
||||||
|
Loading link script "crunching.ld"
|
||||||
|
Inlined call vicSelectGfxBank::$0 = call toDd00 vicSelectGfxBank::gfx
|
||||||
|
Inlined call main::$0 = call toSpritePtr SPRITE
|
||||||
|
|
||||||
|
CONTROL FLOW GRAPH SSA
|
||||||
|
|
||||||
|
void main()
|
||||||
|
main: scope:[main] from __start
|
||||||
|
kickasm() {{ :EXO_DECRUNCH(CRUNCHED_SPRITE_END)
|
||||||
|
}}
|
||||||
|
*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1
|
||||||
|
main::toSpritePtr1_sprite#0 = SPRITE
|
||||||
|
to:main::toSpritePtr1
|
||||||
|
main::toSpritePtr1: scope:[main] from main
|
||||||
|
main::toSpritePtr1_sprite#1 = phi( main/main::toSpritePtr1_sprite#0 )
|
||||||
|
main::toSpritePtr1_$1 = (word)main::toSpritePtr1_sprite#1
|
||||||
|
main::toSpritePtr1_$0 = main::toSpritePtr1_$1 / $40
|
||||||
|
main::toSpritePtr1_return#0 = (byte)main::toSpritePtr1_$0
|
||||||
|
to:main::toSpritePtr1_@return
|
||||||
|
main::toSpritePtr1_@return: scope:[main] from main::toSpritePtr1
|
||||||
|
main::toSpritePtr1_return#2 = phi( main::toSpritePtr1/main::toSpritePtr1_return#0 )
|
||||||
|
main::toSpritePtr1_return#1 = main::toSpritePtr1_return#2
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main::toSpritePtr1_@return
|
||||||
|
main::toSpritePtr1_return#3 = phi( main::toSpritePtr1_@return/main::toSpritePtr1_return#1 )
|
||||||
|
main::$0 = main::toSpritePtr1_return#3
|
||||||
|
SPRITES_PTR[0] = main::$0
|
||||||
|
SPRITES_COLOR[0] = GREEN
|
||||||
|
SPRITES_XPOS[0] = $15
|
||||||
|
SPRITES_YPOS[0] = $33
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@1
|
||||||
|
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
|
||||||
|
const byte* CRUNCHED_SPRITE[] = kickasm( uses SPRITE) {{ .modify MemExomizer(false, true) {
|
||||||
|
.pc = SPRITE
|
||||||
|
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||||
|
.for (var y=0; y<21; y++)
|
||||||
|
.for (var x=0;x<3; x++)
|
||||||
|
.byte pic.getSinglecolorByte(x,y)
|
||||||
|
}
|
||||||
|
CRUNCHED_SPRITE_END:
|
||||||
|
}}
|
||||||
|
const nomodify byte* DEFAULT_SCREEN = (byte*)$400
|
||||||
|
const byte* EXOMIZER[] = kickasm {{ .const EXO_LITERAL_SEQUENCES_USED = true
|
||||||
|
.const EXO_ZP_BASE = $02
|
||||||
|
.const EXO_DECRUNCH_TABLE = $0200
|
||||||
|
#import "exomizer_decrunch.asm"
|
||||||
|
}}
|
||||||
|
const nomodify byte GREEN = 5
|
||||||
|
const nomodify word OFFSET_SPRITE_PTRS = $3f8
|
||||||
|
const byte OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
|
||||||
|
const nomodify byte* SPRITE = (byte*)$2000
|
||||||
|
const nomodify byte* SPRITES_COLOR = (byte*)$d027
|
||||||
|
const nomodify byte* SPRITES_PTR = DEFAULT_SCREEN+OFFSET_SPRITE_PTRS
|
||||||
|
const nomodify byte* SPRITES_XPOS = (byte*)$d000
|
||||||
|
const nomodify byte* SPRITES_YPOS = (byte*)$d001
|
||||||
|
const nomodify struct MOS6569_VICII* VICII = (struct MOS6569_VICII*)$d000
|
||||||
|
void __start()
|
||||||
|
void main()
|
||||||
|
byte~ main::$0
|
||||||
|
number~ main::toSpritePtr1_$0
|
||||||
|
word~ main::toSpritePtr1_$1
|
||||||
|
byte main::toSpritePtr1_return
|
||||||
|
byte main::toSpritePtr1_return#0
|
||||||
|
byte main::toSpritePtr1_return#1
|
||||||
|
byte main::toSpritePtr1_return#2
|
||||||
|
byte main::toSpritePtr1_return#3
|
||||||
|
byte* main::toSpritePtr1_sprite
|
||||||
|
byte* main::toSpritePtr1_sprite#0
|
||||||
|
byte* main::toSpritePtr1_sprite#1
|
||||||
|
|
||||||
|
Adding number conversion cast (unumber) 1 in *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1
|
||||||
|
Adding number conversion cast (unumber) $40 in main::toSpritePtr1_$0 = main::toSpritePtr1_$1 / $40
|
||||||
|
Adding number conversion cast (unumber) main::toSpritePtr1_$0 in main::toSpritePtr1_$0 = main::toSpritePtr1_$1 / (unumber)$40
|
||||||
|
Adding number conversion cast (unumber) 0 in SPRITES_PTR[0] = main::$0
|
||||||
|
Adding number conversion cast (unumber) 0 in SPRITES_COLOR[0] = GREEN
|
||||||
|
Adding number conversion cast (unumber) $15 in SPRITES_XPOS[0] = $15
|
||||||
|
Adding number conversion cast (unumber) 0 in SPRITES_XPOS[0] = ((unumber)) $15
|
||||||
|
Adding number conversion cast (unumber) $33 in SPRITES_YPOS[0] = $33
|
||||||
|
Adding number conversion cast (unumber) 0 in SPRITES_YPOS[0] = ((unumber)) $33
|
||||||
|
Successful SSA optimization PassNAddNumberTypeConversions
|
||||||
|
Inlining cast *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = (unumber)1
|
||||||
|
Inlining cast SPRITES_XPOS[(unumber)0] = (unumber)$15
|
||||||
|
Inlining cast SPRITES_YPOS[(unumber)0] = (unumber)$33
|
||||||
|
Successful SSA optimization Pass2InlineCast
|
||||||
|
Simplifying constant pointer cast (byte*) 53248
|
||||||
|
Simplifying constant pointer cast (byte*) 53249
|
||||||
|
Simplifying constant pointer cast (byte*) 53287
|
||||||
|
Simplifying constant pointer cast (struct MOS6569_VICII*) 53248
|
||||||
|
Simplifying constant pointer cast (byte*) 1024
|
||||||
|
Simplifying constant pointer cast (byte*) 8192
|
||||||
|
Simplifying constant integer cast 1
|
||||||
|
Simplifying constant integer cast $40
|
||||||
|
Simplifying constant integer cast 0
|
||||||
|
Simplifying constant integer cast 0
|
||||||
|
Simplifying constant integer cast $15
|
||||||
|
Simplifying constant integer cast 0
|
||||||
|
Simplifying constant integer cast $33
|
||||||
|
Simplifying constant integer cast 0
|
||||||
|
Successful SSA optimization PassNCastSimplification
|
||||||
|
Finalized unsigned number type (byte) 1
|
||||||
|
Finalized unsigned number type (byte) $40
|
||||||
|
Finalized unsigned number type (byte) 0
|
||||||
|
Finalized unsigned number type (byte) 0
|
||||||
|
Finalized unsigned number type (byte) $15
|
||||||
|
Finalized unsigned number type (byte) 0
|
||||||
|
Finalized unsigned number type (byte) $33
|
||||||
|
Finalized unsigned number type (byte) 0
|
||||||
|
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||||
|
Inferred type updated to word in main::toSpritePtr1_$0 = main::toSpritePtr1_$1 / $40
|
||||||
|
Alias main::toSpritePtr1_sprite#0 = main::toSpritePtr1_sprite#1
|
||||||
|
Alias main::toSpritePtr1_return#0 = main::toSpritePtr1_return#2 main::toSpritePtr1_return#1 main::toSpritePtr1_return#3 main::$0
|
||||||
|
Successful SSA optimization Pass2AliasElimination
|
||||||
|
Constant main::toSpritePtr1_sprite#0 = SPRITE
|
||||||
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
|
Constant main::toSpritePtr1_$1 = (word)main::toSpritePtr1_sprite#0
|
||||||
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
|
Simplifying expression containing zero SPRITES_PTR in [6] SPRITES_PTR[0] = main::toSpritePtr1_return#0
|
||||||
|
Simplifying expression containing zero SPRITES_COLOR in [7] SPRITES_COLOR[0] = GREEN
|
||||||
|
Simplifying expression containing zero SPRITES_XPOS in [8] SPRITES_XPOS[0] = $15
|
||||||
|
Simplifying expression containing zero SPRITES_YPOS in [9] SPRITES_YPOS[0] = $33
|
||||||
|
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||||
|
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
|
||||||
|
Constant right-side identified [2] main::toSpritePtr1_$0 = main::toSpritePtr1_$1 / $40
|
||||||
|
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||||
|
Constant main::toSpritePtr1_$0 = main::toSpritePtr1_$1/$40
|
||||||
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
|
Constant main::toSpritePtr1_return#0 = (byte)main::toSpritePtr1_$0
|
||||||
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
|
Constant inlined main::toSpritePtr1_sprite#0 = SPRITE
|
||||||
|
Constant inlined main::toSpritePtr1_$1 = (word)SPRITE
|
||||||
|
Constant inlined main::toSpritePtr1_$0 = (word)SPRITE/$40
|
||||||
|
Successful SSA optimization Pass2ConstantInlining
|
||||||
|
Adding NOP phi() at start of main::toSpritePtr1
|
||||||
|
Adding NOP phi() at start of main::toSpritePtr1_@return
|
||||||
|
CALL GRAPH
|
||||||
|
|
||||||
|
Created 0 initial phi equivalence classes
|
||||||
|
Coalesced down to 0 phi equivalence classes
|
||||||
|
Culled Empty Block label main::toSpritePtr1_@return
|
||||||
|
Adding NOP phi() at start of main::toSpritePtr1
|
||||||
|
|
||||||
|
FINAL CONTROL FLOW GRAPH
|
||||||
|
|
||||||
|
void main()
|
||||||
|
main: scope:[main] from
|
||||||
|
kickasm() {{ :EXO_DECRUNCH(CRUNCHED_SPRITE_END)
|
||||||
|
}}
|
||||||
|
[1] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1
|
||||||
|
to:main::toSpritePtr1
|
||||||
|
main::toSpritePtr1: scope:[main] from main
|
||||||
|
[2] phi()
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main::toSpritePtr1
|
||||||
|
[3] *SPRITES_PTR = main::toSpritePtr1_return#0
|
||||||
|
[4] *SPRITES_COLOR = GREEN
|
||||||
|
[5] *SPRITES_XPOS = $15
|
||||||
|
[6] *SPRITES_YPOS = $33
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@1
|
||||||
|
[7] return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
|
||||||
|
VARIABLE REGISTER WEIGHTS
|
||||||
|
void main()
|
||||||
|
byte main::toSpritePtr1_return
|
||||||
|
byte* main::toSpritePtr1_sprite
|
||||||
|
|
||||||
|
Initial phi equivalence classes
|
||||||
|
Complete equivalence classes
|
||||||
|
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||||
|
Statement [1] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1 [ ] ( [ ] { } ) always clobbers reg byte a
|
||||||
|
Statement [3] *SPRITES_PTR = main::toSpritePtr1_return#0 [ ] ( [ ] { } ) always clobbers reg byte a
|
||||||
|
Statement [4] *SPRITES_COLOR = GREEN [ ] ( [ ] { } ) always clobbers reg byte a
|
||||||
|
Statement [5] *SPRITES_XPOS = $15 [ ] ( [ ] { } ) always clobbers reg byte a
|
||||||
|
Statement [6] *SPRITES_YPOS = $33 [ ] ( [ ] { } ) always clobbers reg byte a
|
||||||
|
|
||||||
|
REGISTER UPLIFT SCOPES
|
||||||
|
Uplift Scope [MOS6526_CIA]
|
||||||
|
Uplift Scope [MOS6569_VICII]
|
||||||
|
Uplift Scope [MOS6581_SID]
|
||||||
|
Uplift Scope [main]
|
||||||
|
Uplift Scope []
|
||||||
|
|
||||||
|
Uplifting [MOS6526_CIA] best 328 combination
|
||||||
|
Uplifting [MOS6569_VICII] best 328 combination
|
||||||
|
Uplifting [MOS6581_SID] best 328 combination
|
||||||
|
Uplifting [main] best 328 combination
|
||||||
|
Uplifting [] best 328 combination
|
||||||
|
|
||||||
|
ASSEMBLER BEFORE OPTIMIZATION
|
||||||
|
// File Comments
|
||||||
|
// Example showing how to crunch and decrunch part of a file using the KickAss Cruncher Plugins
|
||||||
|
// Exomizer Example
|
||||||
|
// https://github.com/p-a/kickass-cruncher-plugins
|
||||||
|
// Upstart
|
||||||
|
// Commodore 64 PRG executable file - with the cruncher plugin enabled
|
||||||
|
.plugin "se.triad.kickass.CruncherPlugins"
|
||||||
|
.file [name="test-exomizer.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
|
||||||
|
// The offset of the sprite pointers from the screen start address
|
||||||
|
.const OFFSET_SPRITE_PTRS = $3f8
|
||||||
|
.const GREEN = 5
|
||||||
|
.const OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
|
||||||
|
.label SPRITES_XPOS = $d000
|
||||||
|
.label SPRITES_YPOS = $d001
|
||||||
|
.label SPRITES_COLOR = $d027
|
||||||
|
// The VIC-II MOS 6567/6569
|
||||||
|
.label VICII = $d000
|
||||||
|
// Default address of screen character matrix
|
||||||
|
.label DEFAULT_SCREEN = $400
|
||||||
|
// Address to decrunch the sprite to
|
||||||
|
.label SPRITE = $2000
|
||||||
|
.label SPRITES_PTR = DEFAULT_SCREEN+OFFSET_SPRITE_PTRS
|
||||||
|
.segment Code
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
.const toSpritePtr1_return = SPRITE/$40
|
||||||
|
// kickasm() {{ :EXO_DECRUNCH(CRUNCHED_SPRITE_END) }}
|
||||||
|
// Decrunch sprite file into memory
|
||||||
|
:EXO_DECRUNCH(CRUNCHED_SPRITE_END)
|
||||||
|
|
||||||
|
// [1] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1 -- _deref_pbuc1=vbuc2
|
||||||
|
// Show the loaded sprite on screen
|
||||||
|
lda #1
|
||||||
|
sta VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE
|
||||||
|
// [2] phi from main to main::toSpritePtr1 [phi:main->main::toSpritePtr1]
|
||||||
|
toSpritePtr1_from_main:
|
||||||
|
jmp toSpritePtr1
|
||||||
|
// main::toSpritePtr1
|
||||||
|
toSpritePtr1:
|
||||||
|
jmp __b1
|
||||||
|
// main::@1
|
||||||
|
__b1:
|
||||||
|
// [3] *SPRITES_PTR = main::toSpritePtr1_return#0 -- _deref_pbuc1=vbuc2
|
||||||
|
lda #toSpritePtr1_return
|
||||||
|
sta SPRITES_PTR
|
||||||
|
// [4] *SPRITES_COLOR = GREEN -- _deref_pbuc1=vbuc2
|
||||||
|
lda #GREEN
|
||||||
|
sta SPRITES_COLOR
|
||||||
|
// [5] *SPRITES_XPOS = $15 -- _deref_pbuc1=vbuc2
|
||||||
|
lda #$15
|
||||||
|
sta SPRITES_XPOS
|
||||||
|
// [6] *SPRITES_YPOS = $33 -- _deref_pbuc1=vbuc2
|
||||||
|
lda #$33
|
||||||
|
sta SPRITES_YPOS
|
||||||
|
jmp __breturn
|
||||||
|
// main::@return
|
||||||
|
__breturn:
|
||||||
|
// [7] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
.segment Data
|
||||||
|
// The exomizer decruncher
|
||||||
|
EXOMIZER:
|
||||||
|
.const EXO_LITERAL_SEQUENCES_USED = true
|
||||||
|
.const EXO_ZP_BASE = $02
|
||||||
|
.const EXO_DECRUNCH_TABLE = $0200
|
||||||
|
#import "exomizer_decrunch.asm"
|
||||||
|
|
||||||
|
// Array with crunched data created using inline kickasm
|
||||||
|
CRUNCHED_SPRITE:
|
||||||
|
.modify MemExomizer(false, true) {
|
||||||
|
.pc = SPRITE
|
||||||
|
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||||
|
.for (var y=0; y<21; y++)
|
||||||
|
.for (var x=0;x<3; x++)
|
||||||
|
.byte pic.getSinglecolorByte(x,y)
|
||||||
|
}
|
||||||
|
CRUNCHED_SPRITE_END:
|
||||||
|
|
||||||
|
|
||||||
|
ASSEMBLER OPTIMIZATIONS
|
||||||
|
Removing instruction jmp toSpritePtr1
|
||||||
|
Removing instruction jmp __b1
|
||||||
|
Removing instruction jmp __breturn
|
||||||
|
Succesful ASM optimization Pass5NextJumpElimination
|
||||||
|
Removing instruction toSpritePtr1_from_main:
|
||||||
|
Removing instruction toSpritePtr1:
|
||||||
|
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||||
|
Removing instruction __b1:
|
||||||
|
Removing instruction __breturn:
|
||||||
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||||
|
|
||||||
|
FINAL SYMBOL TABLE
|
||||||
|
const byte* CRUNCHED_SPRITE[] = kickasm( uses SPRITE) {{ .modify MemExomizer(false, true) {
|
||||||
|
.pc = SPRITE
|
||||||
|
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||||
|
.for (var y=0; y<21; y++)
|
||||||
|
.for (var x=0;x<3; x++)
|
||||||
|
.byte pic.getSinglecolorByte(x,y)
|
||||||
|
}
|
||||||
|
CRUNCHED_SPRITE_END:
|
||||||
|
}}
|
||||||
|
const nomodify byte* DEFAULT_SCREEN = (byte*) 1024
|
||||||
|
const byte* EXOMIZER[] = kickasm {{ .const EXO_LITERAL_SEQUENCES_USED = true
|
||||||
|
.const EXO_ZP_BASE = $02
|
||||||
|
.const EXO_DECRUNCH_TABLE = $0200
|
||||||
|
#import "exomizer_decrunch.asm"
|
||||||
|
}}
|
||||||
|
const nomodify byte GREEN = 5
|
||||||
|
const nomodify word OFFSET_SPRITE_PTRS = $3f8
|
||||||
|
const byte OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
|
||||||
|
const nomodify byte* SPRITE = (byte*) 8192
|
||||||
|
const nomodify byte* SPRITES_COLOR = (byte*) 53287
|
||||||
|
const nomodify byte* SPRITES_PTR = DEFAULT_SCREEN+OFFSET_SPRITE_PTRS
|
||||||
|
const nomodify byte* SPRITES_XPOS = (byte*) 53248
|
||||||
|
const nomodify byte* SPRITES_YPOS = (byte*) 53249
|
||||||
|
const nomodify struct MOS6569_VICII* VICII = (struct MOS6569_VICII*) 53248
|
||||||
|
void main()
|
||||||
|
byte main::toSpritePtr1_return
|
||||||
|
const byte main::toSpritePtr1_return#0 toSpritePtr1_return = (byte)(word)SPRITE/$40
|
||||||
|
byte* main::toSpritePtr1_sprite
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FINAL ASSEMBLER
|
||||||
|
Score: 292
|
||||||
|
|
||||||
|
// File Comments
|
||||||
|
// Example showing how to crunch and decrunch part of a file using the KickAss Cruncher Plugins
|
||||||
|
// Exomizer Example
|
||||||
|
// https://github.com/p-a/kickass-cruncher-plugins
|
||||||
|
// Upstart
|
||||||
|
// Commodore 64 PRG executable file - with the cruncher plugin enabled
|
||||||
|
.plugin "se.triad.kickass.CruncherPlugins"
|
||||||
|
.file [name="test-exomizer.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
|
||||||
|
// The offset of the sprite pointers from the screen start address
|
||||||
|
.const OFFSET_SPRITE_PTRS = $3f8
|
||||||
|
.const GREEN = 5
|
||||||
|
.const OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
|
||||||
|
.label SPRITES_XPOS = $d000
|
||||||
|
.label SPRITES_YPOS = $d001
|
||||||
|
.label SPRITES_COLOR = $d027
|
||||||
|
// The VIC-II MOS 6567/6569
|
||||||
|
.label VICII = $d000
|
||||||
|
// Default address of screen character matrix
|
||||||
|
.label DEFAULT_SCREEN = $400
|
||||||
|
// Address to decrunch the sprite to
|
||||||
|
.label SPRITE = $2000
|
||||||
|
.label SPRITES_PTR = DEFAULT_SCREEN+OFFSET_SPRITE_PTRS
|
||||||
|
.segment Code
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
.const toSpritePtr1_return = SPRITE/$40
|
||||||
|
// kickasm
|
||||||
|
// kickasm() {{ :EXO_DECRUNCH(CRUNCHED_SPRITE_END) }}
|
||||||
|
// Decrunch sprite file into memory
|
||||||
|
:EXO_DECRUNCH(CRUNCHED_SPRITE_END)
|
||||||
|
|
||||||
|
// VICII->SPRITES_ENABLE = %00000001
|
||||||
|
// [1] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1 -- _deref_pbuc1=vbuc2
|
||||||
|
// Show the loaded sprite on screen
|
||||||
|
lda #1
|
||||||
|
sta VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE
|
||||||
|
// [2] phi from main to main::toSpritePtr1 [phi:main->main::toSpritePtr1]
|
||||||
|
// main::toSpritePtr1
|
||||||
|
// main::@1
|
||||||
|
// SPRITES_PTR[0] = toSpritePtr(SPRITE)
|
||||||
|
// [3] *SPRITES_PTR = main::toSpritePtr1_return#0 -- _deref_pbuc1=vbuc2
|
||||||
|
lda #toSpritePtr1_return
|
||||||
|
sta SPRITES_PTR
|
||||||
|
// SPRITES_COLOR[0] = GREEN
|
||||||
|
// [4] *SPRITES_COLOR = GREEN -- _deref_pbuc1=vbuc2
|
||||||
|
lda #GREEN
|
||||||
|
sta SPRITES_COLOR
|
||||||
|
// SPRITES_XPOS[0] = 0x15
|
||||||
|
// [5] *SPRITES_XPOS = $15 -- _deref_pbuc1=vbuc2
|
||||||
|
lda #$15
|
||||||
|
sta SPRITES_XPOS
|
||||||
|
// SPRITES_YPOS[0] = 0x33
|
||||||
|
// [6] *SPRITES_YPOS = $33 -- _deref_pbuc1=vbuc2
|
||||||
|
lda #$33
|
||||||
|
sta SPRITES_YPOS
|
||||||
|
// main::@return
|
||||||
|
// }
|
||||||
|
// [7] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
.segment Data
|
||||||
|
// The exomizer decruncher
|
||||||
|
EXOMIZER:
|
||||||
|
.const EXO_LITERAL_SEQUENCES_USED = true
|
||||||
|
.const EXO_ZP_BASE = $02
|
||||||
|
.const EXO_DECRUNCH_TABLE = $0200
|
||||||
|
#import "exomizer_decrunch.asm"
|
||||||
|
|
||||||
|
// Array with crunched data created using inline kickasm
|
||||||
|
CRUNCHED_SPRITE:
|
||||||
|
.modify MemExomizer(false, true) {
|
||||||
|
.pc = SPRITE
|
||||||
|
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||||
|
.for (var y=0; y<21; y++)
|
||||||
|
.for (var x=0;x<3; x++)
|
||||||
|
.byte pic.getSinglecolorByte(x,y)
|
||||||
|
}
|
||||||
|
CRUNCHED_SPRITE_END:
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
const byte* CRUNCHED_SPRITE[] = kickasm( uses SPRITE) {{ .modify MemExomizer(false, true) {
|
||||||
|
.pc = SPRITE
|
||||||
|
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
|
||||||
|
.for (var y=0; y<21; y++)
|
||||||
|
.for (var x=0;x<3; x++)
|
||||||
|
.byte pic.getSinglecolorByte(x,y)
|
||||||
|
}
|
||||||
|
CRUNCHED_SPRITE_END:
|
||||||
|
}}
|
||||||
|
const nomodify byte* DEFAULT_SCREEN = (byte*) 1024
|
||||||
|
const byte* EXOMIZER[] = kickasm {{ .const EXO_LITERAL_SEQUENCES_USED = true
|
||||||
|
.const EXO_ZP_BASE = $02
|
||||||
|
.const EXO_DECRUNCH_TABLE = $0200
|
||||||
|
#import "exomizer_decrunch.asm"
|
||||||
|
}}
|
||||||
|
const nomodify byte GREEN = 5
|
||||||
|
const nomodify word OFFSET_SPRITE_PTRS = $3f8
|
||||||
|
const byte OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
|
||||||
|
const nomodify byte* SPRITE = (byte*) 8192
|
||||||
|
const nomodify byte* SPRITES_COLOR = (byte*) 53287
|
||||||
|
const nomodify byte* SPRITES_PTR = DEFAULT_SCREEN+OFFSET_SPRITE_PTRS
|
||||||
|
const nomodify byte* SPRITES_XPOS = (byte*) 53248
|
||||||
|
const nomodify byte* SPRITES_YPOS = (byte*) 53249
|
||||||
|
const nomodify struct MOS6569_VICII* VICII = (struct MOS6569_VICII*) 53248
|
||||||
|
void main()
|
||||||
|
byte main::toSpritePtr1_return
|
||||||
|
const byte main::toSpritePtr1_return#0 toSpritePtr1_return = (byte)(word)SPRITE/$40
|
||||||
|
byte* main::toSpritePtr1_sprite
|
||||||
|
|
Loading…
Reference in New Issue