From 4fee4cfef7d49ebc528cc0d945578a6e59eed167 Mon Sep 17 00:00:00 2001 From: Ivan Tatarinov Date: Wed, 14 Apr 2021 15:56:35 +0300 Subject: [PATCH] sdk: added `GenRom` tool to SDK --- modflash/GenRom.c | 163 --------------------------- modflash/GenRom.exe | Bin 47132 -> 0 bytes modflash/Makefile | 11 +- modflash/addcores.bat | 2 + modflash/addcores.sh | 3 +- modflash/addroms.bat | 2 + modflash/addroms.sh | 3 +- sdk/Makefile | 4 +- sdk/README.md | 18 +-- sdk/bin/.gitignore | 1 + sdk/bin/GenRom.exe | Bin 0 -> 16384 bytes sdk/bin/GenRom.exe.license | 11 ++ sdk/src/Makefile | 10 +- sdk/src/tools/.gitignore | 2 + {firmware => sdk/src/tools}/GenRom.c | 60 ++++++++-- sdk/src/tools/Makefile | 7 +- 16 files changed, 103 insertions(+), 194 deletions(-) delete mode 100644 modflash/GenRom.c delete mode 100644 modflash/GenRom.exe create mode 100644 sdk/bin/GenRom.exe create mode 100644 sdk/bin/GenRom.exe.license rename {firmware => sdk/src/tools}/GenRom.c (78%) diff --git a/modflash/GenRom.c b/modflash/GenRom.c deleted file mode 100644 index 358b5ae..0000000 --- a/modflash/GenRom.c +++ /dev/null @@ -1,163 +0,0 @@ -#include -#include -#include - -FILE *fi, *fo; -int i; -unsigned char mem[0x4004+0x55], checksum; -unsigned short j, k, crc, tab[]= { -0x0000, 0x2110, 0x4220, 0x6330, 0x8440, 0xa550, 0xc660, 0xe770, -0x0881, 0x2991, 0x4aa1, 0x6bb1, 0x8cc1, 0xadd1, 0xcee1, 0xeff1, -0x3112, 0x1002, 0x7332, 0x5222, 0xb552, 0x9442, 0xf772, 0xd662, -0x3993, 0x1883, 0x7bb3, 0x5aa3, 0xbdd3, 0x9cc3, 0xfff3, 0xdee3, -0x6224, 0x4334, 0x2004, 0x0114, 0xe664, 0xc774, 0xa444, 0x8554, -0x6aa5, 0x4bb5, 0x2885, 0x0995, 0xeee5, 0xcff5, 0xacc5, 0x8dd5, -0x5336, 0x7226, 0x1116, 0x3006, 0xd776, 0xf666, 0x9556, 0xb446, -0x5bb7, 0x7aa7, 0x1997, 0x3887, 0xdff7, 0xfee7, 0x9dd7, 0xbcc7, -0xc448, 0xe558, 0x8668, 0xa778, 0x4008, 0x6118, 0x0228, 0x2338, -0xccc9, 0xedd9, 0x8ee9, 0xaff9, 0x4889, 0x6999, 0x0aa9, 0x2bb9, -0xf55a, 0xd44a, 0xb77a, 0x966a, 0x711a, 0x500a, 0x333a, 0x122a, -0xfddb, 0xdccb, 0xbffb, 0x9eeb, 0x799b, 0x588b, 0x3bbb, 0x1aab, -0xa66c, 0x877c, 0xe44c, 0xc55c, 0x222c, 0x033c, 0x600c, 0x411c, -0xaeed, 0x8ffd, 0xeccd, 0xcddd, 0x2aad, 0x0bbd, 0x688d, 0x499d, -0x977e, 0xb66e, 0xd55e, 0xf44e, 0x133e, 0x322e, 0x511e, 0x700e, -0x9fff, 0xbeef, 0xdddf, 0xfccf, 0x1bbf, 0x3aaf, 0x599f, 0x788f, -0x8891, 0xa981, 0xcab1, 0xeba1, 0x0cd1, 0x2dc1, 0x4ef1, 0x6fe1, -0x8010, 0xa100, 0xc230, 0xe320, 0x0450, 0x2540, 0x4670, 0x6760, -0xb983, 0x9893, 0xfba3, 0xdab3, 0x3dc3, 0x1cd3, 0x7fe3, 0x5ef3, -0xb102, 0x9012, 0xf322, 0xd232, 0x3542, 0x1452, 0x7762, 0x5672, -0xeab5, 0xcba5, 0xa895, 0x8985, 0x6ef5, 0x4fe5, 0x2cd5, 0x0dc5, -0xe234, 0xc324, 0xa014, 0x8104, 0x6674, 0x4764, 0x2454, 0x0544, -0xdba7, 0xfab7, 0x9987, 0xb897, 0x5fe7, 0x7ef7, 0x1dc7, 0x3cd7, -0xd326, 0xf236, 0x9106, 0xb016, 0x5766, 0x7676, 0x1546, 0x3456, -0x4cd9, 0x6dc9, 0x0ef9, 0x2fe9, 0xc899, 0xe989, 0x8ab9, 0xaba9, -0x4458, 0x6548, 0x0678, 0x2768, 0xc018, 0xe108, 0x8238, 0xa328, -0x7dcb, 0x5cdb, 0x3feb, 0x1efb, 0xf98b, 0xd89b, 0xbbab, 0x9abb, -0x754a, 0x545a, 0x376a, 0x167a, 0xf10a, 0xd01a, 0xb32a, 0x923a, -0x2efd, 0x0fed, 0x6cdd, 0x4dcd, 0xaabd, 0x8bad, 0xe89d, 0xc98d, -0x267c, 0x076c, 0x645c, 0x454c, 0xa23c, 0x832c, 0xe01c, 0xc10c, -0x1fef, 0x3eff, 0x5dcf, 0x7cdf, 0x9baf, 0xbabf, 0xd98f, 0xf89f, -0x176e, 0x367e, 0x554e, 0x745e, 0x932e, 0xb23e, 0xd10e, 0xf01e}; - -int main(int argc, char *argv[]) { - if( argc==1 ) - printf("\n" - "GenRom v0.06, generates a TAP for loading a ROM in the ZX-Uno, 2016-07-04\n\n" - " GenRom \n\n" - " Set 13 flags parameters, combinable\n" - " 0 MODE=00, DI1FFD=DI7FFD=DITAY=DIAY=DIRADAS=DITIMEX=DIULAPLUS=0\n" - " I2KB=DISCONT=DIVEN=DISNMI=DISD=ENMMU=DIROM1F=DIROM7F=0\n" - " i Change Issue2\n" - " t Force Timing to 128\n" - " p Force Timing to Pentagon\n" - " c Disable Contention\n" - " d Enable DivMMC paging\n" - " n Enable NMI-DivMMC\n" - " s Disable SD ports (DivMMC and ZXMMC)\n" - " m Enable horizontal MMU in Timex Sinclair\n" - " h Disable high bit ROM (1FFD bit 2)\n" - " l Disable low bit ROM (7FFD bit 4)\n" - " 1 Disable 1FFD port (+2A/+3 memory paging)\n" - " 7 Disable 7FFD port (128K memory paging)\n" - " 2 Disable 2nd AY chip\n" - " a Disable main AY chip\n" - " r Disable Radastanian mode\n" - " x Disable Timex mode\n" - " u Disable Ulaplus\n" - " Name between single quotes up to 32 chars\n" - " Input ROM file\n" - " Output TAP file\n\n" - "All params are mandatory\n\n"), - exit(0); - if( argc!=5 ) - printf("\nInvalid number of parameters\n"), - exit(-1); - fi= fopen(argv[3], "rb"); - if( !fi ) - printf("\nInput file not found: %s\n", argv[3]), - exit(-1); - fseek(fi, 0, SEEK_END); - i= ftell(fi); - if( i&0x3fff && i!=8192 ) - printf("\nInput file size must be multiple of 16384: %s\n", argv[3]), - exit(-1); - fo= fopen(argv[4], "wb+"); - if( !fo ) - printf("\nCannot create output file: %s\n", argv[4]), - exit(-1); - fwrite(mem, 1, 0x55, fo); - j= i>>14; - mem[0]= 0x02; - mem[1]= 0x40; - mem[2]= 0xff; - mem[0x4004]= 0x53; - mem[0x4005]= 0x00; - mem[0x4006]= 0xff; - if( j ){ - for ( i= j; i--; ){ - fseek(fi, i<<14, SEEK_SET); - fread(mem+3, 1, 0x4000, fi); - for ( checksum= 0, k= 3; k<0x4003; ++k ) - checksum|= mem[k]; - if( checksum ) - break; - } - j= i+1; - fseek(fi, 0, SEEK_SET); - for ( i= 0; i>8, - checksum^= mem[k]; - *(unsigned short*)(mem+0x400c+(j-i)*2)= crc; - mem[0x4003]= checksum; - fwrite(mem, 1, 0x4004, fo); - } - } - else{ - fseek(fi, 0, SEEK_SET); - mem[1]= 0x20; - fread(mem+3, j= 1, 0x2000, fi); - crc= 0xffff; - for ( checksum= 0xff, k= 3; k<0x2003; ++k ) - crc= tab[mem[k] ^ crc & 0xff] ^ crc>>8, - checksum^= mem[k]; - *(unsigned short*)(mem+0x400e)= crc; - mem[0x2003]= checksum; - fwrite(mem, 1, 0x2004, fo); - } - fseek(fo, 0, SEEK_SET); - mem[0x4007]= j; - mem[0x4008]= 0b00110000; - mem[0x4009]= 0b00000000; - for ( i= 0; iQ-z}6eI&g`u922Ga-R@zwh^X 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 rem rem SPDX-License-Identifier: GPL-3.0-or-later +call ..\sdk\setvars.bat + set /a i=2 for /f "eol=# tokens=1,2,3 delims=;" %%a in (cores.txt) do call :AddCore %%a %%b %%c exit /b diff --git a/modflash/addcores.sh b/modflash/addcores.sh index 123c3c0..145d40c 100755 --- a/modflash/addcores.sh +++ b/modflash/addcores.sh @@ -5,7 +5,6 @@ # # SPDX-License-Identifier: GPL-3.0-or-later -GENROM=./GenRom ADDITEM=./AddItem i=2 @@ -17,7 +16,7 @@ Error() { AddCore() { local f=${3%.*}.tap echo "Adding core $i: \"$2\" ($3)..." - $GENROM $1 "$2" $3 $f || Error $? + GenRom $1 "$2" $3 $f || Error $? $ADDITEM CORE$i $f || Error $? rm -f $f let i+=1 diff --git a/modflash/addroms.bat b/modflash/addroms.bat index 60ada8f..62f5835 100644 --- a/modflash/addroms.bat +++ b/modflash/addroms.bat @@ -5,6 +5,8 @@ rem SPDX-FileNotice: Based on code by Antonio Villena <_@antoniovillena.es> rem rem SPDX-License-Identifier: GPL-3.0-or-later +call ..\sdk\setvars.bat + set /a i=0 for /f "eol=# tokens=1,2,3 delims=;" %%a in (roms.txt) do call :AddROM %%a %%b %%c exit /b diff --git a/modflash/addroms.sh b/modflash/addroms.sh index ae36632..76d052b 100755 --- a/modflash/addroms.sh +++ b/modflash/addroms.sh @@ -5,7 +5,6 @@ # # SPDX-License-Identifier: GPL-3.0-or-later -GENROM=./GenRom ADDITEM=./AddItem i=0 @@ -19,7 +18,7 @@ AddROM() { local i1=$((i+n/16384-1)) local f=${3%.*}.tap echo "Adding ROM in slots $i-$i1: \"$2\" ($3)..." - $GENROM $1 "$2" $3 $f || Error $? + GenRom $1 "$2" $3 $f || Error $? $ADDITEM ROM $i $f || Error $? rm -f $f let i=i1+1 diff --git a/sdk/Makefile b/sdk/Makefile index 728b8f7..c9c1c08 100644 --- a/sdk/Makefile +++ b/sdk/Makefile @@ -48,13 +48,15 @@ ZX7B := zx7b$(EXECEXT) FCUT := fcut$(EXECEXT) FPAD := fpad$(EXECEXT) FPOKE := fpoke$(EXECEXT) +GENROM := GenRom$(EXECEXT) TOOLS:=\ bin/$(SJASMPLUS) \ bin/$(ZX7B) \ bin/$(FCUT) \ bin/$(FPAD) \ - bin/$(FPOKE) + bin/$(FPOKE) \ + bin/$(GENROM) .PHONY: all all: $(TOOLS) diff --git a/sdk/README.md b/sdk/README.md index e63efcd..b843685 100644 --- a/sdk/README.md +++ b/sdk/README.md @@ -32,15 +32,16 @@ Command | Target `make bin/fcut` | **fcut** `make bin/fpad` | **fpad** `make bin/fpoke` | **fpoke** +`make bin/GenRom` | **GenRom** -To build using MinGW add this parameter for **make** tool: +To build using MinGW add this parameter for `make` tool: Parameter | Target system ----|---- `BUILD=mingw32` | Windows with i686 architecture (32-bits) `BUILD=mingw64` | Windows with AMD64 architecture (64-bits) -Remember to specify proper file extension (".exe") for target when building with MinGW. Example: +Remember to specify proper file extension (`.exe`) for target when building with MinGW. Example: ```bash make BUILD=mingw64 bin/fcut.exe bin/fpad.exe bin/fpoke.exe @@ -80,12 +81,12 @@ include ../sdk/common.mk Remember to specify correct relative path to it. -This will set "ZXUNOSDK" environment variable (on first inclusion only) and update your "PATH" environment variable to point to SDK's tools. -These changes are actual for current invocation of "make" utility and all child processes. +This will set `ZXUNOSDK` environment variable (on first inclusion only) and update your `PATH` environment variable to point to SDK's tools. +These changes are actual for current invocation of `make` utility and all child processes. ### 2.3.2. In Bash scripts -Bash scripts are supposed to be invoked from Makefiles where the correct environment is already prepared by "make" utility so nothing must be done for such scripts. +Bash scripts are supposed to be invoked from Makefiles where the correct environment is already prepared by `make` utility so nothing must be done for such scripts. In other cases you must source `setvars.sh` file in a Bash script like this: @@ -112,6 +113,7 @@ This has the same behavior as the inclusion of `common.mk` file in a Makefile. * fcut * fpad * fpoke +* GenRom on Windows platform is disabled right now because of presence of precompiled binaries of them in repository. *By default* they are not deleted when cleaning. @@ -119,7 +121,7 @@ on Windows platform is disabled right now because of presence of precompiled bin ## 3.1. Build tools The building process is similar to one for GNU on Linux, FreeBSD etc. -See [2.1](#21-build-tools) with addition that you should provide correct target name (specify file extension ".exe") and also specify parameter `FORCEBUILD=1`. +See [2.1](#21-build-tools) with addition that you should provide correct target name (specify file extension `.exe`) and also specify parameter `FORCEBUILD=1`. ## 3.2. Clean tools @@ -150,10 +152,10 @@ call ..\sdk\setvars.bat Remember to specify correct relative path to it. -This will set "ZXUNOSDK" environment variable (on first call only) and update your "PATH" environment variable to point to SDK's tools. +This will set `ZXUNOSDK` environment variable (on first call only) and update your `PATH` environment variable to point to SDK's tools. These changes are actual for current invocation of command shell and all child processes. -# Links +# References * [Open Source FPGA Foundation Formed to Accelerate Widespread Adoption of Programmable Logic](https://osfpga.org/osfpga-foundation-launched/) - news article (April 8, 2021) * [Open-Source FPGA Foundation](https://osfpga.org/) - main site diff --git a/sdk/bin/.gitignore b/sdk/bin/.gitignore index 6d8327c..b946794 100644 --- a/sdk/bin/.gitignore +++ b/sdk/bin/.gitignore @@ -7,3 +7,4 @@ zx7b fcut fpad fpoke +GenRom diff --git a/sdk/bin/GenRom.exe b/sdk/bin/GenRom.exe new file mode 100644 index 0000000000000000000000000000000000000000..2cc0be1d6142ffde1b6e85a04d16028064839f35 GIT binary patch literal 16384 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. + * + * SPDX-FileCopyrightText: Copyright (C) 2016, 2021 Antonio Villena + * + * SPDX-License-Identifier: GPL-3.0-only + */ + #include #include #include +#define PROGRAM "GenRom" +#define DESCRIPTION "generates a TAP for loading a ROM in the ZX-Uno." +#define VERSION "0.06 (2016-07-04)" +#define COPYRIGHT "Copyright (C) 2016, 2021 Antonio Villena" +#define LICENSE \ +"This program is free software: you can redistribute it and/or modify\n" \ +"it under the terms of the GNU General Public License as published by\n" \ +"the Free Software Foundation, version 3." +#define HOMEPAGE "https://github.com/zxdos/zxuno/" + FILE *fi, *fo; int i; unsigned char mem[0x4004+0x55], checksum; @@ -39,11 +71,16 @@ unsigned short j, k, crc, tab[]= { 0x1fef, 0x3eff, 0x5dcf, 0x7cdf, 0x9baf, 0xbabf, 0xd98f, 0xf89f, 0x176e, 0x367e, 0x554e, 0x745e, 0x932e, 0xb23e, 0xd10e, 0xf01e}; -int main(int argc, char *argv[]) { - if( argc==1 ) - printf("\n" - "GenRom v0.06, generates a TAP for loading a ROM in the ZX-Uno, 2016-07-04\n\n" - " GenRom \n\n" +void show_help() { + printf( + PROGRAM " version " VERSION " - " DESCRIPTION "\n" + COPYRIGHT "\n" + LICENSE "\n" + "Home page: " HOMEPAGE "\n" + "\n" + "Usage:\n" + " " PROGRAM " \n" + "\n" " Set 13 flags parameters, combinable\n" " 0 MODE=00, DI1FFD=DI7FFD=DITAY=DIAY=DIRADAS=DITIMEX=DIULAPLUS=0\n" " I2KB=DISCONT=DIVEN=DISNMI=DISD=ENMMU=DIROM1F=DIROM7F=0\n" @@ -66,8 +103,15 @@ int main(int argc, char *argv[]) { " u Disable Ulaplus\n" " Name between single quotes up to 32 chars\n" " Input ROM file\n" - " Output TAP file\n\n" - "All params are mandatory\n\n"), + " Output TAP file\n" + "\n" + "All paramaters are mandatory.\n" + ); +} + +int main(int argc, char *argv[]) { + if( argc==1 ) + show_help(), exit(0); if( argc!=5 ) printf("\nInvalid number of parameters\n"), @@ -159,5 +203,5 @@ int main(int argc, char *argv[]) { checksum^= mem[k]; mem[0x4058]= checksum; fwrite(mem+0x4004, 1, 0x55, fo); - printf("\nFile generated successfully\n"); + printf("File `%s' is successfully generated.\n", argv[4]); } diff --git a/sdk/src/tools/Makefile b/sdk/src/tools/Makefile index 7f4c22c..3f840d1 100644 --- a/sdk/src/tools/Makefile +++ b/sdk/src/tools/Makefile @@ -23,11 +23,13 @@ include ../../common.mk FCUT := fcut$(EXECEXT) FPAD := fpad$(EXECEXT) FPOKE := fpoke$(EXECEXT) +GENROM := GenRom$(EXECEXT) TOOLS:=\ $(FCUT) \ $(FPAD) \ - $(FPOKE) + $(FPOKE) \ + $(GENROM) .PHONY: all all: $(TOOLS) @@ -41,6 +43,9 @@ $(FPAD): fpad.c $(FPOKE): fpoke.c $(CC) $(CFLAGS) -o $@ $< +$(GENROM): GenRom.c + $(CC) $(CFLAGS) -o $@ $< + .PHONY: clean clean: rm -f $(TOOLS)