Merge pull request #92 from ivan-tat/master

sdk: added `dzx7b` tool and macros
This commit is contained in:
Ivan Tatarinov 2021-05-25 14:32:21 +03:00 committed by GitHub
commit 54cbce14f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 479 additions and 96 deletions

View File

@ -13,6 +13,8 @@
include ../../sdk/common.mk
srcdir = .
INCLUDEDIR = ../../sdk/include
FUENTEABIN = tools/build/FuenteABin$(EXESUFFIX)
AS = sjasmplus
@ -27,35 +29,12 @@ endif
AFLAGS += -I$(INCLUDEDIR)
.PHONY: all
all: scroll.tap
all: $(srcdir)/scroll.tap
scroll.tap: scrolldesc.bin
GenTape $@ basic "SCROLL" 0 $<
scrolldesc.bin: scrolldesc.asm define.asm scroll.bin.zx7b
$(AS) $(AFLAGS) --raw=$@ $<
define.asm: scroll.bin scroll.exp
echo ' define filesize $(shell stat -c %s $<)' >$@
cat scroll.exp >>$@
scroll.bin.zx7b: scroll.bin
zx7b $< $@
scroll.bin scroll.exp:\
scroll.asm\
string.asm\
$(INCLUDEDIR)/playstc.inc\
$(INCLUDEDIR)/filestc.def\
$(INCLUDEDIR)/ay.def\
music.stc\
fuente6x8.bin\
lineas.asm\
fondo.rcs
$(AS) $(AFLAGS) --raw=scroll.bin --exp=scroll.exp $<
fuente6x8.bin: fuente6x8.png | $(FUENTEABIN)
$(FUENTEABIN) $< $@
$(srcdir)/fondo.rcs:\
$(srcdir)/fondo.png\
$(srcdir)/fondo.atr
Png2Rcs $< $@ -a $(srcdir)/fondo.atr
$(FUENTEABIN): | tools
ifeq ($(OS),Windows_NT)
@ -64,8 +43,39 @@ else
$(MAKE) -w -C $|
endif
fondo.rcs: fondo.png fondo.atr
Png2Rcs $< $@ -a fondo.atr
$(srcdir)/fuente6x8.bin: $(srcdir)/fuente6x8.png | $(FUENTEABIN)
$(FUENTEABIN) $< $@
$(srcdir)/scroll.exp\
$(srcdir)/scroll.bin: $(srcdir)/scroll.asm\
$(srcdir)/string.asm\
$(INCLUDEDIR)/playstc.inc\
$(INCLUDEDIR)/filestc.def\
$(INCLUDEDIR)/ay.def\
$(srcdir)/music.stc\
$(srcdir)/fuente6x8.bin\
$(srcdir)/lineas.asm\
$(srcdir)/fondo.rcs
$(AS) $(AFLAGS) --exp=scroll.exp --raw=scroll.bin $<
$(srcdir)/scroll.bin.zx7b: $(srcdir)/scroll.bin
zx7b $< $@
$(srcdir)/define.asm:\
$(srcdir)/scroll.bin\
$(srcdir)/scroll.exp
echo ' define filesize $(shell stat -c %s $<)' >$@
cat $(srcdir)/scroll.exp >>$@
$(srcdir)/scrolldesc.bin:\
$(srcdir)/scrolldesc.asm\
$(srcdir)/define.asm\
$(INCLUDEDIR)/dzx7b.mac\
$(srcdir)/scroll.bin.zx7b
$(AS) $(AFLAGS) --raw=$@ $<
$(srcdir)/scroll.tap: $(srcdir)/scrolldesc.bin
GenTape $@ basic "SCROLL" 0 $<
.PHONY: install
install:;
@ -76,7 +86,15 @@ uninstall:;
.PHONY: clean
clean: | tools
$(MAKE) -w -C $| $@
rm -f fuente6x8.bin fondo.rcs scroll.bin scroll.exp scroll.bin.zx7b define.asm scrolldesc.bin scroll.tap
rm -f\
$(srcdir)/fuente6x8.bin\
$(srcdir)/fondo.rcs\
$(srcdir)/scroll.bin\
$(srcdir)/scroll.exp\
$(srcdir)/scroll.bin.zx7b\
$(srcdir)/define.asm\
$(srcdir)/scrolldesc.bin\
$(srcdir)/scroll.tap
.PHONY: distclean
distclean:;
distclean: clean

