From 4fee4cfef7d49ebc528cc0d945578a6e59eed167 Mon Sep 17 00:00:00 2001 From: Ivan Tatarinov Date: Wed, 14 Apr 2021 15:56:35 +0300 Subject: [PATCH 1/2] 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) From 02ab6a26b8274658e58db0e0cf733d284053281c Mon Sep 17 00:00:00 2001 From: Ivan Tatarinov Date: Wed, 14 Apr 2021 16:25:23 +0300 Subject: [PATCH 2/2] sdk: added `AddItem` tool to SDK --- modflash/AddItem.c | 68 --------------------- modflash/AddItem.exe | Bin 45084 -> 0 bytes sdk/Makefile | 4 +- sdk/README.md | 2 + sdk/bin/.gitignore | 1 + sdk/bin/AddItem.exe | Bin 0 -> 14336 bytes sdk/bin/AddItem.exe.license | 11 ++++ sdk/src/Makefile | 10 +++- sdk/src/tools/.gitignore | 2 + sdk/src/tools/AddItem.c | 114 ++++++++++++++++++++++++++++++++++++ sdk/src/tools/Makefile | 7 ++- 11 files changed, 147 insertions(+), 72 deletions(-) delete mode 100644 modflash/AddItem.c delete mode 100644 modflash/AddItem.exe create mode 100644 sdk/bin/AddItem.exe create mode 100644 sdk/bin/AddItem.exe.license create mode 100644 sdk/src/tools/AddItem.c diff --git a/modflash/AddItem.c b/modflash/AddItem.c deleted file mode 100644 index ebdb41d..0000000 --- a/modflash/AddItem.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include - -FILE *fi, *fo; -int i; -unsigned char mem[0x4004], core; -unsigned short j, k; - -int main(int argc, char *argv[]) { - if( argc==1 ) - printf("\n" - "AddItem v0.02, simulates Machine and ROM addition to the ZX-Uno flash image\n\n" - " AddItem \n\n" - " ROM or COREX, when 2<=X<=45, i.e. CORE5\n" - " Input .TAP file generate with GenRom\n" - " Number of slot from 0 to 63, only when type is ROM\n\n" - "All modifications occur in the file FLASH.ZX1\n\n"), - exit(0); - fo= fopen("FLASH.ZX1", "rb+"); - if( strstr(argv[1], "CORE")==argv[1] && strlen(argv[1])<=6 && strlen(argv[1])>=5 && argc==3 ){ - core= (strlen(argv[1])==5 ? argv[1][4] : (argv[1][4]-'0')*10+argv[1][5])-'2'; - if( core>43 ) - printf("\nCore number out of range: %d\n", core+2), - exit(-1); - fi= fopen(argv[2], "rb"); - if( !fi ) - printf("\nInput file not found: %s\n", argv[2]), - exit(-1); - fread(mem, 1, 0x58, fi); - fseek(fo, 0x7100+(core<<5), SEEK_SET); - fwrite(mem+0x34, 1, 0x20, fo); - j= mem[3]; - fseek(fo, (core>7?0x160000:0xac000)+core*0x54000, SEEK_SET); - for ( i=0; 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

jyAd>$D#KTA$Jbcwg|p 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

VASYe~4pFkaBtf%^m_^>aMMcdm$O6mpvSN&i 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 diff --git a/sdk/Makefile b/sdk/Makefile index c9c1c08..2a3de07 100644 --- a/sdk/Makefile +++ b/sdk/Makefile @@ -49,6 +49,7 @@ FCUT := fcut$(EXECEXT) FPAD := fpad$(EXECEXT) FPOKE := fpoke$(EXECEXT) GENROM := GenRom$(EXECEXT) +ADDITEM := AddItem$(EXECEXT) TOOLS:=\ bin/$(SJASMPLUS) \ @@ -56,7 +57,8 @@ TOOLS:=\ bin/$(FCUT) \ bin/$(FPAD) \ bin/$(FPOKE) \ - bin/$(GENROM) + bin/$(GENROM) \ + bin/$(ADDITEM) .PHONY: all all: $(TOOLS) diff --git a/sdk/README.md b/sdk/README.md index b843685..24ed6b5 100644 --- a/sdk/README.md +++ b/sdk/README.md @@ -33,6 +33,7 @@ Command | Target `make bin/fpad` | **fpad** `make bin/fpoke` | **fpoke** `make bin/GenRom` | **GenRom** +`make bin/AddItem` | **AddItem** To build using MinGW add this parameter for `make` tool: @@ -114,6 +115,7 @@ This has the same behavior as the inclusion of `common.mk` file in a Makefile. * fpad * fpoke * GenRom +* AddItem 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. diff --git a/sdk/bin/.gitignore b/sdk/bin/.gitignore index b946794..bc459a0 100644 --- a/sdk/bin/.gitignore +++ b/sdk/bin/.gitignore @@ -8,3 +8,4 @@ fcut fpad fpoke GenRom +AddItem diff --git a/sdk/bin/AddItem.exe b/sdk/bin/AddItem.exe new file mode 100644 index 0000000000000000000000000000000000000000..1e0954c30cd1273bf323dda44370931ec894cdac GIT binary patch literal 14336 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 literal 0 HcmV?d00001 diff --git a/sdk/bin/AddItem.exe.license b/sdk/bin/AddItem.exe.license new file mode 100644 index 0000000..e45abdf --- /dev/null +++ b/sdk/bin/AddItem.exe.license @@ -0,0 +1,11 @@ +SPDX-FileName: AddItem.exe + +SPDX-FileType: BINARY + +SPDX-FileChecksum: SHA1: 4c0298aa44631d46b241f90471d36775b536d844 + +SPDX-FileCopyrightText: Copyright (C) 2019, 2021 Antonio Villena + +SPDX-License-Identifier: GPL-3.0-only + +SPDX-FileComment: AddItem version 0.02 - simulates Machine and ROM addition to the ZX-Uno flash image. diff --git a/sdk/src/Makefile b/sdk/src/Makefile index c23ad81..4aa79d9 100644 --- a/sdk/src/Makefile +++ b/sdk/src/Makefile @@ -28,6 +28,7 @@ FCUT := fcut$(EXECEXT) FPAD := fpad$(EXECEXT) FPOKE := fpoke$(EXECEXT) GENROM := GenRom$(EXECEXT) +ADDITEM := AddItem$(EXECEXT) TOOLS:= \ ../bin/$(SJASMPLUS) \ @@ -35,7 +36,8 @@ TOOLS:= \ ../bin/$(FCUT) \ ../bin/$(FPAD) \ ../bin/$(FPOKE) \ - ../bin/$(GENROM) + ../bin/$(GENROM) \ + ../bin/$(ADDITEM) .PHONY: all all: $(TOOLS) @@ -94,10 +96,14 @@ zx7b/$(ZX7B): | zx7b ../bin/$(GENROM): tools/$(GENROM) cp $< $@ +../bin/$(ADDITEM): tools/$(ADDITEM) + cp $< $@ + tools/$(FCUT) \ tools/$(FPAD) \ tools/$(FPOKE) \ -tools/$(GENROM): | tools +tools/$(GENROM) \ +tools/$(ADDITEM): | tools $(MAKE) -w -C $| endif diff --git a/sdk/src/tools/.gitignore b/sdk/src/tools/.gitignore index a088ac8..0e0a00a 100644 --- a/sdk/src/tools/.gitignore +++ b/sdk/src/tools/.gitignore @@ -10,3 +10,5 @@ fpoke fpoke.exe GenRom GenRom.exe +AddItem +AddItem.exe diff --git a/sdk/src/tools/AddItem.c b/sdk/src/tools/AddItem.c new file mode 100644 index 0000000..e0f10e5 --- /dev/null +++ b/sdk/src/tools/AddItem.c @@ -0,0 +1,114 @@ +/* + * AddItem - simulates Machine and ROM addition to the ZX-Uno flash image. + * + * Copyright (C) 2019, 2021 Antonio Villena + * + * 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 + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Copyright (C) 2019, 2021 Antonio Villena + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include +#include +#include + +#define PROGRAM "AddItem" +#define DESCRIPTION "simulates Machine and ROM addition to the ZX-Uno flash image." +#define VERSION "0.02" +#define COPYRIGHT "Copyright (C) 2019, 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/" + +#define OUTPUT_FILE "FLASH.ZX1" + +FILE *fi, *fo; +int i; +unsigned char mem[0x4004], core; +unsigned short j, k; + +void show_help() { + printf( + PROGRAM " version " VERSION " - " DESCRIPTION "\n" + COPYRIGHT "\n" + LICENSE "\n" + "Home page: " HOMEPAGE "\n" + "\n" + "Usage:\n" + " " PROGRAM " \n" + "\n" + " ROM or COREX, where 2<=X<=45, i.e. CORE5\n" + " Input .TAP file generated with GenRom\n" + " Slot's number from 0 to 63, only when type is ROM\n" + "\n" + "All modifications occur in the file `" OUTPUT_FILE "'.\n" + ); +} + +int main(int argc, char *argv[]) { + if( argc==1 ) + show_help(), + exit(0); + fo= fopen(OUTPUT_FILE, "rb+"); + if( strstr(argv[1], "CORE")==argv[1] && strlen(argv[1])<=6 && strlen(argv[1])>=5 && argc==3 ){ + core= (strlen(argv[1])==5 ? argv[1][4] : (argv[1][4]-'0')*10+argv[1][5])-'2'; + if( core>43 ) + printf("\nCore number out of range: %d\n", core+2), + exit(-1); + fi= fopen(argv[2], "rb"); + if( !fi ) + printf("\nInput file not found: %s\n", argv[2]), + exit(-1); + fread(mem, 1, 0x58, fi); + fseek(fo, 0x7100+(core<<5), SEEK_SET); + fwrite(mem+0x34, 1, 0x20, fo); + j= mem[3]; + fseek(fo, (core>7?0x160000:0xac000)+core*0x54000, SEEK_SET); + for ( i=0; i