mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-10-08 01:59:01 +00:00
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
|
||||
- Toiletrensdyr SID is redistributed by personal permission from Søren Lund
|
||||
- KickAssembler is redistributed by personal permission from Mads Nielsen
|
||||
- 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
|
||||
- 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
|
||||
|
||||
-------------------------------------------------
|
||||
Toiletrensdyr - https://csdb.dk/sid/?id=54859
|
||||
-------------------------------------------------
|
||||
|
||||
-------------------------------------------------
|
||||
KickAssembler - https://theweb.dk/KickAssembler/
|
||||
Created by Mads Nielsen
|
||||
-------------------------------------------------
|
||||
|
||||
-------------------------------------------------
|
||||
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/
|
||||
-------------------------------------------------
|
||||
|
@ -27,5 +27,6 @@
|
||||
<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: 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>
|
||||
</module>
|
5
pom.xml
5
pom.xml
@ -66,6 +66,11 @@
|
||||
<artifactId>kickassxexformat</artifactId>
|
||||
<version>1.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>se.triad.kickass</groupId>
|
||||
<artifactId>kickass-cruncher-plugins</artifactId>
|
||||
<version>2.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<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
|
18
src/main/repo/mvn-repo-install-cruncherplugins.sh
Executable file
18
src/main/repo/mvn-repo-install-cruncherplugins.sh
Executable file
@ -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");
|
||||
}
|
||||
|
||||
@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
|
||||
public void testMusic() throws IOException, URISyntaxException {
|
||||
compileAndCompare("examples/music/music.c");
|
||||
|
18
src/test/kc/examples/crunching/byteboozer.c
Normal file
18
src/test/kc/examples/crunching/byteboozer.c
Normal file
@ -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"
|
||||
}};
|
6
src/test/kc/examples/crunching/byteboozer.h
Normal file
6
src/test/kc/examples/crunching/byteboozer.h
Normal file
@ -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);
|
182
src/test/kc/examples/crunching/byteboozer_decrunch.asm
Normal file
182
src/test/kc/examples/crunching/byteboozer_decrunch.asm
Normal file
@ -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
|
9
src/test/kc/examples/crunching/crunching.ld
Normal file
9
src/test/kc/examples/crunching/crunching.ld
Normal file
@ -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)
|
354
src/test/kc/examples/crunching/exomizer_decrunch.asm
Normal file
354
src/test/kc/examples/crunching/exomizer_decrunch.asm
Normal file
@ -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
|
||||
|
||||
}
|
BIN
src/test/kc/examples/crunching/sprite.png
Normal file
BIN
src/test/kc/examples/crunching/sprite.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
36
src/test/kc/examples/crunching/test-byteboozer.c
Normal file
36
src/test/kc/examples/crunching/test-byteboozer.c
Normal file
@ -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)
|
||||
}
|
||||
}};
|
46
src/test/kc/examples/crunching/test-exomizer.c
Normal file
46
src/test/kc/examples/crunching/test-exomizer.c
Normal file
@ -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:
|
||||
}};
|
||||
|
84
src/test/ref/examples/crunching/test-byteboozer.asm
Normal file
84
src/test/ref/examples/crunching/test-byteboozer.asm
Normal file
@ -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)
|
||||
}
|
||||
|
29
src/test/ref/examples/crunching/test-byteboozer.cfg
Normal file
29
src/test/ref/examples/crunching/test-byteboozer.cfg
Normal file
@ -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
|
508
src/test/ref/examples/crunching/test-byteboozer.log
Normal file
508
src/test/ref/examples/crunching/test-byteboozer.log
Normal file
@ -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
|
||||