View File

@ -6,6 +6,8 @@
; complete names.
;
; Copyright (C) 2016, 2017, 2020, 2021 Antonio Villena
; Contributors:
; 2021 Ivan Tatarinov <ivan-tat@ya.ru>
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
@ -21,12 +23,14 @@
;
; SPDX-FileCopyrightText: Copyright (C) 2016, 2017, 2020, 2021 Antonio Villena
;
; SPDX-FileContributor: 2021 Ivan Tatarinov <ivan-tat@ya.ru>
;
; SPDX-License-Identifier: GPL-3.0-only
; Compatible compilers:
; SJAsmPlus, <https://github.com/sjasmplus/sjasmplus/>
output scroll.bin
; output scroll.bin
org $5e6d

View File

@ -1,17 +1,31 @@
@rem SPDX-FileCopyrightText: 2016, 2021 Antonio Villena
@rem
@rem SPDX-License-Identifier: GPL-3.0-only
@call ..\..\sdk\setenv.bat
FuenteABin fuente6x8.png fuente6x8.bin
@echo off
rem SPDX-FileCopyrightText: 2016, 2021 Antonio Villena
rem
rem SPDX-FileContributor: 2021 Ivan Tatarinov <ivan-tat@ya.ru>
rem
rem SPDX-License-Identifier: GPL-3.0-only
call ..\..\sdk\setenv.bat
set FuenteABin=tools\build\FuenteABin
set AS=sjasmplus
set AFLAGS="-I%ZXSDK%\include"
%FuenteABin% fuente6x8.png fuente6x8.bin
Png2Rcs fondo.png fondo.rcs -a fondo.atr
sjasmplus scroll.asm
call :getfilesize scroll.bin
echo define filesize %_filesize% > define.asm
%AS% %AFLAGS% --exp=scroll.exp --raw=scroll.bin scroll.asm
call :getfilesize _filesize scroll.bin
echo define filesize %_filesize% > define.asm
type scroll.exp >> define.asm
zx7b scroll.bin scroll.bin.zx7b
sjasmplus scrolldesc.asm
%AS% %AFLAGS% --raw=scrolldesc.bin scrolldesc.asm
GenTape scroll.tap basic "SCROLL" 0 scrolldesc.bin
rem Clean
del /q fuente6x8.bin fondo.rcs scroll.exp scroll.bin define.asm scroll.bin.zx7b scrolldesc.bin >nul
goto :eof
:getfilesize
set _filesize=%~z1
set %1=%~z2
goto :eof

View File

@ -1,68 +1,32 @@
; scrolldesc.asm
; scrolldesc.asm - loader of packed "scroll" demo.
;
; SPDX-FileCopyrightText: Copyright (C) 2016, 2017, 2020, 2021 Antonio Villena
;
; SPDX-FileContributor: 2021 Ivan Tatarinov <ivan-tat@ya.ru>
;
; SPDX-License-Identifier: GPL-3.0-only
; Compatible compilers:
; SJAsmPlus, <https://github.com/sjasmplus/sjasmplus/>
; output scrolldesc.bin
include define.asm
output scrolldesc.bin
include dzx7b.mac
org $5ccb
ld de, filestart+filesize-1
di
defb $de, $c0, $37, $0e, $8f, $39, $96
jr aqui
getbit ld a, (hl)
dec hl
adc a, a
ret
aqui ld hl, fin-1
; -----------------------------------------------------------------------------
; ZX7 Backwards by Einar Saukas, Antonio Villena
; Parameters:
; HL: source address (compressed data)
; DE: destination address (decompressing)
; -----------------------------------------------------------------------------
dzx7b ld bc, $8000
ld a, b
copyby inc c
ldd
mainlo add a, a
call z, getbit
jr nc, copyby
push de
ld d, c
defb $30
lenval add a, a
call z, getbit
rl c
rl b
add a, a
call z, getbit
jr nc, lenval
inc c
jr z, exitdz
ld e, (hl)
dec hl
sll e
jr nc, offend
ld d, $10
nexbit add a, a
call z, getbit
rl d
jr nc, nexbit
inc d
srl d
offend rr e
ex (sp), hl
ex de, hl
adc hl, de
lddr
exitdz pop hl
jr nc, mainlo
ld hl, scroll_end-1
dzx7b dzx7b_body getbit
jp start
getbit dzx7b_getbit
incbin scroll.bin.zx7b
fin
scroll_end

