diff --git a/.idea/libraries/Maven__se_triad_kickass_kickass_cruncher_plugins_2_0.xml b/.idea/libraries/Maven__se_triad_kickass_kickass_cruncher_plugins_2_0.xml new file mode 100644 index 000000000..b6d7699cf --- /dev/null +++ b/.idea/libraries/Maven__se_triad_kickass_kickass_cruncher_plugins_2_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/NOTICE.txt b/NOTICE.txt index fd23bfde0..75fa4646d 100644 --- a/NOTICE.txt +++ b/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/ ------------------------------------------------- diff --git a/kickc.iml b/kickc.iml index f0fdbded5..22a8da212 100644 --- a/kickc.iml +++ b/kickc.iml @@ -27,5 +27,6 @@ + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 2bf2475ef..457d65922 100644 --- a/pom.xml +++ b/pom.xml @@ -66,6 +66,11 @@ kickassxexformat 1.3 + + se.triad.kickass + kickass-cruncher-plugins + 2.0 + diff --git a/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/_remote.repositories b/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/_remote.repositories new file mode 100644 index 000000000..ad4140ce1 --- /dev/null +++ b/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/_remote.repositories @@ -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>= diff --git a/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.jar b/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.jar new file mode 100644 index 000000000..006925dec Binary files /dev/null and b/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.jar differ diff --git a/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.jar.md5 b/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.jar.md5 new file mode 100644 index 000000000..151023a62 --- /dev/null +++ b/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.jar.md5 @@ -0,0 +1 @@ +447c4814f5ec16eb83c11beb3b01d31e \ No newline at end of file diff --git a/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.jar.sha1 b/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.jar.sha1 new file mode 100644 index 000000000..ffd0ea58a --- /dev/null +++ b/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.jar.sha1 @@ -0,0 +1 @@ +6bf3f7ab6484422cab660080f9c52e32fd1a3494 \ No newline at end of file diff --git a/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.pom b/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.pom new file mode 100644 index 000000000..56188317d --- /dev/null +++ b/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.pom @@ -0,0 +1,9 @@ + + + 4.0.0 + se.triad.kickass + kickass-cruncher-plugins + 2.0 + POM was created from install:install-file + diff --git a/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.pom.md5 b/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.pom.md5 new file mode 100644 index 000000000..880f6cb6d --- /dev/null +++ b/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.pom.md5 @@ -0,0 +1 @@ +8df79d73d4bb320c097875441b02c73f \ No newline at end of file diff --git a/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.pom.sha1 b/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.pom.sha1 new file mode 100644 index 000000000..475b55bc4 --- /dev/null +++ b/repo/se/triad/kickass/kickass-cruncher-plugins/2.0/kickass-cruncher-plugins-2.0.pom.sha1 @@ -0,0 +1 @@ +0a9df4151d0ac74eb6faba472ed7f0aa7fb1f330 \ No newline at end of file diff --git a/repo/se/triad/kickass/kickass-cruncher-plugins/maven-metadata.xml b/repo/se/triad/kickass/kickass-cruncher-plugins/maven-metadata.xml new file mode 100644 index 000000000..8af2f2250 --- /dev/null +++ b/repo/se/triad/kickass/kickass-cruncher-plugins/maven-metadata.xml @@ -0,0 +1,12 @@ + + + se.triad.kickass + kickass-cruncher-plugins + + 2.0 + + 2.0 + + 20201230180211 + + diff --git a/repo/se/triad/kickass/kickass-cruncher-plugins/maven-metadata.xml.md5 b/repo/se/triad/kickass/kickass-cruncher-plugins/maven-metadata.xml.md5 new file mode 100644 index 000000000..747f1dc75 --- /dev/null +++ b/repo/se/triad/kickass/kickass-cruncher-plugins/maven-metadata.xml.md5 @@ -0,0 +1 @@ +ab025b6956bb8dc32185f8a6e084762d \ No newline at end of file diff --git a/repo/se/triad/kickass/kickass-cruncher-plugins/maven-metadata.xml.sha1 b/repo/se/triad/kickass/kickass-cruncher-plugins/maven-metadata.xml.sha1 new file mode 100644 index 000000000..98c606414 --- /dev/null +++ b/repo/se/triad/kickass/kickass-cruncher-plugins/maven-metadata.xml.sha1 @@ -0,0 +1 @@ +22b621912e62295723e7aa4e9614b2032ac4377b \ No newline at end of file diff --git a/src/main/repo/mvn-repo-install-cruncherplugins.sh b/src/main/repo/mvn-repo-install-cruncherplugins.sh new file mode 100755 index 000000000..04bb9468c --- /dev/null +++ b/src/main/repo/mvn-repo-install-cruncherplugins.sh @@ -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 diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 85e4c2174..84c73a6d1 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -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"); diff --git a/src/test/kc/examples/crunching/byteboozer.c b/src/test/kc/examples/crunching/byteboozer.c new file mode 100644 index 000000000..fb2de1d1f --- /dev/null +++ b/src/test/kc/examples/crunching/byteboozer.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" +}}; \ No newline at end of file diff --git a/src/test/kc/examples/crunching/byteboozer.h b/src/test/kc/examples/crunching/byteboozer.h new file mode 100644 index 000000000..7fabd299e --- /dev/null +++ b/src/test/kc/examples/crunching/byteboozer.h @@ -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); diff --git a/src/test/kc/examples/crunching/byteboozer_decrunch.asm b/src/test/kc/examples/crunching/byteboozer_decrunch.asm new file mode 100644 index 000000000..a5ae4daca --- /dev/null +++ b/src/test/kc/examples/crunching/byteboozer_decrunch.asm @@ -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 + 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 diff --git a/src/test/kc/examples/crunching/crunching.ld b/src/test/kc/examples/crunching/crunching.ld new file mode 100644 index 000000000..e1997932b --- /dev/null +++ b/src/test/kc/examples/crunching/crunching.ld @@ -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) \ No newline at end of file diff --git a/src/test/kc/examples/crunching/exomizer_decrunch.asm b/src/test/kc/examples/crunching/exomizer_decrunch.asm new file mode 100644 index 000000000..628ff1a22 --- /dev/null +++ b/src/test/kc/examples/crunching/exomizer_decrunch.asm @@ -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_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� 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 +#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) + } +}}; \ No newline at end of file diff --git a/src/test/kc/examples/crunching/test-exomizer.c b/src/test/kc/examples/crunching/test-exomizer.c new file mode 100644 index 000000000..b4de19817 --- /dev/null +++ b/src/test/kc/examples/crunching/test-exomizer.c @@ -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 + +// 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: +}}; + diff --git a/src/test/ref/examples/crunching/test-byteboozer.asm b/src/test/ref/examples/crunching/test-byteboozer.asm new file mode 100644 index 000000000..74c9bbe82 --- /dev/null +++ b/src/test/ref/examples/crunching/test-byteboozer.asm @@ -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+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) + } + diff --git a/src/test/ref/examples/crunching/test-byteboozer.cfg b/src/test/ref/examples/crunching/test-byteboozer.cfg new file mode 100644 index 000000000..7cc76388f --- /dev/null +++ b/src/test/ref/examples/crunching/test-byteboozer.cfg @@ -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 diff --git a/src/test/ref/examples/crunching/test-byteboozer.log b/src/test/ref/examples/crunching/test-byteboozer.log new file mode 100644 index 000000000..84e54b6fb --- /dev/null +++ b/src/test/ref/examples/crunching/test-byteboozer.log @@ -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+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+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) + } + + diff --git a/src/test/ref/examples/crunching/test-byteboozer.sym b/src/test/ref/examples/crunching/test-byteboozer.sym new file mode 100644 index 000000000..bdd9d0384 --- /dev/null +++ b/src/test/ref/examples/crunching/test-byteboozer.sym @@ -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 ] diff --git a/src/test/ref/examples/crunching/test-exomizer.asm b/src/test/ref/examples/crunching/test-exomizer.asm new file mode 100644 index 000000000..29d9ee650 --- /dev/null +++ b/src/test/ref/examples/crunching/test-exomizer.asm @@ -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: + diff --git a/src/test/ref/examples/crunching/test-exomizer.cfg b/src/test/ref/examples/crunching/test-exomizer.cfg new file mode 100644 index 000000000..5a97cef23 --- /dev/null +++ b/src/test/ref/examples/crunching/test-exomizer.cfg @@ -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 diff --git a/src/test/ref/examples/crunching/test-exomizer.log b/src/test/ref/examples/crunching/test-exomizer.log new file mode 100644 index 000000000..0ccc77105 --- /dev/null +++ b/src/test/ref/examples/crunching/test-exomizer.log @@ -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: + + diff --git a/src/test/ref/examples/crunching/test-exomizer.sym b/src/test/ref/examples/crunching/test-exomizer.sym new file mode 100644 index 000000000..f08eb1e28 --- /dev/null +++ b/src/test/ref/examples/crunching/test-exomizer.sym @@ -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 +