1
0
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:
jespergravgaard 2020-12-30 23:13:55 +01:00
parent 2dd2697ba1
commit c36da71ecd
32 changed files with 1990 additions and 6 deletions

View File

@ -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>

View File

@ -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/
-------------------------------------------------

View File

@ -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>

View File

@ -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>

View File

@ -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>=

View File

@ -0,0 +1 @@
447c4814f5ec16eb83c11beb3b01d31e

View File

@ -0,0 +1 @@
6bf3f7ab6484422cab660080f9c52e32fd1a3494

View File

@ -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>

View File

@ -0,0 +1 @@
8df79d73d4bb320c097875441b02c73f

View File

@ -0,0 +1 @@
0a9df4151d0ac74eb6faba472ed7f0aa7fb1f330

View File

@ -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>

View File

@ -0,0 +1 @@
ab025b6956bb8dc32185f8a6e084762d

View File

@ -0,0 +1 @@
22b621912e62295723e7aa4e9614b2032ac4377b

View 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

View File

@ -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");

View 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"
}};

View 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);

View 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

View 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)

View 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
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View 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)
}
}};

View 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:
}};

View 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)
}

View 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

View 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