View File

@ -259,6 +259,7 @@
dz $48, 'Sinclair Research Ltd'
dz $48, 'LodePNG project'
dz $48, 'SJAsmPlus project'
dz $48, 'Einar Saukas'
dz $48, 'Xilinx Inc?'
dz $48
dz $43, 'The ZX>UNO core team are'

BIN
sdk/bin/dzx7b.exe Executable file

Binary file not shown.

11
sdk/bin/dzx7b.exe.license Normal file
View File

@ -0,0 +1,11 @@
SPDX-FileName: dzx7b.exe
SPDX-FileType: BINARY
SPDX-FileChecksum: SHA1: 1c1d766371864e10bfb5c95fa57d7598e8a6bf89
SPDX-FileCopyrightText: Copyright (c) 2015 Einar Saukas. All rights reserved.
SPDX-License-Identifier: BSD-3-clause
SPDX-FileComment: dzx7b version 1.0 (2015) - LZ77/LZSS backwards decompressor.

71
sdk/include/dzx7b.mac Normal file
View File

@ -0,0 +1,71 @@
; dzx7b.mac - ZX7 backwards decompressor macros.
;
; SPDX-FileCopyrightText: Copyright (C) 2016, 2021 Antonio Villena
;
; SPDX-FileNotice: Based on LZ77/LZSS backwards decompressor by Einar Saukas.
; SPDX-FileNotice: LZ77/LZSS backwards decompressor is Copyright (c) 2015 Einar Saukas. All rights reserved.
; SPDX-FileNotice: LZ77/LZSS backwards decompressor is distributed under BSD 3-Clause license.
;
; SPDX-License-Identifier: GPL-3.0-only
; Compatible compilers:
; SJAsmPlus, <https://github.com/sjasmplus/sjasmplus/>
ifndef dzx7b_mac_included
define dzx7b_mac_included
macro dzx7b_getbit
ld a, (hl)
dec hl
adc a, a
ret
endm
; -----------------------------------------------------------------------------
; ZX7 Backwards by Einar Saukas, Antonio Villena
; Parameters:
; HL: source address (compressed data)
; DE: destination address (decompressing)
; -----------------------------------------------------------------------------
macro dzx7b_body getbit_label
ld bc, $8000
ld a, b
.copyby inc c
ldd
.mainlo add a, a
call z, getbit_label
jr nc, .copyby
push de
ld d, c
defb $30 ; 2 bytes opcode "jr nc, nn" but CY=1 and it is ignored with the following "add a, a"
.lenval add a, a ; 1 byte opcode
call z, getbit_label
rl c
rl b
add a, a
call z, getbit_label
jr nc, .lenval
inc c
jr z, .exitdz
ld e, (hl)
dec hl
sll e
jr nc, .offend
ld d, $10
.nexbit add a, a
call z, getbit_label
rl d
jr nc, .nexbit
inc d
srl d
.offend rr e
ex (sp), hl
ex de, hl
adc hl, de
lddr
.exitdz pop hl
jr nc, .mainlo
; ret ; use it in source code to jump outside
endm
endif ; !dzx7b_mac_included

View File

