Skip to content

Commit

Permalink
Add RLE compression and decompression macros/subs.
Browse files Browse the repository at this point in the history
  • Loading branch information
maciejmalecki authored Jan 7, 2023
1 parent 2da8e14 commit 53acb79
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 1 deletion.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ Check our [User's Manual](https://c64lib.github.io/user-manual/#_common) for mor

## Change log

### Changes in version 0.4.0

* New macro: `compress.asm\compressRLE`.
* New subroutine: `decompress_rle.asm`.

### Changes in version 0.3.0

* New macro: `math.asm/mulAndAdd` - multiple two numbers and add result to memory location.
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ retroProject {
dialect = "KickAssembler"
dialectVersion = "5.25"
libDirs = [".ra/deps/c64lib"]
verbose = true
srcDirs = ["lib"]
libFromGitHub "c64lib/64spec", "0.7.0pr"
}

2 changes: 2 additions & 0 deletions lib/common-global.asm
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
* SOFTWARE.
*/
#import "common.asm"
#importonce

.filenamespace c64lib

.macro @c64lib_ch(data) { ch(data) }
Expand Down
30 changes: 30 additions & 0 deletions lib/compress-global.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* MIT License
*
* Copyright (c) 2017-2023 c64lib
* Copyright (c) 2017-2023 Maciej Małecki
*
* 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.
*/
#import "compress.asm"
#importonce

.filenamespace c64lib

.macro @c64lib_compressRLE(data) { compressRLE(data) }
55 changes: 55 additions & 0 deletions lib/compress.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* MIT License
*
* Copyright (c) 2017-2023 c64lib
* Copyright (c) 2017-2023 Maciej Małecki
*
* 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.
*/
#importonce
.filenamespace c64lib

/*
* Performs RLE (Running Length Encoding) compression of given binary data (kick assembler data type).
* The compressed result is placed as is in the result file starting from the place where this macro is called.
*/
.macro compressRLE(binaryData) {
.var runLength = 0
.var runValue = 0
.var crunchedLength = 0
.for(var i = 0; i < binaryData.getSize(); i++) {
.if(runLength > 0 && (binaryData.get(i) != runValue || runLength == $ff)) {
.byte runLength
.byte runValue
.eval runLength = 0
.eval crunchedLength = crunchedLength + 2
}
.if(runLength == 0) {
.eval runValue = binaryData.get(i)
.eval runLength = 1
} else {
.eval runLength++
}
}
.byte runLength
.byte runValue
.byte $00 // end mark
.eval crunchedLength++
.print "Crunched from " + binaryData.getSize() + " to " + crunchedLength + " (" + round((crunchedLength/binaryData.getSize())*100) + "%)"
}
68 changes: 68 additions & 0 deletions lib/sub/decompress-rle.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* MIT License
*
* Copyright (c) 2017-2023 c64lib
* Copyright (c) 2017-2023 Maciej Małecki
*
* 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.
*/
#import "../invoke.asm"

.namespace c64lib {

/*
* Stack:
* source address (2 bytes)
* dest address (2 bytes)
*/
decompressRLE: {
invokeStackBegin(returnPtr)
pullParamW(destination)
pullParamW(source)
invokeStackEnd(returnPtr)

nextSequence:
jsr loadSource
cmp #0
beq end // end mark
tax // x <- run length
jsr loadSource // a <- run value
decrunch:
sta destination:$ffff
inc destination
bne !+
inc destination + 1
!:
dex
bne decrunch
jmp nextSequence

end:
rts
loadSource:
lda source:$ffff
inc source
bne !+
inc source + 1
!:
rts
// locals
returnPtr: .word 0
}
}
57 changes: 57 additions & 0 deletions spec/decompress-rle.spec.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* MIT License
*
* Copyright (c) 2017-2023 c64lib
* Copyright (c) 2017-2023 Maciej Małecki
*
* 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.
*/
#import "64spec/lib/64spec.asm"
#import "../lib/compress-global.asm"
#import "../lib/invoke-global.asm"

.var testData = LoadBinary("decompress-rle.test-data.txt")

sfspec: init_spec()
describe("decompressRLE")

it("decompress data"); {
c64lib_pushParamW(compressedData)
c64lib_pushParamW(targetData)
jsr decompressRLE

assert_bytes_equal testData.getSize(): targetData: originalData
}
finish_spec()

* = * "Data"
decompressRLE:
#import "../lib/sub/decompress-rle.asm"

originalData:
.fill testData.getSize(), testData.get(i)
originalDataEnd:

compressedData:
c64lib_compressRLE(testData)
compressedDataEnd:

targetData:
.fill testData.getSize(), 0
targetDataEnd:
1 change: 1 addition & 0 deletions spec/decompress-rle.test-data.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
wegiel drogi to i atari nie dziala

0 comments on commit 53acb79

Please sign in to comment.