@ -30,7 +30,9 @@ bindir ?= $(exec_prefix)/bin
INSTALL ?= install
INSTALL_PROGRAM ?= $(INSTALL)
BINS = zx7b$(EXESUFFIX)
BINS=\
zx7b$(EXESUFFIX)\
dzx7b$(EXESUFFIX)
.PHONY: all
all: $(foreach t,$(BINS),build/$(t))
@ -42,12 +44,18 @@ $(DESTDIR)$(bindir):
build/zx7b$(EXESUFFIX): $(srcdir)/zx7b.c Makefile | build
$(CC) $(CFLAGS) -o $@ $<
build/dzx7b$(EXESUFFIX): $(srcdir)/dzx7b.c Makefile | build
$(CC) $(CFLAGS) -o $@ $<
.PHONY: install
install: $(foreach t,$(BINS),$(DESTDIR)$(bindir)/$(t))
$(DESTDIR)$(bindir)/zx7b$(EXESUFFIX): build/zx7b$(EXESUFFIX) | $(DESTDIR)$(bindir)
$(INSTALL_PROGRAM) $< $@
$(DESTDIR)$(bindir)/dzx7b$(EXESUFFIX): build/dzx7b$(EXESUFFIX) | $(DESTDIR)$(bindir)
$(INSTALL_PROGRAM) $< $@
.PHONY: uninstall
uninstall:
rm -f $(foreach t,$(BINS),$(DESTDIR)$(bindir)/$(t))

291
sdk/src/zx7b/dzx7b.c Normal file
View File

@ -0,0 +1,291 @@
/*
* dzx7b - LZ77/LZSS backwards decompressor.
*
* Copyright (c) 2015 Einar Saukas. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * The name of its author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* SPDX-FileCopyrightText: Copyright (c) 2015 Einar Saukas. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
* SPDX-LicenseComments: License's text equals to one from https://directory.fsf.org/wiki/License:BSD-3-Clause
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PROGRAM "dzx7b"
#define DESCRIPTION "LZ77/LZSS backwards decompressor."
#define VERSION "1.0 (2015)"
#define COPYRIGHT "Copyright (c) 2015 Einar Saukas. All rights reserved."
#define LICENSE "Distributed under BSD 3-clause license."
#define HOMEPAGE "https://github.com/antoniovillena/zx7b/"
FILE *ifp;
FILE *ofp;
char *input_name;
char *output_name;
unsigned char *input_data;
unsigned char *output_data;
size_t input_index;
size_t output_index;
size_t input_size;
size_t output_size;
size_t partial_counter;
size_t total_counter;
int bit_mask;
int bit_value;
int read_byte() {
return input_data[input_index++];
}
int read_bit() {
bit_mask >>= 1;
if (bit_mask == 0) {
bit_mask = 128;
bit_value = read_byte();
}
return bit_value & bit_mask ? 1 : 0;
}
int read_elias_gamma() {
int i;
int value;
value = 1;
while (!read_bit()) {
value = value << 1 | read_bit();
}
if( (value&255)==255 )
value= -1;
return value;
}
int read_offset() {
int value;
int i;
value = read_byte();
if (value < 128) {
return value;
} else {
i = read_bit();
i = i << 1 | read_bit();
i = i << 1 | read_bit();
i = i << 1 | read_bit();
return (value & 127 | i << 7) + 128;
}
}
void write_byte(int value) {
output_data[output_index++] = value;
}
void write_bytes(int offset, int length) {
if (offset > output_size+output_index) {
fprintf(stderr, "Error: Invalid data in input file %s\n", input_name);
exit(1);
}
while (length-- > 0) {
write_byte(output_data[output_index-offset]);
}
}
void decompress() {
int length,i;
input_index = 0;
partial_counter = 0;
output_index = 0;
bit_mask = 0;
write_byte(read_byte());
while (1) {
if (!read_bit()) {
write_byte(read_byte());
} else {
length = read_elias_gamma()+1;
if (length == 0) {
return;
}
write_bytes(read_offset()+1, length);
}
}
}
void show_help() {
printf(
PROGRAM " version " VERSION " - " DESCRIPTION "\n"
COPYRIGHT "\n"
LICENSE "\n"
"Home page: " HOMEPAGE "\n"
"\n"
"Usage:\n"
" " PROGRAM " [-f] input.zx7 [output]\n"
"\n"
" -f Force overwrite of output file\n"
" output Decompressed output file\n"
);
}
int main(int argc, char *argv[]) {
int forced_mode = 0;
int i;
/* process hidden optional parameters */
for (i = 1; i < argc && *argv[i] == '-'; i++) {
if (!strcmp(argv[i], "-f")) {
forced_mode = 1;
} else {
fprintf(stderr, "Error: Invalid parameter `%s\'\n", argv[i]);
exit(1);
}
}
/* determine output filename */
if (argc == i+1) {
input_name = argv[i];
input_size = strlen(input_name);
if (input_size > 4 && !strcmp(input_name+input_size-4, ".zx7")) {
output_name = (char *)malloc(input_size);
strcpy(output_name, input_name);
output_name[input_size-4] = '\0';
} else {
fprintf(stderr, "Error: Cannot infer output filename\n");
exit(1);
}
} else if (argc == i+2) {
input_name = argv[i];
output_name = argv[i+1];
} else {
show_help();
exit(1);
}
/* open input file */
ifp = fopen(input_name, "rb");
if (!ifp) {
fprintf(stderr, "Error: Cannot access input file %s\n", input_name);
exit(1);
}
/* determine input size */
fseek(ifp, 0L, SEEK_END);
input_size = ftell(ifp);
fseek(ifp, 0L, SEEK_SET);
if (!input_size) {
fprintf(stderr, "Error: Empty input file %s\n", argv[1]);
exit(1);
}
/* allocate input buffer */
input_data = (unsigned char *)malloc(input_size);
if (!input_data) {
fprintf(stderr, "Error: Insufficient memory\n");
exit(1);
}
/* read input file */
total_counter = 0;
do {
partial_counter = fread(input_data+total_counter, sizeof(char), input_size-total_counter, ifp);
total_counter += partial_counter;
} while ( partial_counter > 0 );
if (total_counter != input_size) {
fprintf(stderr, "Error: Cannot read input file %s\n", argv[1]);
exit(1);
}
/* check output file */
if (!forced_mode && fopen(output_name, "rb") != NULL) {
fprintf(stderr, "Error: Already existing output file %s\n", output_name);
exit(1);
}
/* create output file */
ofp = fopen(output_name, "wb");
if (!ofp) {
fprintf(stderr, "Error: Cannot create output file %s\n", output_name);
exit(1);
}
/* reverse input data */
for ( i= 0; i<input_size>>1; i++ ){
partial_counter = input_data[i];
input_data[i] = input_data[input_size-1-i];
input_data[input_size-1-i] = partial_counter;
}
/* calculate output file size and allocate memory */
output_size = 1;
read_byte();
while (1) {
if (!read_bit()) {
output_size++;
read_byte();
} else {
i = read_elias_gamma()+1;
if (i == 0) {
break;
}
read_offset();
output_size+= i;
}
}
output_data = (unsigned char *)malloc(output_size);
if (!output_data) {
fprintf(stderr, "Error: Insufficient memory\n");
exit(1);
}
/* decompress */
decompress();
/* reverse output data */
for ( i= 0; i<output_size>>1; i++ ) {
partial_counter= output_data[i];
output_data[i]= output_data[output_size-1-i];
output_data[output_size-1-i]= partial_counter;
}
/* write output file */
if (fwrite(output_data, sizeof(char), output_size, ofp) != output_size) {
fprintf(stderr, "Error: Cannot write output file %s\n", output_name);
exit(1);
}
/* close input file */
fclose(ifp);
/* close output file */
fclose(ofp);
/* done! */
printf("File `%s' converted from %lu to %lu bytes!\n",
output_name, (unsigned long)input_size, (unsigned long)output_size);
return 0;
}

View File

@ -40,6 +40,7 @@ Files:
* `UPGRADE`
* `UPGRZX2`
* `UPGRZXD`
* `ZXUNOCFG`
## Build utilities