diff --git a/projects/Z80/.github/pull_request_template.md b/projects/Z80/.github/pull_request_template.md index 74984ed..5c30277 100644 --- a/projects/Z80/.github/pull_request_template.md +++ b/projects/Z80/.github/pull_request_template.md @@ -4,8 +4,8 @@ _Describe your pull request here._ ### Legal notice _(do not delete)_ -It is required that contributors assign copyright to the original author so that he retains full ownership of the project. This makes it easier for other entities to use the software because they only have to deal with one copyright holder. It also gives the original author assurance that he will be able to make decisions in the future without gathering and consulting all contributors. +Contributors are required to assign copyright to the original author of the project so that he retains full ownership. This ensures that other entities can use the software more easily, as they only need to deal with a single copyright holder. It also provides the original author with the assurance that he can make decisions in the future without needing to consult or obtain consent from all contributors. -By submitting this PR, you agree to the following: +By submitting this pull request (PR), you agree to the following: -> You hereby assign copyright in this PR's code to the original author of the Z80 library, Manuel Sainz de Baranda y Goñi, to be licensed under the same terms as the rest of the code. You agree to relinquish any and all copyright interest in the software, to the detriment of your heirs and successors. +> You hereby assign the copyright in the code included in this pull request to the original author of the Z80 library, Manuel Sainz de Baranda y Goñi, to be licensed under the same terms as the rest of the code. You also agree to relinquish any and all copyright interest in the software, to the detriment of your heirs and successors. diff --git a/projects/Z80/.github/workflows/build-and-test-library.yml b/projects/Z80/.github/workflows/build-and-test-library.yml index 50b1879..3fee7ac 100644 --- a/projects/Z80/.github/workflows/build-and-test-library.yml +++ b/projects/Z80/.github/workflows/build-and-test-library.yml @@ -6,8 +6,11 @@ on: - '.github/workflows/build-and-test-library.yml' - 'API/**' - 'CMake/FindZeta.cmake' - - 'sources/*.c' - - 'sources/*.rc.in' + - 'sources/generate-daa-af-table.c' + - 'sources/generate-pf-parity-table.c' + - 'sources/test-Z80.c' + - 'sources/Z80.c' + - 'sources/Z80.rc.in' - 'support/*.sha3-512' - 'CMakeLists.txt' pull_request: @@ -15,8 +18,11 @@ on: - '.github/workflows/build-and-test-library.yml' - 'API/**' - 'CMake/FindZeta.cmake' - - 'sources/*.c' - - 'sources/*.rc.in' + - 'sources/generate-daa-af-table.c' + - 'sources/generate-pf-parity-table.c' + - 'sources/test-Z80.c' + - 'sources/Z80.c' + - 'sources/Z80.rc.in' - 'support/*.sha3-512' - 'CMakeLists.txt' @@ -26,15 +32,20 @@ env: CMAKE_BUILD_TYPE: Release Z80_FETCH_TEST_FILES: YES Z80_NOSTDLIB_FLAGS: Auto - Z80_WITH_CMAKE_SUPPORT: NO + Z80_OBJECT_LIBS: NO + Z80_WITH_CMAKE_SUPPORT: YES + Z80_WITH_CODE_GENERATION_TOOLS: YES Z80_WITH_HTML_DOCUMENTATION: NO Z80_WITH_PDF_DOCUMENTATION: NO - Z80_WITH_PKGCONFIG_SUPPORT: NO + Z80_WITH_PKGCONFIG_SUPPORT: YES Z80_WITH_STANDARD_DOCUMENTS: NO - Z80_WITH_TESTS: YES + Z80_WITH_STEP_TESTING_TOOL: NO + Z80_WITH_TESTING_TOOL: YES Z80_WITH_EXECUTE: YES Z80_WITH_FULL_IM0: YES Z80_WITH_IM0_RETX_NOTIFICATIONS: YES + Z80_WITH_PARITY_COMPUTATION: NO + Z80_WITH_PRECOMPUTED_DAA: NO Z80_WITH_Q: YES Z80_WITH_SPECIAL_RESET: YES Z80_WITH_UNOFFICIAL_RETI: NO @@ -42,7 +53,7 @@ env: jobs: build-and-test-library: - runs-on: ${{matrix.os}} + runs-on: ${{ matrix.os }} strategy: matrix: @@ -54,42 +65,47 @@ jobs: - name: Install dependencies (POSIX) if: startsWith(matrix.os, 'macos') || startsWith(matrix.os, 'ubuntu') run: | - mkdir -p "${{github.workspace}}/build" - curl -L "${{env.ZETA_TARBALL_URL}}" | xz -cd | tar -C "${{github.workspace}}/build" --strip-components=2 -xvf - Zeta/API/Z + mkdir -p "${{ github.workspace }}/build" + curl -L "${{ env.ZETA_TARBALL_URL }}" | xz -cd | tar -C "${{ github.workspace }}/build" --strip-components=2 -xf - Zeta/API/Z - name: Install dependencies (Windows) if: startsWith(matrix.os, 'windows') shell: cmd run: | - mkdir "${{github.workspace}}\build" - curl -L "${{env.ZETA_TARBALL_URL}}" | 7z x -txz -si -so | 7z x -si -ttar -o"${{github.workspace}}\build" Zeta/API/Z + mkdir "${{ github.workspace }}\build" + curl -L "${{ env.ZETA_TARBALL_URL }}" | 7z x -txz -si -so | 7z x -si -ttar -o"${{ github.workspace }}\build" Zeta/API/Z - name: Configure CMake run: >- cmake - -DBUILD_SHARED_LIBS=${{env.BUILD_SHARED_LIBS}} - -DCMAKE_BUILD_TYPE=${{env.CMAKE_BUILD_TYPE}} - -DZ80_FETCH_TEST_FILES=${{env.Z80_FETCH_TEST_FILES}} - -DZ80_NOSTDLIB_FLAGS=${{env.Z80_NOSTDLIB_FLAGS}} - -DZ80_WITH_CMAKE_SUPPORT=${{env.Z80_WITH_CMAKE_SUPPORT}} - -DZ80_WITH_HTML_DOCUMENTATION=${{env.Z80_WITH_HTML_DOCUMENTATION}} - -DZ80_WITH_PDF_DOCUMENTATION=${{env.Z80_WITH_PDF_DOCUMENTATION}} - -DZ80_WITH_PKGCONFIG_SUPPORT=${{env.Z80_WITH_PKGCONFIG_SUPPORT}} - -DZ80_WITH_STANDARD_DOCUMENTS=${{env.Z80_WITH_STANDARD_DOCUMENTS}} - -DZ80_WITH_TESTS=${{env.Z80_WITH_TESTS}} - -DZ80_WITH_EXECUTE=${{env.Z80_WITH_EXECUTE}} - -DZ80_WITH_FULL_IM0=${{env.Z80_WITH_FULL_IM0}} - -DZ80_WITH_IM0_RETX_NOTIFICATIONS=${{env.Z80_WITH_IM0_RETX_NOTIFICATIONS}} - -DZ80_WITH_Q=${{env.Z80_WITH_Q}} - -DZ80_WITH_SPECIAL_RESET=${{env.Z80_WITH_SPECIAL_RESET}} - -DZ80_WITH_UNOFFICIAL_RETI=${{env.Z80_WITH_UNOFFICIAL_RETI}} - -DZ80_WITH_ZILOG_NMOS_LD_A_IR_BUG=${{env.Z80_WITH_ZILOG_NMOS_LD_A_IR_BUG}} - -B "${{github.workspace}}/build" - -S "${{github.workspace}}" + -DBUILD_SHARED_LIBS=${{ env.BUILD_SHARED_LIBS }} + -DCMAKE_BUILD_TYPE=${{ env.CMAKE_BUILD_TYPE }} + -DZ80_FETCH_TEST_FILES=${{ env.Z80_FETCH_TEST_FILES }} + -DZ80_NOSTDLIB_FLAGS=${{ env.Z80_NOSTDLIB_FLAGS }} + -DZ80_OBJECT_LIBS=${{ env.Z80_OBJECT_LIBS }} + -DZ80_WITH_CMAKE_SUPPORT=${{ env.Z80_WITH_CMAKE_SUPPORT }} + -DZ80_WITH_CODE_GENERATION_TOOLS=${{ env.Z80_WITH_CODE_GENERATION_TOOLS }} + -DZ80_WITH_HTML_DOCUMENTATION=${{ env.Z80_WITH_HTML_DOCUMENTATION }} + -DZ80_WITH_PDF_DOCUMENTATION=${{ env.Z80_WITH_PDF_DOCUMENTATION }} + -DZ80_WITH_PKGCONFIG_SUPPORT=${{ env.Z80_WITH_PKGCONFIG_SUPPORT }} + -DZ80_WITH_STANDARD_DOCUMENTS=${{ env.Z80_WITH_STANDARD_DOCUMENTS }} + -DZ80_WITH_STEP_TESTING_TOOL=${{ env.Z80_WITH_STEP_TESTING_TOOL }} + -DZ80_WITH_TESTING_TOOL=${{ env.Z80_WITH_TESTING_TOOL }} + -DZ80_WITH_EXECUTE=${{ env.Z80_WITH_EXECUTE }} + -DZ80_WITH_FULL_IM0=${{ env.Z80_WITH_FULL_IM0 }} + -DZ80_WITH_IM0_RETX_NOTIFICATIONS=${{ env.Z80_WITH_IM0_RETX_NOTIFICATIONS }} + -DZ80_WITH_PARITY_COMPUTATION=${{ env.Z80_WITH_PARITY_COMPUTATION }} + -DZ80_WITH_PRECOMPUTED_DAA=${{ env.Z80_WITH_PRECOMPUTED_DAA }} + -DZ80_WITH_Q=${{ env.Z80_WITH_Q }} + -DZ80_WITH_SPECIAL_RESET=${{ env.Z80_WITH_SPECIAL_RESET }} + -DZ80_WITH_UNOFFICIAL_RETI=${{ env.Z80_WITH_UNOFFICIAL_RETI }} + -DZ80_WITH_ZILOG_NMOS_LD_A_IR_BUG=${{ env.Z80_WITH_ZILOG_NMOS_LD_A_IR_BUG }} + -B "${{ github.workspace }}/build" + -S "${{ github.workspace }}" - name: Build - run: cmake --build "${{github.workspace}}/build" --config ${{env.CMAKE_BUILD_TYPE}} --verbose + run: cmake --build "${{ github.workspace }}/build" --config ${{ env.CMAKE_BUILD_TYPE }} --verbose - name: Test - working-directory: ${{github.workspace}}/build - run: ctest --build-config ${{env.CMAKE_BUILD_TYPE}} --output-on-failure + working-directory: ${{ github.workspace }}/build + run: ctest --build-config ${{ env.CMAKE_BUILD_TYPE }} --output-on-failure diff --git a/projects/Z80/.github/workflows/build-documentation.yml b/projects/Z80/.github/workflows/build-documentation.yml index a0f38b7..fcefa58 100644 --- a/projects/Z80/.github/workflows/build-documentation.yml +++ b/projects/Z80/.github/workflows/build-documentation.yml @@ -22,11 +22,13 @@ env: CMAKE_BUILD_TYPE: Release Z80_FETCH_TEST_FILES: NO Z80_WITH_CMAKE_SUPPORT: NO + Z80_WITH_CODE_GENERATION_TOOLS: NO Z80_WITH_HTML_DOCUMENTATION: YES Z80_WITH_PDF_DOCUMENTATION: YES Z80_WITH_PKGCONFIG_SUPPORT: NO Z80_WITH_STANDARD_DOCUMENTS: NO - Z80_WITH_TESTS: NO + Z80_WITH_STEP_TESTING_TOOL: NO + Z80_WITH_TESTING_TOOL: NO jobs: build-documentation: @@ -45,26 +47,28 @@ jobs: - name: Install dependencies run: | - mkdir -p "${{github.workspace}}/build" - curl -L "${{env.ZETA_TARBALL_URL}}" | xz -cd | tar -C "${{github.workspace}}/build" --strip-components=2 -xvf - Zeta/API/Z + mkdir -p "${{ github.workspace }}/build" + curl -L "${{ env.ZETA_TARBALL_URL }}" | xz -cd | tar -C "${{ github.workspace }}/build" --strip-components=2 -xf - Zeta/API/Z - name: Configure CMake run: >- cmake - -DBUILD_SHARED_LIBS=${{env.BUILD_SHARED_LIBS}} - -DCMAKE_BUILD_TYPE=${{env.CMAKE_BUILD_TYPE}} - -DZ80_FETCH_TEST_FILES=${{env.Z80_FETCH_TEST_FILES}} - -DZ80_WITH_CMAKE_SUPPORT=${{env.Z80_WITH_CMAKE_SUPPORT}} - -DZ80_WITH_HTML_DOCUMENTATION=${{env.Z80_WITH_HTML_DOCUMENTATION}} - -DZ80_WITH_PDF_DOCUMENTATION=${{env.Z80_WITH_PDF_DOCUMENTATION}} - -DZ80_WITH_PKGCONFIG_SUPPORT=${{env.Z80_WITH_PKGCONFIG_SUPPORT}} - -DZ80_WITH_STANDARD_DOCUMENTS=${{env.Z80_WITH_STANDARD_DOCUMENTS}} - -DZ80_WITH_TESTS=${{env.Z80_WITH_TESTS}} - -B "${{github.workspace}}/build" - -S "${{github.workspace}}" + -DBUILD_SHARED_LIBS=${{ env.BUILD_SHARED_LIBS }} + -DCMAKE_BUILD_TYPE=${{ env.CMAKE_BUILD_TYPE }} + -DZ80_FETCH_TEST_FILES=${{ env.Z80_FETCH_TEST_FILES }} + -DZ80_WITH_CMAKE_SUPPORT=${{ env.Z80_WITH_CMAKE_SUPPORT }} + -DZ80_WITH_CODE_GENERATION_TOOLS=${{ env.Z80_WITH_CODE_GENERATION_TOOLS }} + -DZ80_WITH_HTML_DOCUMENTATION=${{ env.Z80_WITH_HTML_DOCUMENTATION }} + -DZ80_WITH_PDF_DOCUMENTATION=${{ env.Z80_WITH_PDF_DOCUMENTATION }} + -DZ80_WITH_PKGCONFIG_SUPPORT=${{ env.Z80_WITH_PKGCONFIG_SUPPORT }} + -DZ80_WITH_STANDARD_DOCUMENTS=${{ env.Z80_WITH_STANDARD_DOCUMENTS }} + -DZ80_WITH_STEP_TESTING_TOOL=${{ env.Z80_WITH_STEP_TESTING_TOOL }} + -DZ80_WITH_TESTING_TOOL=${{ env.Z80_WITH_TESTING_TOOL }} + -B "${{ github.workspace }}/build" + -S "${{ github.workspace }}" - name: Build HTML documentation - run: cmake --build "${{github.workspace}}/build" --config ${{env.CMAKE_BUILD_TYPE}} --target Z80-Documentation-HTML --verbose + run: cmake --build "${{ github.workspace }}/build" --config ${{ env.CMAKE_BUILD_TYPE }} --target Z80-Documentation-HTML --verbose - name: Build PDF documentation - run: cmake --build "${{github.workspace}}/build" --config ${{env.CMAKE_BUILD_TYPE}} --target Z80-Documentation-PDF --verbose + run: cmake --build "${{ github.workspace }}/build" --config ${{ env.CMAKE_BUILD_TYPE }} --target Z80-Documentation-PDF --verbose diff --git a/projects/Z80/.github/workflows/step-tests.yml b/projects/Z80/.github/workflows/step-tests.yml new file mode 100644 index 0000000..d88d9bd --- /dev/null +++ b/projects/Z80/.github/workflows/step-tests.yml @@ -0,0 +1,116 @@ +name: Step tests + +on: + push: + paths: + - '.github/workflows/step-tests.yml' + - 'API/**' + - 'CMake/FindZeta.cmake' + - 'sources/step-test-Z80.c' + - 'sources/Z80.c' + - 'CMakeLists.txt' + pull_request: + paths: + - '.github/workflows/step-tests.yml' + - 'API/**' + - 'CMake/FindZeta.cmake' + - 'sources/step-test-Z80.c' + - 'sources/Z80.c' + - 'CMakeLists.txt' + +env: + TEST_FILES_QUERY_URL: 'https://api.github.com/repos/SingleStepTests/z80/releases/latest' + TEST_FILES_PATH: '*/v1' + BUILD_SHARED_LIBS: YES + CMAKE_BUILD_TYPE: Release + Z80_FETCH_TEST_FILES: NO + Z80_NOSTDLIB_FLAGS: Auto + Z80_OBJECT_LIBS: NO + Z80_WITH_CMAKE_SUPPORT: NO + Z80_WITH_CODE_GENERATION_TOOLS: NO + Z80_WITH_HTML_DOCUMENTATION: NO + Z80_WITH_PDF_DOCUMENTATION: NO + Z80_WITH_PKGCONFIG_SUPPORT: NO + Z80_WITH_STANDARD_DOCUMENTS: NO + Z80_WITH_STEP_TESTING_TOOL: YES + Z80_WITH_TESTING_TOOL: NO + Z80_WITH_EXECUTE: YES + Z80_WITH_FULL_IM0: YES + Z80_WITH_IM0_RETX_NOTIFICATIONS: YES + Z80_WITH_PARITY_COMPUTATION: NO + Z80_WITH_PRECOMPUTED_DAA: NO + Z80_WITH_Q: YES + Z80_WITH_SPECIAL_RESET: YES + Z80_WITH_UNOFFICIAL_RETI: NO + Z80_WITH_ZILOG_NMOS_LD_A_IR_BUG: YES + +jobs: + step-tests: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies (macOS) + if: startsWith(matrix.os, 'macos') + run: | + brew install cjson + brew install redcode/zxe/z80insnclock + + - name: Install dependencies (Ubuntu) + if: startsWith(matrix.os, 'ubuntu') + run: | + curl -L https://zxe.io/scripts/add-zxe-apt-repo.sh | sudo sh + sudo apt-get update + sudo apt-get -y install libcjson-dev + sudo apt-get -y install libz80insnclock-dev + + - name: Fetch test files + run: | + mkdir -p "${{ github.workspace }}/build/step-tests" + curl -L $(curl -sL "${{ env.TEST_FILES_QUERY_URL }}" | jq -r .tarball_url) | + gzip -cd | + tar -C "${{ github.workspace }}/build/step-tests" --strip-components=2 -xf - $([[ $(tar --version | head -n 1 | cut -d " " -f 1) = tar ]] && echo --wildcards) "${{ env.TEST_FILES_PATH }}" + + - name: Configure CMake + run: >- + cmake + -DBUILD_SHARED_LIBS=${{ env.BUILD_SHARED_LIBS }} + -DCMAKE_BUILD_TYPE=${{ env.CMAKE_BUILD_TYPE }} + -DZ80_FETCH_TEST_FILES=${{ env.Z80_FETCH_TEST_FILES }} + -DZ80_NOSTDLIB_FLAGS=${{ env.Z80_NOSTDLIB_FLAGS }} + -DZ80_OBJECT_LIBS=${{ env.Z80_OBJECT_LIBS }} + -DZ80_WITH_CMAKE_SUPPORT=${{ env.Z80_WITH_CMAKE_SUPPORT }} + -DZ80_WITH_CODE_GENERATION_TOOLS=${{ env.Z80_WITH_CODE_GENERATION_TOOLS }} + -DZ80_WITH_HTML_DOCUMENTATION=${{ env.Z80_WITH_HTML_DOCUMENTATION }} + -DZ80_WITH_PDF_DOCUMENTATION=${{ env.Z80_WITH_PDF_DOCUMENTATION }} + -DZ80_WITH_PKGCONFIG_SUPPORT=${{ env.Z80_WITH_PKGCONFIG_SUPPORT }} + -DZ80_WITH_STANDARD_DOCUMENTS=${{ env.Z80_WITH_STANDARD_DOCUMENTS }} + -DZ80_WITH_STEP_TESTING_TOOL=${{ env.Z80_WITH_STEP_TESTING_TOOL }} + -DZ80_WITH_TESTING_TOOL=${{ env.Z80_WITH_TESTING_TOOL }} + -DZ80_WITH_EXECUTE=${{ env.Z80_WITH_EXECUTE }} + -DZ80_WITH_FULL_IM0=${{ env.Z80_WITH_FULL_IM0 }} + -DZ80_WITH_IM0_RETX_NOTIFICATIONS=${{ env.Z80_WITH_IM0_RETX_NOTIFICATIONS }} + -DZ80_WITH_PARITY_COMPUTATION=${{ env.Z80_WITH_PARITY_COMPUTATION }} + -DZ80_WITH_PRECOMPUTED_DAA=${{ env.Z80_WITH_PRECOMPUTED_DAA }} + -DZ80_WITH_Q=${{ env.Z80_WITH_Q }} + -DZ80_WITH_SPECIAL_RESET=${{ env.Z80_WITH_SPECIAL_RESET }} + -DZ80_WITH_UNOFFICIAL_RETI=${{ env.Z80_WITH_UNOFFICIAL_RETI }} + -DZ80_WITH_ZILOG_NMOS_LD_A_IR_BUG=${{ env.Z80_WITH_ZILOG_NMOS_LD_A_IR_BUG }} + -B "${{ github.workspace }}/build" + -S "${{ github.workspace }}" + + - name: Build + run: cmake --build "${{ github.workspace }}/build" --config ${{ env.CMAKE_BUILD_TYPE }} --verbose + + - name: Test + working-directory: ${{ github.workspace }}/build + run: ./step-test-Z80 step-tests/*.json + + - name: Test with `--run` + working-directory: ${{ github.workspace }}/build + run: ./step-test-Z80 --run step-tests/*.json diff --git a/projects/Z80/API/Z80.h b/projects/Z80/API/Z80.h index 2ac7d15..e2ed0a1 100644 --- a/projects/Z80/API/Z80.h +++ b/projects/Z80/API/Z80.h @@ -4,7 +4,7 @@ ____ \/__/ /\_\ __ \\ \/\ \ ________________________________________________ | /\_____\\_____\\_____\ | | Zilog \/_____//_____//_____/ CPU Emulator | -| Copyright (C) 1999-2024 Manuel Sainz de Baranda y Goñi. | +| Copyright (C) 1999-2026 Manuel Sainz de Baranda y Goñi. | | | | This emulator is free software: you can redistribute it and/or modify it | | under the terms of the GNU Lesser General Public License as published by | @@ -30,13 +30,13 @@ * of the Zilog Z80 that emulates all that is known to date about this CPU, * including the undocumented behaviors, MEMPTR, Q and the special RESET. * - * @version 0.2 - * @date 2024 + * @version 0.2-pre-2025-07-02 + * @date 2025-07-02 * @author Manuel Sainz de Baranda y Goñi */ -#ifdef Z80_DEPENDENCIES_HEADER +#ifdef Z80_EXTERNAL_HEADER # define Z80_H -# include Z80_DEPENDENCIES_HEADER +# include Z80_EXTERNAL_HEADER # undef Z80_H #else # include @@ -88,11 +88,27 @@ #define Z80_MINIMUM_CYCLES_PER_STEP 4 +/** @brief Opcode of the @c halt instruction in the Z80 ISA. */ + +#define Z80_HALT 0x76 + /** @brief Opcode interpreted as a trap by the Z80 library. It corresponds to * the ld h,h instruction in the Z80 ISA. */ #define Z80_HOOK 0x64 +/** @brief Opcode of the jp WORD instruction in the Z80 ISA. */ + +#define Z80_JP_WORD 0xC3 + +/** @brief Opcode of the @c nop instruction in the Z80 ISA. */ + +#define Z80_NOP 0x00 + +/** @brief Opcode of the @c ret instruction in the Z80 ISA. */ + +#define Z80_RET 0xC9 + #define Z80_SF 128 /**< @brief Bitmask of the Z80 S flag. */ #define Z80_ZF 64 /**< @brief Bitmask of the Z80 Z flag. */ #define Z80_YF 32 /**< @brief Bitmask of the Z80 Y flag. */ @@ -160,10 +176,10 @@ typedef zuint8 (* Z80Illegal)(Z80 *cpu, zuint8 opcode); * in use. */ struct Z80 { - - /** @brief Number of clock cycles already executed. */ - - zusize cycles; +# if !defined(__DOXYGEN__) && defined(Z80_WITH_VOLATILE_CYCLES) + volatile +# endif + zusize cycles; /**< @brief Number of clock cycles already executed. */ /** @brief Maximum number of clock cycles to be executed. */ @@ -405,12 +421,12 @@ struct Z80 { ZInt16 memptr; /**< @brief Register MEMPTR, also known as WZ. */ ZInt16 af; /**< @brief Register pair AF (accumulator and flags). */ - ZInt16 bc; /**< @brief Register pair BC. */ - ZInt16 de; /**< @brief Register pair DE. */ - ZInt16 hl; /**< @brief Register pair HL. */ ZInt16 af_; /**< @brief Register pair AF'. */ + ZInt16 bc; /**< @brief Register pair BC. */ ZInt16 bc_; /**< @brief Register pair BC'. */ + ZInt16 de; /**< @brief Register pair DE. */ ZInt16 de_; /**< @brief Register pair DE'. */ + ZInt16 hl; /**< @brief Register pair HL. */ ZInt16 hl_; /**< @brief Register pair HL'. */ zuint8 r; /**< @brief Register R (memory refresh). */ zuint8 i; /**< @brief Register I (interrupt vector base). */ @@ -447,7 +463,7 @@ struct Z80 { zuint8 iff1; /**< @brief Interrupt enable flip-flop #1 (IFF1). */ zuint8 iff2; /**< @brief Interrupt enable flip-flop #2 (IFF2). */ - zuint8 q; /**< @brief Pseudo-register Q. */ + zuint8 q; /**< @brief Q factor. */ /** @brief Emulation options. * @@ -471,6 +487,33 @@ struct Z80 { * @ref Z80::halt, not after. */ zuint8 halt_line; + +# ifdef Z80_WITH_RESET_SIGNAL + /** @brief Pointer to a memory-mapped register containing a reset signal. + * + * If not @c Z_NULL, the emulator reads this register at every + * instruction boundary inside @ref z80_run and tests it against + * @ref reset_signal_mask. A non-zero result causes the emulation + * loop to exit immediately, before the next instruction fetch. + * This allows an external hardware reset line to halt the CPU at + * the same point a real Z80 would: at the end of the current + * instruction. + * + * Typical usage: point this to a PIO IRQ flag register or a GPIO + * input register, with the mask selecting the relevant bit. + * + * Setting this to @c Z_NULL disables the check (default). */ + + zuint32 volatile const *reset_signal; + + /** @brief Bitmask applied to @ref reset_signal. + * + * The emulator tests *reset_signal & reset_signal_mask + * at each instruction boundary. A non-zero result indicates that + * a reset is active. */ + + zuint32 reset_signal_mask; +# endif }; /** @brief @ref Z80::options bitmask that enables emulation of the @@ -775,7 +818,7 @@ Z_EXTERN_C_BEGIN * @c Z_TRUE = power on; * @c Z_FALSE = power off. */ -Z80_API void z80_power(Z80 *self, zboolean state); +Z80_API void z80_power(Z80 *self, zbool state); /** @brief Performs an instantaneous normal RESET on a @ref Z80. * @@ -800,7 +843,7 @@ Z80_API void z80_special_reset(Z80 *self); * @c Z_TRUE = set line low; * @c Z_FALSE = set line high. */ -Z80_API void z80_int(Z80 *self, zboolean state); +Z80_API void z80_int(Z80 *self, zbool state); /** @brief Triggers the NMI line of a @ref Z80. * @@ -809,7 +852,8 @@ Z80_API void z80_int(Z80 *self, zboolean state); Z80_API void z80_nmi(Z80 *self); /** @brief Runs a @ref Z80 for a given number of clock @p cycles, - * executing only instructions without responding to signals. + * executing only instructions without responding to interrupts requests or + * special RESET signals. * * @param self Pointer to the object on which the function is called. * @param cycles Number of clock cycles to be emulated. @@ -831,7 +875,7 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles); * * This function should only be used inside callback functions. It zeroes * @ref Z80::cycle_limit, thus breaking the emulation loop after the - * ongoing emulation step has finished executing. + * completion of the ongoing emulation step. * * @param self Pointer to the object on which the function is called. */ @@ -899,6 +943,19 @@ static inline zuint8 z80_out_cycle(Z80 const *self) } +/** @brief Sends a WAIT signal to a @ref Z80. + * + * This function should only be used inside callback functions. It adds the + * given number of clock @p cycles to @ref Z80::cycles, thus + * lengthening the ongoing emulation step. + * + * @param self Pointer to the object on which the function is called. + * @param cycles Duration of the WAIT signal, in clock cycles. */ + +static inline void z80_wait(Z80 *self, zusize cycles) + {self->cycles += cycles;} + + Z_EXTERN_C_END #endif /* Z80_H */ diff --git a/projects/Z80/AUTHORS b/projects/Z80/AUTHORS index 779ef3a..20d7491 100644 --- a/projects/Z80/AUTHORS +++ b/projects/Z80/AUTHORS @@ -1,6 +1,11 @@ Original author: Sainz de Baranda y Goñi, Manuel -Contributors: +Collaborators: Ortega Sosa, Sofía + +Contributors: + Haubenthal, Stefan + Rolandi, Giovan Battista + Slayden, Glenn Vučenović, Zoran diff --git a/projects/Z80/CITATION.cff b/projects/Z80/CITATION.cff index 7cbb8c0..00b07ce 100644 --- a/projects/Z80/CITATION.cff +++ b/projects/Z80/CITATION.cff @@ -6,7 +6,7 @@ authors: email: 'manuel@zxe.io' website: 'https://zxe.io' cff-version: '1.2.0' -date-released: '2024-04-18' +date-released: '2025-07-02' keywords: - CPU - LLE @@ -18,5 +18,5 @@ message: If you use this software, please cite it using these metadata. repository-code: 'https://github.com/redcode/Z80' title: Z80 type: software -version: '0.2-pre-2024-04-18' +version: '0.2-pre-2025-07-02' url: 'https://zxe.io/software/Z80' diff --git a/projects/Z80/CMake/FindBreathe.cmake b/projects/Z80/CMake/FindBreathe.cmake index ec2d8ca..18d243b 100644 --- a/projects/Z80/CMake/FindBreathe.cmake +++ b/projects/Z80/CMake/FindBreathe.cmake @@ -1,31 +1,62 @@ # FindBreathe.cmake -# Copyright (C) 2021-2023 Manuel Sainz de Baranda y Goñi. -# This "find module" is DISTRIBUTED AS PUBLIC DOMAIN. No restrictions apply. +# Copyright (C) 2021-2024 Manuel Sainz de Baranda y Goñi. +# This "find module" is distributed as public domain software. + +#[=======================================================================[.rst: +FindBreathe +----------- + +Find Breathe. + +Result variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project: + +``Breathe_FOUND`` + ``TRUE`` if Breathe was found. + +``Breathe_APIDOC_VERSION`` + The version of the ``breathe-apidoc`` executable that was found. + +``Breathe_VERSION`` + Same as ``Breathe_APIDOC_VERSION``. + +Cache variables +^^^^^^^^^^^^^^^ + +Search results are saved persistently in CMake cache entries: + +``Breathe_APIDOC_EXECUTABLE`` + The full path to the ``breathe-apidoc`` executable. + +#]=======================================================================] include(FindPackageHandleStandardArgs) find_program( - BREATHE_APIDOC_EXECUTABLE + Breathe_APIDOC_EXECUTABLE NAMES breathe-apidoc - DOC "Breathe extension for Sphinx") + DOC "`breathe-apidoc` executable.") -if(BREATHE_APIDOC_EXECUTABLE) +if(Breathe_APIDOC_EXECUTABLE) execute_process( - COMMAND "${BREATHE_APIDOC_EXECUTABLE}" --version - OUTPUT_VARIABLE _output) + COMMAND "${Breathe_APIDOC_EXECUTABLE}" --version + OUTPUT_VARIABLE _Breathe_output) - if("${_output}" MATCHES ".* ([^\n]+)\n") - set(BREATHE_APIDOC_VERSION "${CMAKE_MATCH_1}") + if("${_Breathe_output}" MATCHES ".* ([0-9]+(\\.[0-9]+(\\.[0-9]+)?)?).*\n") + set(Breathe_APIDOC_VERSION "${CMAKE_MATCH_1}") + set(Breathe_VERSION ${Breathe_APIDOC_VERSION}) endif() - unset(_output) + unset(_Breathe_output) endif() find_package_handle_standard_args( Breathe - REQUIRED_VARS BREATHE_APIDOC_EXECUTABLE - VERSION_VAR BREATHE_APIDOC_VERSION) + REQUIRED_VARS Breathe_APIDOC_EXECUTABLE Breathe_APIDOC_VERSION + VERSION_VAR Breathe_VERSION) -mark_as_advanced(BREATHE_APIDOC_EXECUTABLE) +mark_as_advanced(Breathe_APIDOC_EXECUTABLE) # FindBreathe.cmake EOF diff --git a/projects/Z80/CMake/FindSphinx.cmake b/projects/Z80/CMake/FindSphinx.cmake index fe2aeab..e345701 100644 --- a/projects/Z80/CMake/FindSphinx.cmake +++ b/projects/Z80/CMake/FindSphinx.cmake @@ -1,31 +1,117 @@ # FindSphinx.cmake -# Copyright (C) 2021-2023 Manuel Sainz de Baranda y Goñi. -# This "find module" is DISTRIBUTED AS PUBLIC DOMAIN. No restrictions apply. +# Copyright (C) 2021-2026 Manuel Sainz de Baranda y Goñi. +# This "find module" is distributed as public domain software. + +#[=======================================================================[.rst: +FindSphinx +---------- + +Find the Sphinx documentation tools. + +Optional components +^^^^^^^^^^^^^^^^^^^ + +This module supports 4 optional ``COMPONENTS``: + +``apidoc`` + Looks for the ``sphinx-apidoc`` executable. + +``autogen`` + Looks for the ``sphinx-autogen`` executable. + +``build`` + Looks for the ``sphinx-build`` executable. This component is used by default + if no components are specified. + +``quickstart`` + Looks for the ``sphinx-quickstart`` executable. + +Result variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project: + +``Sphinx_FOUND`` + ``TRUE`` if all requested Sphinx tools were found. + +``Sphinx__VERSION`` + The version of the ``sphinx-`` executable that was found, where + ```` and ```` are the uppercase and lowercase names of + the component, respectively. + +``Sphinx_VERSION`` + The version of Sphinx that was found. It is the same as + ``Sphinx_BUILD_VERSION`` if the ``build`` component was requested; otherwise, + it is the same as the first one requested. + +Cache variables +^^^^^^^^^^^^^^^ + +Search results are saved persistently in CMake cache entries: + +``Sphinx__EXECUTABLE`` + The full path to the ``sphinx-`` executable, where ```` + and ```` are the uppercase and lowercase names of the component, + respectively. + +#]=======================================================================] + +set(_Sphinx_required_vars) + +if(NOT Sphinx_FIND_COMPONENTS) + set(Sphinx_FIND_COMPONENTS build) +endif() + +foreach(_Sphinx_tool IN LISTS Sphinx_FIND_COMPONENTS) + if(NOT _Sphinx_tool MATCHES "^(apidoc|autogen|build|quickstart)$") + message(FATAL_ERROR "Invalid components: ${Sphinx_FIND_COMPONENTS}") + endif() + + string(TOUPPER ${_Sphinx_tool} _Sphinx_tool_uppercase) + set(_Sphinx_tool_executable_var Sphinx_${_Sphinx_tool_uppercase}_EXECUTABLE) + set(_Sphinx_tool_version_var Sphinx_${_Sphinx_tool_uppercase}_VERSION) + + list( APPEND _Sphinx_required_vars + ${_Sphinx_tool_executable_var} ${_Sphinx_tool_version_var}) + + find_program( + ${_Sphinx_tool_executable_var} + NAMES sphinx-${_Sphinx_tool} + DOC "`sphinx-${_Sphinx_tool}` executable.") + + if(${_Sphinx_tool_executable_var}) + execute_process( + COMMAND "${${_Sphinx_tool_executable_var}}" --version + OUTPUT_VARIABLE _Sphinx_output) + + if("${_Sphinx_output}" MATCHES ".* ([0-9]+(\\.[0-9]+(\\.[0-9]+)?)?).*\n") + set(${_Sphinx_tool_version_var} "${CMAKE_MATCH_1}") + + if(NOT DEFINED Sphinx_VERSION) + set(Sphinx_VERSION ${${_Sphinx_tool_version_var}}) + endif() + endif() + + unset(_Sphinx_output) + endif() + + mark_as_advanced(${_Sphinx_tool_executable_var}) + unset(_Sphinx_tool_version_var) + unset(_Sphinx_tool_executable_var) + unset(_Sphinx_tool_uppercase) +endforeach() + +if(DEFINED Sphinx_BUILD_VERSION) + set(Sphinx_VERSION ${Sphinx_BUILD_VERSION}) +endif() include(FindPackageHandleStandardArgs) -find_program( - SPHINX_BUILD_EXECUTABLE - NAMES sphinx-build - DOC "Sphinx Documentation Builder") - -if(SPHINX_BUILD_EXECUTABLE) - execute_process( - COMMAND "${SPHINX_BUILD_EXECUTABLE}" --version - OUTPUT_VARIABLE _output) - - if("${_output}" MATCHES ".* ([^\n]+)\n") - set(SPHINX_BUILD_VERSION "${CMAKE_MATCH_1}") - endif() - - unset(_output) -endif() - find_package_handle_standard_args( Sphinx - REQUIRED_VARS SPHINX_BUILD_EXECUTABLE - VERSION_VAR SPHINX_BUILD_VERSION) + REQUIRED_VARS ${_Sphinx_required_vars} + VERSION_VAR Sphinx_VERSION) -mark_as_advanced(SPHINX_BUILD_EXECUTABLE) +unset(_Sphinx_required_vars) # FindSphinx.cmake EOF diff --git a/projects/Z80/CMake/FindZeta.cmake b/projects/Z80/CMake/FindZeta.cmake index 6210f93..1586702 100644 --- a/projects/Z80/CMake/FindZeta.cmake +++ b/projects/Z80/CMake/FindZeta.cmake @@ -1,73 +1,191 @@ -# Zeta - FindZeta.cmake +# FindZeta.cmake # ______ ______________ ___ # |__ / | ___|___ ___|/ \ # / /__| __| | | / - \ # /______|_____| |__| /__/ \__\ # Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. -# This "find module" is DISTRIBUTED AS PUBLIC DOMAIN. No restrictions apply. +# This "find module" is distributed as public domain software. + +#[=======================================================================[.rst: +FindZeta +-------- + +Find the Zeta library. + +Search behavior +^^^^^^^^^^^^^^^ + +By default, this module will search for Zeta in the directory specified by the +``ZETA_DIR`` environment variable. If this variable is not defined, it will +search in ``PROJECT_BINARY_DIR`` and the following paths relative to +``PROJECT_SOURCE_DIR`` (in the listed order): + +* :file:`.` +* :file:`3rd` +* :file:`3rd-party` +* :file:`3rd-parties` +* :file:`3rd_party` +* :file:`3rd_parties` +* :file:`3rdparty` +* :file:`3rdparties` +* :file:`third-party` +* :file:`third-parties` +* :file:`third_party` +* :file:`third_parties` +* :file:`thirdparty` +* :file:`thirdparties` +* :file:`dependencies` +* :file:`deps` +* :file:`extern` +* :file:`external` +* :file:`externals` +* :file:`..` + +Finally, if the relaive search is unsuccessful, the module will search for the +headers of the Zeta library in system include directories. + +Input variables +^^^^^^^^^^^^^^^ + +The search process can be controlled by using the following variables: + +``Zeta_IGNORE_ZETA_DIR`` + Set this variable to ``TRUE`` to ignore the ``ZETA_DIR`` environment variable. + +``Zeta_SKIP_RELATIVE_SEARCH`` + If set to ``TRUE``, the module will not search in ``PROJECT_BINARY_DIR`` and + paths relative to ``PROJECT_BINARY_DIR`` before trying system include + directories. + +``Zeta_SKIP_SYSTEM_SEARCH`` + If set to ``TRUE``, the module will not search in system include directories. + +Imported targets +^^^^^^^^^^^^^^^^ + +This module defines the following ``INTERFACE IMPORTED`` target: + +``Zeta`` + The Zeta library, if found. + +Result variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project: + +``Zeta_FOUND`` + ``TRUE`` if the Zeta library was found. + +``Zeta_INCLUDE_DIRS`` + The include directory needed to use Zeta. + +``Zeta_VERSION`` + The version of the Zeta library that was found. + +``Zeta_VERSION_MAJOR`` + First version number component of the ``Zeta_VERSION`` variable. + +``Zeta_VERSION_MINOR`` + Second version number component of the ``Zeta_VERSION`` variable. + +``Zeta_VERSION_MICRO`` + Third version number component of the ``Zeta_VERSION`` variable. + +``Zeta_VERSION_PATCH`` + Same as ``Zeta_VERSION_MICRO``. + +Cache Variables +^^^^^^^^^^^^^^^ + +Search results are saved persistently in CMake cache entries: + +``Zeta_INCLUDE_DIR`` + Same as ``Zeta_INCLUDE_DIRS``. + +Hints +^^^^^ + +The user can set the ``ZETA_DIR`` environment variable to specify the include +directory of the Zeta library or the directory where its tarball has been +extracted. However, if this variable is defined and Zeta is not found in the +specified directory, the module will fail and will not look anywhere else. + +#]=======================================================================] include(FindPackageHandleStandardArgs) -if(NOT DEFINED Zeta_FIND_RELATIVE OR Zeta_FIND_RELATIVE) +if( DEFINED ENV{ZETA_DIR} AND + (NOT DEFINED Zeta_IGNORE_ZETA_DIR OR NOT Zeta_IGNORE_ZETA_DIR) +) find_path( Zeta_INCLUDE_DIR "Z/version.h" - PATHS "${PROJECT_BINARY_DIR}/Zeta/API" - "${PROJECT_BINARY_DIR}" - "${PROJECT_SOURCE_DIR}/Zeta/API" - "${PROJECT_SOURCE_DIR}" - "${PROJECT_SOURCE_DIR}/3rd/Zeta/API" - "${PROJECT_SOURCE_DIR}/3rd" - "${PROJECT_SOURCE_DIR}/3rd-party/Zeta/API" - "${PROJECT_SOURCE_DIR}/3rd-party" - "${PROJECT_SOURCE_DIR}/3rd-parties/Zeta/API" - "${PROJECT_SOURCE_DIR}/3rd-parties" - "${PROJECT_SOURCE_DIR}/3rd_party/Zeta/API" - "${PROJECT_SOURCE_DIR}/3rd_party" - "${PROJECT_SOURCE_DIR}/3rd_parties/Zeta/API" - "${PROJECT_SOURCE_DIR}/3rd_parties" - "${PROJECT_SOURCE_DIR}/3rdparty/Zeta/API" - "${PROJECT_SOURCE_DIR}/3rdparty" - "${PROJECT_SOURCE_DIR}/3rdparties/Zeta/API" - "${PROJECT_SOURCE_DIR}/3rdparties" - "${PROJECT_SOURCE_DIR}/third-party/Zeta/API" - "${PROJECT_SOURCE_DIR}/third-party" - "${PROJECT_SOURCE_DIR}/third-parties/Zeta/API" - "${PROJECT_SOURCE_DIR}/third-parties" - "${PROJECT_SOURCE_DIR}/third_party/Zeta/API" - "${PROJECT_SOURCE_DIR}/third_party" - "${PROJECT_SOURCE_DIR}/third_parties/Zeta/API" - "${PROJECT_SOURCE_DIR}/third_parties" - "${PROJECT_SOURCE_DIR}/thirdparty/Zeta/API" - "${PROJECT_SOURCE_DIR}/thirdparty" - "${PROJECT_SOURCE_DIR}/thirdparties/Zeta/API" - "${PROJECT_SOURCE_DIR}/thirdparties" - "${PROJECT_SOURCE_DIR}/dependencies/Zeta/API" - "${PROJECT_SOURCE_DIR}/dependencies" - "${PROJECT_SOURCE_DIR}/deps/Zeta/API" - "${PROJECT_SOURCE_DIR}/deps" - "${PROJECT_SOURCE_DIR}/extern/Zeta/API" - "${PROJECT_SOURCE_DIR}/extern" - "${PROJECT_SOURCE_DIR}/external/Zeta/API" - "${PROJECT_SOURCE_DIR}/external" - "${PROJECT_SOURCE_DIR}/externals/Zeta/API" - "${PROJECT_SOURCE_DIR}/externals" - "${PROJECT_SOURCE_DIR}/../zeta-src/API" - "${PROJECT_SOURCE_DIR}/../Zeta/API" - "${PROJECT_SOURCE_DIR}/.." + PATHS "$ENV{ZETA_DIR}" NO_DEFAULT_PATH) + +else() + if(NOT DEFINED Zeta_SKIP_RELATIVE_SEARCH OR NOT Zeta_SKIP_RELATIVE_SEARCH) + find_path( + Zeta_INCLUDE_DIR "Z/version.h" + PATHS "${PROJECT_BINARY_DIR}/Zeta/API" + "${PROJECT_BINARY_DIR}" + "${PROJECT_SOURCE_DIR}/Zeta/API" + "${PROJECT_SOURCE_DIR}" + "${PROJECT_SOURCE_DIR}/3rd/Zeta/API" + "${PROJECT_SOURCE_DIR}/3rd" + "${PROJECT_SOURCE_DIR}/3rd-party/Zeta/API" + "${PROJECT_SOURCE_DIR}/3rd-party" + "${PROJECT_SOURCE_DIR}/3rd-parties/Zeta/API" + "${PROJECT_SOURCE_DIR}/3rd-parties" + "${PROJECT_SOURCE_DIR}/3rd_party/Zeta/API" + "${PROJECT_SOURCE_DIR}/3rd_party" + "${PROJECT_SOURCE_DIR}/3rd_parties/Zeta/API" + "${PROJECT_SOURCE_DIR}/3rd_parties" + "${PROJECT_SOURCE_DIR}/3rdparty/Zeta/API" + "${PROJECT_SOURCE_DIR}/3rdparty" + "${PROJECT_SOURCE_DIR}/3rdparties/Zeta/API" + "${PROJECT_SOURCE_DIR}/3rdparties" + "${PROJECT_SOURCE_DIR}/third-party/Zeta/API" + "${PROJECT_SOURCE_DIR}/third-party" + "${PROJECT_SOURCE_DIR}/third-parties/Zeta/API" + "${PROJECT_SOURCE_DIR}/third-parties" + "${PROJECT_SOURCE_DIR}/third_party/Zeta/API" + "${PROJECT_SOURCE_DIR}/third_party" + "${PROJECT_SOURCE_DIR}/third_parties/Zeta/API" + "${PROJECT_SOURCE_DIR}/third_parties" + "${PROJECT_SOURCE_DIR}/thirdparty/Zeta/API" + "${PROJECT_SOURCE_DIR}/thirdparty" + "${PROJECT_SOURCE_DIR}/thirdparties/Zeta/API" + "${PROJECT_SOURCE_DIR}/thirdparties" + "${PROJECT_SOURCE_DIR}/dependencies/Zeta/API" + "${PROJECT_SOURCE_DIR}/dependencies" + "${PROJECT_SOURCE_DIR}/deps/Zeta/API" + "${PROJECT_SOURCE_DIR}/deps" + "${PROJECT_SOURCE_DIR}/extern/Zeta/API" + "${PROJECT_SOURCE_DIR}/extern" + "${PROJECT_SOURCE_DIR}/external/Zeta/API" + "${PROJECT_SOURCE_DIR}/external" + "${PROJECT_SOURCE_DIR}/externals/Zeta/API" + "${PROJECT_SOURCE_DIR}/externals" + "${PROJECT_SOURCE_DIR}/../zeta-src/API" + "${PROJECT_SOURCE_DIR}/../Zeta/API" + "${PROJECT_SOURCE_DIR}/.." + NO_DEFAULT_PATH) + endif() + + if(NOT DEFINED Zeta_SKIP_SYSTEM_SEARCH OR NOT Zeta_SKIP_SYSTEM_SEARCH) + find_path( + Zeta_INCLUDE_DIR "Z/version.h" + HINTS ENV CPATH + ENV C_INCLUDE_PATH + ENV CPLUS_INCLUDE_PATH + ENV OBJC_INCLUDE_PATH) + endif() endif() -find_path( - Zeta_INCLUDE_DIR "Z/version.h" - HINTS ENV CPATH - ENV C_INCLUDE_PATH - ENV CPLUS_INCLUDE_PATH - ENV OBJC_INCLUDE_PATH) - if(Zeta_INCLUDE_DIR AND EXISTS "${Zeta_INCLUDE_DIR}/Z/version.h") - file(READ "${Zeta_INCLUDE_DIR}/Z/version.h" _) + file(READ "${Zeta_INCLUDE_DIR}/Z/version.h" _Zeta_Z_version_h) - if(_ MATCHES ".*Z_LIBRARY_VERSION_STRING \"([^\n]*)\".*") + if(_Zeta_Z_version_h MATCHES ".*Z_LIBRARY_VERSION_STRING \"([^\n]*)\".*") set(Zeta_VERSION ${CMAKE_MATCH_1}) if(Zeta_VERSION MATCHES "^([0-9]+)\\.([0-9]+)") @@ -75,14 +193,16 @@ if(Zeta_INCLUDE_DIR AND EXISTS "${Zeta_INCLUDE_DIR}/Z/version.h") set(Zeta_VERSION_MINOR ${CMAKE_MATCH_2}) if(Zeta_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)") - set(Zeta_VERSION_PATCH ${CMAKE_MATCH_3}) + set(Zeta_VERSION_MICRO ${CMAKE_MATCH_3}) + set(Zeta_VERSION_PATCH ${Zeta_VERSION_MICRO}) else() + set(Zeta_VERSION_MICRO 0) set(Zeta_VERSION_PATCH 0) endif() endif() endif() - unset(_) + unset(_Zeta_Z_version_h) endif() find_package_handle_standard_args( @@ -92,6 +212,7 @@ find_package_handle_standard_args( VERSION_VAR Zeta_VERSION) if(Zeta_FOUND AND NOT TARGET Zeta) + set(Zeta_INCLUDE_DIRS "${Zeta_INCLUDE_DIR}") add_library(Zeta INTERFACE IMPORTED) if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_LESS 3.11) diff --git a/projects/Z80/CMakeLists.txt b/projects/Z80/CMakeLists.txt index 785299f..af3e15f 100644 --- a/projects/Z80/CMakeLists.txt +++ b/projects/Z80/CMakeLists.txt @@ -4,7 +4,7 @@ # \/__/ /\_\ __ \\ \/\ \ # /\_____\\_____\\_____\ # Zilog \/_____//_____//_____/ CPU Emulator -# Copyright (C) 1999-2024 Manuel Sainz de Baranda y Goñi. +# Copyright (C) 1999-2026 Manuel Sainz de Baranda y Goñi. # Released under the terms of the GNU Lesser General Public License v3. cmake_minimum_required( @@ -24,7 +24,7 @@ add_compile_options(-Wall ) file(READ "${CMAKE_CURRENT_SOURCE_DIR}/API/Z80.h" _) -string(REGEX MATCH ".*Z80_LIBRARY_VERSION_STRING \"([^\n]*)\".*" _ ${_}) +string(REGEX MATCH ".*Z80_LIBRARY_VERSION_STRING \"([^\"]+)\".*" _ ${_}) project(Z80 VERSION ${CMAKE_MATCH_1} @@ -33,13 +33,13 @@ project(Z80 HOMEPAGE_URL "https://zxe.io/software/Z80") unset(_) -message("${PROJECT_NAME} v${PROJECT_VERSION}") + +execute_process( + COMMAND ${CMAKE_COMMAND} -E echo + "${PROJECT_NAME} v${PROJECT_VERSION}") include(GNUInstallDirs) -#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -mcpu=cortex-m33 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard") -#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -mcpu=cortex-m33 -mthumb") - set(${PROJECT_NAME}_DEPOT_LOCATION "http://zxe.io/depot" CACHE STRING "${PROJECT_NAME}: \ @@ -101,9 +101,15 @@ Install the standard text documents distributed with the package: \ AUTHORS, COPYING, COPYING.LESSER, HISTORY, README and THANKS." NO) -option(${PROJECT_NAME}_WITH_TESTS +option(${PROJECT_NAME}_WITH_STEP_TESTING_TOOL "${PROJECT_NAME}: \ -Build the testing tool." +Build `step-test-${PROJECT_NAME}`, a tool for unit tests in JSON format." +NO) + +option(${PROJECT_NAME}_WITH_TESTING_TOOL +"${PROJECT_NAME}: \ +Build `test-${PROJECT_NAME}`, a tool that runs various Z80-specific tests for \ +CP/M and ZX Spectrum." NO) option(${PROJECT_NAME}_WITH_EXECUTE @@ -126,8 +132,13 @@ NO) option(${PROJECT_NAME}_WITH_PARITY_COMPUTATION "${PROJECT_NAME}: \ Enable actual parity calculation for the P/V flag instead of using a \ -table of precomputed values (this is for benchmarks, DO NOT ENABLE in \ -production builds)." +table of precomputed values (NOT RECOMMENDED for production builds)." +NO) + +option(${PROJECT_NAME}_WITH_PRECOMPUTED_DAA +"${PROJECT_NAME}: \ +Use a table of precomputed values to emulate the `daa` instruction (NOT \ +RECOMMENDED for production builds)." NO) option(${PROJECT_NAME}_WITH_Q @@ -140,6 +151,14 @@ option(${PROJECT_NAME}_WITH_SPECIAL_RESET Build the implementation of the special RESET." NO) +option(${PROJECT_NAME}_WITH_RESET_SIGNAL +"${PROJECT_NAME}: \ +Build the implementation of the external reset signal check. When enabled, a \ +pointer to a volatile byte (reset_signal) is checked at every instruction \ +boundary. A non-zero value causes z80_run to exit immediately, allowing \ +hardware-in-the-loop emulators to respond to a physical RESET line." +NO) + option(${PROJECT_NAME}_WITH_UNOFFICIAL_RETI "${PROJECT_NAME}: \ Configure the undocumented instructions ED5Dh, ED6Dh and ED7Dh as `reti` \ @@ -153,6 +172,11 @@ causes the P/V flag to be reset when a maskable interrupt is accepted \ during the execution of the `ld a,{i|r}` instructions." NO) +option(${PROJECT_NAME}_WITH_CODE_GENERATION_TOOLS +"${PROJECT_NAME}: \ +Build the tools that have been used to generate parts of the source code." +NO) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake") find_package(Zeta REQUIRED) @@ -195,17 +219,25 @@ else() set(PROJECT_VERSION_PATCH 0) endif() + file(READ "${CMAKE_CURRENT_SOURCE_DIR}/README" _) + string(REGEX MATCH ".*Copyright \\(C\\) ([^ ]+) (([^. \t\n]+ ?)*[^. \t\n]+).*" _ ${_}) + set(RC_COPYRIGHT_YEAR ${CMAKE_MATCH_1}) + set(RC_AUTHOR ${CMAKE_MATCH_2}) + unset(_) + configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/sources/Z80.rc.in" "${CMAKE_CURRENT_BINARY_DIR}/Z80.rc" @ONLY) + unset(RC_COPYRIGHT_YEAR) + unset(RC_AUTHOR) target_sources(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/Z80.rc") endif() if(${PROJECT_NAME}_NOSTDLIB_FLAGS STREQUAL "Auto") if(MSVC) - target_compile_definitions(${PROJECT_NAME} PRIVATE Z80_WITH_WINDOWS_DLL_MAIN) + target_compile_definitions(${PROJECT_NAME} PRIVATE Z80_WITH_DLL_MAIN_CRT_STARTUP) target_link_options(${PROJECT_NAME} PRIVATE "/NODEFAULTLIB") elseif(APPLE) if(CMAKE_C_COMPILER_ID MATCHES "^(AppleClang|Clang|GNU)$") @@ -229,7 +261,9 @@ target_compile_definitions( $<$:Z80_WITH_FULL_IM0> $<$:Z80_WITH_IM0_RETX_NOTIFICATIONS> $<$:Z80_WITH_PARITY_COMPUTATION> + $<$:Z80_WITH_PRECOMPUTED_DAA> $<$:Z80_WITH_Q> + $<$:Z80_WITH_RESET_SIGNAL> $<$:Z80_WITH_SPECIAL_RESET> $<$:Z80_WITH_UNOFFICIAL_RETI> $<$:Z80_WITH_ZILOG_NMOS_LD_A_IR_BUG>) @@ -245,12 +279,10 @@ install(TARGETS ${PROJECT_NAME} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" COMPONENT ${PROJECT_NAME}_Development) -if( NOT ${PROJECT_NAME}_OBJECT_LIBS AND - (${PROJECT_NAME}_WITH_CMAKE_SUPPORT OR ${PROJECT_NAME}_WITH_PKGCONFIG_SUPPORT) -) - include(CMakePackageConfigHelpers) - +if(NOT ${PROJECT_NAME}_OBJECT_LIBS) if(${PROJECT_NAME}_WITH_CMAKE_SUPPORT) + include(CMakePackageConfigHelpers) + if(BUILD_SHARED_LIBS) set(_type Shared) else() @@ -274,9 +306,8 @@ if( NOT ${PROJECT_NAME}_OBJECT_LIBS AND "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" INSTALL_DESTINATION "${${PROJECT_NAME}_INSTALL_CMAKEDIR}") - install(FILES - "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" DESTINATION "${${PROJECT_NAME}_INSTALL_CMAKEDIR}" COMPONENT ${PROJECT_NAME}_Development) endif() @@ -308,11 +339,28 @@ if(${PROJECT_NAME}_WITH_HTML_DOCUMENTATION OR ${PROJECT_NAME}_WITH_PDF_DOCUMENTA add_subdirectory(documentation) endif() -if(${PROJECT_NAME}_WITH_TESTS) +if(${PROJECT_NAME}_WITH_STEP_TESTING_TOOL) + find_package(cJSON REQUIRED) + find_package(Z80InsnClock REQUIRED) + + add_executable(step-test-${PROJECT_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/sources/step-test-Z80.c") + target_link_libraries(step-test-${PROJECT_NAME} PRIVATE ${PROJECT_NAME} cjson Z80InsnClock) + + target_compile_definitions( + step-test-${PROJECT_NAME} PRIVATE + $<$:STEP_TEST_Z80_WITH_EXECUTE>) + + install(TARGETS step-test-${PROJECT_NAME} + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + COMPONENT ${PROJECT_NAME}_Testing + EXCLUDE_FROM_ALL) +endif() + +if(${PROJECT_NAME}_WITH_TESTING_TOOL) include(CTest) - find_package(ZLIB QUIET) find_package(libzip QUIET) + find_package(ZLIB QUIET) add_executable(test-${PROJECT_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/sources/test-Z80.c") target_link_libraries(test-${PROJECT_NAME} PRIVATE ${PROJECT_NAME}) @@ -326,9 +374,14 @@ if(${PROJECT_NAME}_WITH_TESTS) target_compile_definitions(test-${PROJECT_NAME} PRIVATE TEST_Z80_WITH_EXECUTE) endif() + install(TARGETS test-${PROJECT_NAME} + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + COMPONENT ${PROJECT_NAME}_Testing + EXCLUDE_FROM_ALL) + if(${PROJECT_NAME}_FETCH_TEST_FILES) - function(_fetch_files _file_list _location _destination_dir) - file(STRINGS "${_file_list}" _lines) + function(_fetch_files _list_path _location _destination_dir) + file(STRINGS "${_list_path}" _lines) if(_location MATCHES ".*://.*") set(_message_action "Downloading") @@ -398,15 +451,15 @@ if(${PROJECT_NAME}_WITH_TESTS) (NOT ZLIB_FOUND OR NOT libzip_FOUND) ) message(WARNING - "libzip or zlib were not found on your system, which will cause the " - "test-Z80 tool to be built without archive extraction support. When " - "this happens, the build script extracts those test files that are " - "compressed so that test-Z80 can use them later, but this has failed " - "because the version of CMake you are using is too old and does not " - "support archive extraction.\n" - "To fix this, extract all files with `.tar.gz` or `.zip` extension " - "located in " - "`${CMAKE_CURRENT_BINARY_DIR}/depot/software/**/`") + "libzip or zlib could not be found on your system, which causes " + "`test-Z80` to be built without archive extraction support. " + "In this case, the build system normally extracts compressed test " + "files so that `test-Z80` can use them later, but this step has " + "failed because the version of CMake you are using is too old and " + "does not support archive extraction.\n" + "To fix this, extract all archives with the \".tar.gz\" or \".zip\" " + "extension located under " + "\"${CMAKE_CURRENT_BINARY_DIR}/depot/software/**/\".") endif() endif() @@ -416,8 +469,14 @@ if(${PROJECT_NAME}_WITH_TESTS) set(_depot_dir "${${PROJECT_NAME}_DEPOT_LOCATION}") endif() + set(_test_name "Z80 test suites for CP/M and ZX Spectrum") + + if(${PROJECT_NAME}_WITH_EXECUTE) + string(APPEND _test_name " (using `z80_execute`)") + endif() + add_test( - NAME test-${PROJECT_NAME} + NAME "${_test_name}" COMMAND test-${PROJECT_NAME} --path "${_depot_dir}/firmware" --path "${_depot_dir}/software/POSIX" @@ -425,11 +484,49 @@ if(${PROJECT_NAME}_WITH_TESTS) --all WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + unset(_test_name) + + if(${PROJECT_NAME}_WITH_EXECUTE) + add_test( + NAME "Z80 test suites for CP/M and ZX Spectrum (using `z80_run`)" + COMMAND test-${PROJECT_NAME} + --run + --path "${_depot_dir}/firmware" + --path "${_depot_dir}/software/POSIX" + --path "${_depot_dir}/software/ZX Spectrum" + --all + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + endif() + unset(_depot_dir) endif() +if(${PROJECT_NAME}_WITH_CODE_GENERATION_TOOLS) + add_executable( + ${PROJECT_NAME}-generate-daa-af-table + "${CMAKE_CURRENT_SOURCE_DIR}/sources/generate-daa-af-table.c") + + set_target_properties( + ${PROJECT_NAME}-generate-daa-af-table + PROPERTIES OUTPUT_NAME generate-daa-af-table) + + target_link_libraries(${PROJECT_NAME}-generate-daa-af-table PRIVATE ${PROJECT_NAME}) + + add_executable( + ${PROJECT_NAME}-generate-pf-parity-table + "${CMAKE_CURRENT_SOURCE_DIR}/sources/generate-pf-parity-table.c") + + set_target_properties( + ${PROJECT_NAME}-generate-pf-parity-table + PROPERTIES OUTPUT_NAME generate-pf-parity-table) + + target_link_libraries(${PROJECT_NAME}-generate-pf-parity-table PRIVATE Zeta) +endif() + if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) - message("${PROJECT_NAME} END") + execute_process( + COMMAND ${CMAKE_COMMAND} -E echo + "${PROJECT_NAME} v${PROJECT_VERSION} END") endif() # CMakeLists.txt EOF diff --git a/projects/Z80/HISTORY b/projects/Z80/HISTORY index a6f6eea..7cba882 100644 --- a/projects/Z80/HISTORY +++ b/projects/Z80/HISTORY @@ -1,4 +1,4 @@ -Z80 v0.2-pre (2024-04-18) +Z80 v0.2-pre (2025-07-02) ========================= This is an important update that addresses a number of issues and also includes @@ -12,97 +12,107 @@ Changes: 4. Switched the build system from Premake to CMake. 5. Switched to Zeta v0.1. 6. Added pkg-config support. - 7. Added the following files to the project: .vimrc, CITATION.cff, file_id.diz - and THANKS. + 7. Added the following files to the project: .vimrc, CITATION.cff and THANKS. 8. Added detailed documentation. 9. Added Pascal binding, courtesy of Zoran Vučenović. -10. Added tests. -11. Added public macros for checking the library version, working with flags, +10. Added `test-Z80`, a tool that runs various Z80-specific tests for CP/M and + ZX Spectrum. +11. Added `step-test-Z80`, a tool for unit tests in JSON format. +12. Renamed the macros `CPU_Z80_DEPENDENCIES_H` and `CPU_Z80_STATIC` to + `Z80_EXTERNAL_HEADER` and `Z80_STATIC`, respectively. +13. Added public macros for checking the library version, working with flags, accessing the 16-bit registers and other purposes. -12. Added the ability to end the emulation loop immediately, and the `z80_break` +14. Added the ability to end the emulation loop immediately, and the `z80_break` function. -13. Added the `z80_execute` function for running a simplified emulation without +15. Added the `z80_execute` function for running a simplified emulation without RESET and interrupts. -14. Added the `z80_refresh_address` function for getting the refresh address of - the current M1 cycle. -15. Added the `z80_in_cycle` and `z80_out_cycle` functions for obtaining the +16. Added the `z80_in_cycle` and `z80_out_cycle` functions for obtaining the clock cycle at which the I/O M-cycle begins, relative to the start of the instruction. -16. Renamed the `z80_reset` function to `z80_instant_reset`. -17. Added optional emulation of the special RESET, and the `z80_special_reset` +17. Added the `z80_r` function for getting the current value of the R register. +18. Added the `z80_refresh_address` function for getting the refresh address of + the current M1 cycle. +19. Added the `z80_wait` function for inserting wait states. +20. Renamed the `z80_reset` function to `z80_instant_reset`. +21. Added optional emulation of the special RESET, and the `z80_special_reset` function. -18. Added the `Z80::fetch_opcode` and `Z80::fetch` callbacks for performing - opcode fetch operations and memory read operations on instruction data - respectively. -19. Added the `Z80::nop` callback for performing disregarded opcode fetch +22. Added the `Z80::fetch_opcode` and `Z80::fetch` callbacks for performing, + respectively, opcode fetch operations and memory read operations on + instruction data. +23. Added the `Z80::nop` callback for performing disregarded opcode fetch operations during internal NOP M-cycles. -20. Added emulation of the NMI acknowledge M-cycle through the new `Z80::nmia` +24. Added emulation of the NMI acknowledge M-cycle through the new `Z80::nmia` callback. -21. Added emulation of the INT acknowledge M-cycle through the new `Z80::inta` +25. Added emulation of the INT acknowledge M-cycle through the new `Z80::inta` callback, which replaces `Z80::int_data`. -22. Added optional full emulation of the interrupt mode 0, along with the new +26. Added optional full emulation of the interrupt mode 0, along with the new `Z80::int_fetch` callback for performing bus read operations on instruction data. If not enabled at compile-time, the old simplified emulation is built, which supports only the most typical instructions. -23. Added four callbacks for notifying the execution of important instructions: +27. Added four callbacks for notifying the execution of important instructions: `Z80::ld_i_a`, `Z80::ld_r_a`, `Z80::reti` and `Z80::retn`. -24. Added hooking functionality through the `ld h,h` instruction and the new +28. Added hooking functionality through the `ld h,h` instruction and the new `Z80::hook` callback. -25. Added the `Z80::illegal` callback for delegating the emulation of illegal +29. Added the `Z80::illegal` callback for delegating the emulation of illegal instructions. -26. Added emulation options that can be configured at runtime. -27. Removed `Z80::state`. Replaced with individual members for the registers, +30. Added emulation options that can be configured at runtime. +31. Removed `Z80::state`. Replaced with individual members for the registers, the interrupt enable flip-flops and the interrupt mode. -28. Removed the superfluous EI flag. The previous opcode is checked instead, +32. Removed the superfluous EI flag. The previous opcode is checked instead, which is faster and makes the `Z80` object smaller. -29. Removed all module-related stuff. -30. Added emulation of the additional flag changes performed during the extra 5 +33. Removed all module-related stuff. +34. Added emulation of the additional flag changes performed during the extra 5 clock cycles of the following instructions: `ldir`, `lddr`, `cpir`, `cpdr`, `inir`, `indr`, `otir` and `otdr`. -31. Added emulation of the interrupt acceptance deferral that occurs during the +35. Added emulation of the interrupt acceptance deferral that occurs during the `reti` and `retn` instructions. -32. Added MEMPTR emulation. The `bit N,(hl)` instruction now produces a correct +36. Added MEMPTR emulation. The `bit N,(hl)` instruction now produces a correct value of F. -33. Added optional emulation of Q. If enabled at compile-time, the `ccf` and +37. Added optional emulation of Q. If enabled at compile-time, the `ccf` and `scf` instructions will produce a correct value of F. -34. Added emulation of the `out (c),255` instruction (Zilog Z80 CMOS). -35. Added optional emulation of the bug affecting the `ld a,{i|r}` instructions +38. Added emulation of the `out (c),255` instruction (Zilog Z80 CMOS). +39. Added optional emulation of the bug affecting the `ld a,{i|r}` instructions (Zilog Z80 NMOS). If enabled at compile-time and configured at runtime, the P/V flag will be reset if an INT is accepted during the execution of these instructions. -36. Increased granularity. The emulator can now stop directly after fetching a +40. Added an optional implementation of the parity calculation for the P/V flag + that performs the actual computation instead of using a table of precomputed + values. +41. Added an optional implementation of the `daa` instruction that uses a table + of precomputed values. +42. Increased granularity. The emulator can now stop directly after fetching a prefix DDh or FDh if it runs out of clock cycles. This also works during the INT response in mode 0. -37. Reimplemented the HALT state. The emulation should now be fully accurate. +43. Reimplemented the HALT state. The emulation should now be fully accurate. HALTskip optimization is also supported. -38. Fixed a bug in the `sll` instruction. -39. Fixed a bug in the `INX` and `OUTX` macros affecting the S and N flags. -40. Fixed a bug in the `OUTX` macro affecting the MSByte of the port number. -41. Fixed the clock cycles of the `dec XY` and `in (c)` instructions. -42. Fixed the `read_16` function so that the order of the memory read operations +44. Fixed a bug in the `sll` instruction. +45. Fixed a bug in the `INX` and `OUTX` macros affecting the S and N flags. +46. Fixed a bug in the `OUTX` macro affecting the MSByte of the port number. +47. Fixed the clock cycles of the `dec XY` and `in (c)` instructions. +48. Fixed the `read_16` function so that the order of the memory read operations is not determined by the order in which the compiler evaluates expressions. -43. Fixed the order in which the memory write operations are performed when the +49. Fixed the order in which the memory write operations are performed when the SP register is involved. This affects the NMI response, the INT response in modes 1 and 2, and the following instructions: `ex (sp),{hl|XY}`, `push TT`, `push XY`, `call WORD`, `call Z,WORD` and `rst N`. -44. Fixed the handling of illegal instructions to avoid stack overflows in long +50. Fixed the handling of illegal instructions to avoid stack overflows in long sequences of DDh/FDh prefixes. -45. Fixed several implicit conversions to avoid warnings about loss of sign and +51. Fixed several implicit conversions to avoid warnings about loss of sign and precision. -46. Fixed some bitwise operations to avoid undefined behavior and arithmetic +52. Fixed some bitwise operations to avoid undefined behavior and arithmetic right shifts on signed integers. -47. Fixed violations of the C standard in several identifiers. -48. Renamed the 8-bit register lists: X/Y to J/K; J/K and P/Q to O/P. -49. Replaced all P/V overflow computation functions with a single, faster macro. -50. Replaced all register resolution functions with macros. -51. Replaced all `ld {J,K|O,P}` instructions that have the same destination and +53. Fixed violations of the C standard in several identifiers. +54. Renamed the 8-bit register lists: X/Y to J/K; J/K and P/Q to O/P. +55. Replaced all P/V overflow computation functions with a single, faster macro. +56. Replaced all register resolution functions with macros. +57. Replaced all `ld {J,K|O,P}` instructions that have the same destination and source register with NOPs. In addition, the "illegal" forms of the following instructions are now executed without using the illegal instruction handler: `ld O,P`, `ld O,BYTE`, `U [a,]P` and `V O`. -52. Optimizations in flag computation and condition evaluation. -53. New source code comments and improvements to existing ones. -54. Improved code aesthetics. -55. Other improvements, optimizations and minor changes. +58. Optimizations in flag computation and condition evaluation. +59. New source code comments and improvements to existing ones. +60. Improved code aesthetics. +61. Other improvements, optimizations and minor changes. Z80 v0.1 (2018-11-10) diff --git a/projects/Z80/README b/projects/Z80/README index fdb2b7d..8c2f088 100644 --- a/projects/Z80/README +++ b/projects/Z80/README @@ -15,7 +15,7 @@ | Zilog Z80 CPU Emulator | | version 0.2 | | | -| Copyright (C) 1999-2024 Manuel Sainz de Baranda y Goñi | +| Copyright (C) 1999-2026 Manuel Sainz de Baranda y Goñi | | Released under the terms of the GNU Lesser General Public License v3 | | | | https://zxe.io/software/Z80 | @@ -41,7 +41,7 @@ need for major changes. ============ This Z80 CPU emulator has a classic design with instruction-level granularity -that delivers the best performance, whilst offering a reasonable flexibility to +that delivers high performance, whilst offering reasonable flexibility to achieve precision down to the T-state level. Instruction-level granularity implies that, except in a few well-defined cases, @@ -59,33 +59,41 @@ Test Suite", Patrik Rak's "Zilog Z80 CPU Test Suite" and Peter Helcmanovsky's "Z80 Block Flags Test", to name a few. -3. Installation -================ +3. Installation from source code +================================= + +3.1. Prerequisites You will need CMake v3.14 or later to build the package and, optionally, recent versions of Doxygen, Sphinx and Breathe to compile the documentation. Also, make sure that you have LaTeX with PDF support installed on your system if you want to generate the documentation in PDF format. -The emulator requires some types and macros included in Zeta (https://zeta.st), -a dependency-free, header-only library used to retain compatibility with most C -compilers. Install Zeta or extract its source code tarball to the root directory -of the Z80 project or its parent directory. Zeta is the sole dependency; the -emulator is a freestanding implementation and as such does not depend on the C +The Z80 library requires some types and macros included in Zeta, a header-only, +dependency-free library used for portability reasons. Install Zeta or extract +its source code tarball to the root directory of the Z80 project or its parent +directory. Zeta is the sole dependency; the emulator does not depend on the C standard library. -Once the prerequisites are met, create a directory and run cmake from there to +Lastly, the package includes two testing tools, which are optional to build. +The first one runs various Z80-specific tests for CP/M and ZX Spectrum, and will +use libzip and zlib if they are available on your system. The second tool is for +unit tests in JSON format and requires the cJSON and Z80InsnClock libraries. + +3.2. Configure + +Once the prerequisites are met, create a directory and run `cmake` from there to prepare the build system: $ mkdir build $ cd build $ cmake [options] -The resulting build files can be configured by passing options to cmake. To show -a complete list of those available along with their current settings, type the -following: +The resulting build files can be configured by passing options to `cmake`. To +show a complete list of those available along with their current settings, type +the following: - $ cmake -LAH + $ cmake -LAH -N -B . If in doubt, read the CMake documentation for more information on configuration options. The following are some of the most relevant standard options of CMake: @@ -98,6 +106,11 @@ options. The following are some of the most relevant standard options of CMake: Choose the type of build (configuration) to generate. The default is `Release`. + -DCMAKE_INSTALL_NAME_DIR="" + Specify the directory portion of the dynamic library install name on + Apple platforms (for installed shared libraries). + Not defined by default. + -DCMAKE_INSTALL_PREFIX="" Specify the installation prefix. The default is `/usr/local` (on UNIX and UNIX-like operating systems). @@ -108,11 +121,12 @@ library: -DZ80_DEPOT_LOCATION="" Specify the directory or URL of the depot containing the test files - (i.e., the firmware and software required by the testing tool). + (i.e., the firmware and software required by the `test-Z80` tool). The default is `http://zxe.io/depot`. -DZ80_FETCH_TEST_FILES=(YES|NO) - Copy or download the test files from the depot to the build directory. + If `Z80_WITH_TESTING_TOOL` is `YES`, copy or download the test files + from the depot to the build directory. The default is `NO`. -DZ80_INSTALL_CMAKEDIR="" @@ -168,8 +182,14 @@ library: AUTHORS, COPYING, COPYING.LESSER, HISTORY, README and THANKS. The default is `NO`. - -DZ80_WITH_TESTS=(YES|NO) - Build the testing tool. + -DZ80_WITH_STEP_TESTING_TOOL=(YES|NO) + Build `step-test-Z80`, a tool for unit tests in JSON format. + It requires cJSON and Z80InsnClock. + The default is `NO`. + + -DZ80_WITH_TESTING_TOOL=(YES|NO) + Build `test-Z80`, a tool that runs various Z80-specific tests for CP/M + and ZX Spectrum. The default is `NO`. The second group of package-specific options configures the source code of the @@ -189,6 +209,16 @@ library by predefining macros that enable optional features: executed during the interrupt mode 0 response. The default is `NO`. + -DZ80_WITH_PARITY_COMPUTATION=(YES|NO) + Enable actual parity calculation for the P/V flag instead of using a + table of precomputed values (NOT RECOMMENDED for production builds). + The default is `NO`. + + -DZ80_WITH_PRECOMPUTED_DAA=(YES|NO) + Use a table of precomputed values to emulate the `daa` instruction (NOT + RECOMMENDED for production builds). + The default is `NO`. + -DZ80_WITH_Q=(YES|NO) Build the implementation of Q. The default is `NO`. @@ -217,6 +247,8 @@ shared library: -DZ80_WITH_Q=YES -DZ80_WITH_ZILOG_NMOS_LD_A_IR_BUG=YES +3.3. Build and install + Finally, once the build system is configured according to your needs, build and install the package: @@ -253,14 +285,16 @@ the static versions, `BUILD_SHARED_LIBS` determines which one to link against. 4.2. As a CMake subproject To embed the Z80 library as a CMake subproject, extract the source code tarballs -of Zeta (https://zeta.st) and Z80 (or clone their respective repositories) into -a subdirectory of another project. Then use `add_subdirectory` in the parent -project to add the Z80 source code tree to the build process (N.B., the Z80 -subproject will automatically find Zeta and import it as an interface library). +of Zeta and Z80 (or clone their respective repositories) into a subdirectory of +another project. Then use `add_subdirectory` in the parent project to add the +Z80 source code tree to the build process (N.B., the Z80 subproject will +automatically find Zeta and import it as an interface library). It is advisable to configure the Z80 library in the CMakeLists.txt of the parent -project. This will prevent the user from having to specify configuration options -for the Z80 subproject through the command line when building the main project. +project. This will eliminate the need for the user to specify configuration +options for the Z80 subproject through the command line when building the main +project. See section 3.2 of this document for a list of available configuration +options. Example: @@ -281,39 +315,42 @@ The source code of the emulator can be configured at compile time by predefining a series of macros. Both Z80.h and Z80.c obey the first two explained below. The rest of the macros are only relevant when compiling Z80.c: - #define Z80_DEPENDENCIES_HEADER "header-name.h" + #define Z80_EXTERNAL_HEADER "header-name.h" Specifies the only external header to `#include`, replacing all others. Predefine this macro to provide a header file that defines the external types and macros used by the emulator, thus preventing your project from - depending on Zeta. You can use this when compiling Z80.c as a part of - your project or (if your types do not break the binary compatibility) - when including `` and linking against a pre-built Z80 library. + depending on Zeta. You can use this when compiling Z80.c within your + project or (if your types do not break the binary compatibility) when + including `` and linking against a pre-built Z80 library. #define Z80_STATIC - Restricts the visibility of public symbols. - This macro is required if you are building Z80.c as a static library, - compiling it directly as a part of your project, or linking your program - against the static version of the Z80 library. In either of these cases, - make sure this macro is defined before including `"Z80.h"` or ``. + Indicates that the emulator is a static library. + This macro must be predefined when building Z80.c as a static library. + Additionally, if you compile Z80.c directly within your project or link + your program against the static version of the Z80 library, ensure that + this macro is defined before including `"Z80.h"` or ``. #define Z80_WITH_LOCAL_HEADER Tells Z80.c to `#include "Z80.h"` instead of ``. -The optional features of the emulator mentioned in section 3 of this document -are disabled by default. If you compile Z80.c as a part of your project, enable -those features you need by predefining their respective activation macros. They -have the same name as their CMake equivalents: +The optional features of the emulator mentioned in section 3.2 of this document +are disabled by default. If you compile Z80.c within your project, enable those +features you need by predefining their respective activation macros. They have +the same name as their CMake equivalents: #define Z80_WITH_EXECUTE #define Z80_WITH_FULL_IM0 #define Z80_WITH_IM0_RETX_NOTIFICATIONS + #define Z80_WITH_PARITY_COMPUTATION + #define Z80_WITH_PRECOMPUTED_DAA #define Z80_WITH_Q #define Z80_WITH_SPECIAL_RESET #define Z80_WITH_UNOFFICIAL_RETI + #define Z80_WITH_VOLATILE_CYCLES #define Z80_WITH_ZILOG_NMOS_LD_A_IR_BUG -Except for `Z80_DEPENDENCIES_HEADER`, the above macros can be empty; the source -code only checks whether they are defined. +Except for `Z80_EXTERNAL_HEADER`, the above macros can be empty; the source code +only checks whether they are defined. Please note that the activation of some of the optional features affects the speed of the emulator due to various factors (read the documentation for more @@ -335,5 +372,6 @@ PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . + ________________________________________________________________________________ -Last update: 2023-12-31 README EOF +Last update: 2026-01-01 README EOF diff --git a/projects/Z80/README.md b/projects/Z80/README.md index a20a691..ecbba14 100644 --- a/projects/Z80/README.md +++ b/projects/Z80/README.md @@ -1,14 +1,15 @@ # Zilog Z80 CPU Emulator -[![](https://zxe.io/software/Z80/assets/images/documentation-badge.svg)](https://zxe.io/software/Z80/documentation/latest) +[![Documentation](https://zxe.io/software/Z80/assets/images/documentation-badge.svg)](https://zxe.io/software/Z80/documentation/latest) [![](https://github.com/redcode/Z80/actions/workflows/build-and-test-library.yml/badge.svg)](https://github.com/redcode/Z80/actions/workflows/build-and-test-library.yml) [![](https://github.com/redcode/Z80/actions/workflows/build-documentation.yml/badge.svg)](https://github.com/redcode/Z80/actions/workflows/build-documentation.yml) -[![](https://zxe.io/software/Z80/assets/images/chat-badge.svg)](https://zxe.io/software/Z80/chat) +[![](https://github.com/redcode/Z80/actions/workflows/step-tests.yml/badge.svg)](https://github.com/redcode/Z80/actions/workflows/step-tests.yml) +[![Chat](https://zxe.io/software/Z80/assets/images/chat-badge.svg)](https://zxe.io/software/Z80/chat) ![](https://zxe.io/software/Z80/assets/images/mentioned-in-awesome-badge.svg) ## Introduction - + The [Z80 library](https://zxe.io/software/Z80) implements a fast, small and accurate [emulator](https://en.wikipedia.org/wiki/Emulator) of the [Zilog Z80](https://en.wikipedia.org/wiki/Zilog_Z80). It emulates all that is known to date about this CPU, including the undocumented behaviors, [MEMPTR](https://zxpress.ru/zxnet/zxnet.pc/5909), [Q](https://worldofspectrum.org/forums/discussion/41704) and the [special RESET](http://www.primrosebank.net/computers/z80/z80_special_reset.htm). It also has the honor of having been the first open-source project to provide full emulation of the interrupt mode 0. @@ -16,9 +17,9 @@ The source code is written in [ANSI C](https://en.wikipedia.org/wiki/ANSI_C) for ## Accuracy -This Z80 CPU emulator has a classic design with instruction-level granularity that delivers the best performance, whilst offering a reasonable flexibility to achieve [precision down to the T-state level](https://github.com/agaxia/Z80InsnClock). +This Z80 CPU emulator has a classic design with instruction-level granularity that delivers high performance, whilst offering reasonable flexibility to achieve [precision down to the T-state level](https://github.com/agaxia/Z80InsnClock). -Instruction-level granularity implies that, except in a few well-defined cases, the execution of a given instruction cannot stop until all its internal M-cycles have been processed (i.e., instructions are not divided into micro-operations). Moreover, registers are modified only once per instruction and the [T-state counter](https://zxe.io/software/Z80/documentation/latest/APIReference.html#c.Z80.cycles) is normally updated after a full instruction has been executed. +Instruction-level granularity implies that, except in a few well-defined cases, the execution of a given instruction cannot stop until all its internal M-cycles have been processed (i.e., instructions are not divided into micro-operations). Moreover, registers are modified only once per instruction and the [T-state counter](https://zxe.io/software/Z80/documentation/latest/api-reference.html#c.Z80.cycles) is normally updated after a full instruction has been executed. That said, instructions, flags, memory accesses, interrupts, clock cycles, etc., are accurately emulated according to the available [technical documentation](https://github.com/redcode/Z80/wiki/Technical-literature), the findings made after decades of research on the Z80 and [electronic simulations](https://github.com/redcode/Z80/wiki/Simulators). And, of course, the emulator passes the most exhaustive [tests](https://github.com/redcode/Z80/wiki/Tests) written to date, including all three major test suites: @@ -306,60 +307,19 @@ Frank Cringle's _Z80 Instruction Set Exerciser_ attempts to execute every Z80 op ## Installation -### Debian, Ubuntu and other Debian-based Linux distributions +The Z80 library is available through various package managers. For an up-to-date list and installation instructions, see the "[Installation](https://github.com/redcode/Z80/wiki/Installation)" page on the repository wiki. -First, add the `zxe` repository and update the package index: +## Installation from source code -```shell -sudo mkdir -pm700 /root/.gnupg -sudo mkdir -pm755 /etc/apt/keyrings -sudo gpg --no-default-keyring --keyring /etc/apt/keyrings/zxe-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys FE214A38D6A0C01D9AF514EE841EA3BD3A7E1487 -echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/zxe-archive-keyring.gpg] https://zxe.io/repos/apt stable main" | sudo tee /etc/apt/sources.list.d/zxe.list -sudo apt update -``` - -Next, install the library package: - -```shell -sudo apt install libz80 -``` - -In case you need to build software that requires the Z80 library, install the development package too: - -```shell -sudo apt install libz80-dev -``` - -### Gentoo - -First, add and sync the [`zxe`](https://github.com/redcode/zxe-gentoo-overlay) overlay: - -```shell -eselect repository add zxe git https://github.com/redcode/zxe-gentoo-overlay.git -emaint sync --repo zxe -``` - -Then install the library: - -```shell -emerge emulation-libs/z80 -``` - -### Homebrew - -```shell -brew install redcode/zxe/z80 -``` - -### Windows - -Pre-built binaries for Windows are available on the [download](https://zxe.io/software/Z80/download) page. - -## Installation from sources +### Prerequisites You will need [CMake](https://cmake.org) v3.14 or later to build the package and, optionally, recent versions of [Doxygen](https://www.doxygen.nl), [Sphinx](https://www.sphinx-doc.org) and [Breathe](https://www.breathe-doc.org) to compile the documentation. Also, make sure that you have [LaTeX](https://www.latex-project.org) with PDF support installed on your system if you want to generate the documentation in PDF format. -The emulator requires some types and macros included in [Zeta](https://zeta.st), a dependency-free, [header-only](https://en.wikipedia.org/wiki/Header-only) library used to retain compatibility with most C compilers. Install Zeta or extract its [source code tarball](https://zeta.st/download) to the root directory of the Z80 project or its parent directory. Zeta is the sole dependency; the emulator is a freestanding implementation and as such does not depend on the [C standard library](https://en.wikipedia.org/wiki/C_standard_library). +The Z80 library requires some types and macros included in [Zeta](https://zxe.io/software/Zeta), a [header-only](https://en.wikipedia.org/wiki/Header-only), dependency-free library used for portability reasons. Install Zeta or extract its [source code tarball](https://zxe.io/software/Zeta/download) to the root directory of the Z80 project or its parent directory. Zeta is the sole dependency; the emulator does not depend on the [C standard library](https://en.wikipedia.org/wiki/C_standard_library). + +Lastly, the package includes two testing tools, which are optional to build. The first one runs various Z80-specific tests for [CP/M](https://en.wikipedia.org/wiki/CP/M) and [ZX Spectrum](https://en.wikipedia.org/wiki/ZX_Spectrum), and will use [libzip](https://libzip.org) and [zlib](https://zlib.net) if they are available on your system. The second tool is for [unit tests in JSON format](https://github.com/SingleStepTests/z80) and requires the [cJSON](https://github.com/DaveGamble/cJSON) and [Z80InsnClock](https://zxe.io/software/Z80InsnClock) libraries. + +### Configure Once the prerequisites are met, create a directory and run `cmake` from there to prepare the build system: @@ -372,7 +332,7 @@ cmake [options] The resulting build files can be configured by passing options to `cmake`. To show a complete list of those available along with their current settings, type the following: ```shell -cmake -LAH +cmake -LAH -N -B . ``` If in doubt, read the [CMake documentation](https://cmake.org/documentation/) for more information on configuration options. The following are some of the most relevant standard options of CMake: @@ -385,6 +345,10 @@ If in doubt, read the [CMake documentation](https://cmake.org/documentation/) fo Choose the type of build (configuration) to generate. The default is `Release`. +* **-D[CMAKE_INSTALL_NAME_DIR](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_NAME_DIR.html)="\"** + Specify the [directory portion](https://developer.apple.com/documentation/xcode/build-settings-reference#Dynamic-Library-Install-Name-Base) of the [dynamic library install name](https://developer.apple.com/documentation/xcode/build-settings-reference#Dynamic-Library-Install-Name) on Apple platforms (for installed shared libraries). + Not defined by default. + * **-D[CMAKE_INSTALL_PREFIX](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html)="\"** Specify the installation prefix. The default is `"/usr/local"` (on [UNIX](https://en.wikipedia.org/wiki/Unix) and [UNIX-like](https://en.wikipedia.org/wiki/Unix-like) operating systems). @@ -392,11 +356,11 @@ If in doubt, read the [CMake documentation](https://cmake.org/documentation/) fo Package-specific options are prefixed with `Z80_` and can be divided into two groups. The first one controls aspects not related to the source code of the library: * **`-DZ80_DEPOT_LOCATION=""`** - Specify the directory or URL of the depot containing the test files (i.e., the firmware and software required by the [testing tool](#running-the-tests)). + Specify the directory or URL of the depot containing the test files (i.e., the firmware and software required by the [`test-Z80`](#running-the-tests) tool). The default is `"http://zxe.io/depot"`. * **`-DZ80_FETCH_TEST_FILES=(YES|NO)`** - Copy or download the test files from the depot to the build directory. + If [`Z80_WITH_TESTING_TOOL`](#cmake_option_z80_with_testing_tool) is `YES`, copy or download the test files from the depot to the build directory. The default is `NO`. * **`-DZ80_INSTALL_CMAKEDIR=""`** @@ -447,14 +411,19 @@ If in doubt, read the [CMake documentation](https://cmake.org/documentation/) fo Install the standard text documents distributed with the package: [`AUTHORS`](AUTHORS), [`COPYING`](COPYING), [`COPYING.LESSER`](COPYING.LESSER), [`HISTORY`](HISTORY), [`README`](README) and [`THANKS`](THANKS). The default is `NO`. -* **`-DZ80_WITH_TESTS=(YES|NO)`** - Build the [testing tool](#running-the-tests). +* **`-DZ80_WITH_STEP_TESTING_TOOL=(YES|NO)`** + Build `step-test-Z80`, a tool for [unit tests in JSON format](https://github.com/SingleStepTests/z80). + It requires cJSON and Z80InsnClock. The default is `NO`. -The second group of package-specific options configures the source code of the library by predefining macros that enable [optional features](https://zxe.io/software/Z80/documentation/latest/Introduction.html#optional-features): +* **`-DZ80_WITH_TESTING_TOOL=(YES|NO)`** + Build `test-Z80`, a tool that runs various Z80-specific tests for [CP/M](https://en.wikipedia.org/wiki/CP/M) and [ZX Spectrum](https://en.wikipedia.org/wiki/ZX_Spectrum). + The default is `NO`. + +The second group of package-specific options configures the source code of the library by predefining macros that enable [optional features](https://zxe.io/software/Z80/documentation/latest/introduction.html#optional-features): * **`-DZ80_WITH_EXECUTE=(YES|NO)`** - Build the implementation of the [`z80_execute`](https://zxe.io/software/Z80/documentation/latest/APIReference.html#c.z80_execute) function. + Build the implementation of the [`z80_execute`](https://zxe.io/software/Z80/documentation/latest/api-reference.html#c.z80_execute) function. The default is `NO`. * **`-DZ80_WITH_FULL_IM0=(YES|NO)`** @@ -465,6 +434,14 @@ If in doubt, read the [CMake documentation](https://cmake.org/documentation/) fo Enable optional notifications for any `reti` or `retn` instruction executed during the interrupt mode 0 response. The default is `NO`. +* **`-DZ80_WITH_PARITY_COMPUTATION=(YES|NO)`** + Enable actual parity calculation for the P/V flag instead of using a table of precomputed values (NOT RECOMMENDED for production builds). + The default is `NO`. + +* **`-DZ80_WITH_PRECOMPUTED_DAA=(YES|NO)`** + Use a table of precomputed values to emulate the `daa` instruction (NOT RECOMMENDED for production builds). + The default is `NO`. + * **`-DZ80_WITH_Q=(YES|NO)`** Build the implementation of [Q](https://worldofspectrum.org/forums/discussion/41704). The default is `NO`. @@ -491,6 +468,8 @@ Package maintainers are encouraged to use at least the following options for the -DZ80_WITH_ZILOG_NMOS_LD_A_IR_BUG=YES ``` +### Build and install + Finally, once the build system is configured according to your needs, build and install the package: ```shell @@ -512,7 +491,7 @@ cd Zeta mkdir build && cd build cmake \ -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=$HOME/.local \ + -DCMAKE_INSTALL_PREFIX="$HOME/.local" \ -DZeta_WITH_CMAKE_SUPPORT=YES \ -DZeta_WITH_PKGCONFIG_SUPPORT=YES \ .. @@ -522,7 +501,8 @@ mkdir build && cd build cmake \ -DBUILD_SHARED_LIBS=YES \ -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=$HOME/.local \ + -DCMAKE_INSTALL_NAME_DIR="$HOME/.local/lib" \ + -DCMAKE_INSTALL_PREFIX="$HOME/.local" \ -DZ80_WITH_CMAKE_SUPPORT=YES \ -DZ80_WITH_PKGCONFIG_SUPPORT=YES \ -DZ80_WITH_EXECUTE=YES \ @@ -535,11 +515,11 @@ cmake --build . --config Release cmake --install . --config Release --strip ``` -**[ build-and-install-Z80.sh](https://zxe.io/software/Z80/scripts/build-and-install-Z80.sh)** +**[ build-and-install-Z80.sh](https://zxe.io/software/Z80/scripts/build-and-install-Z80.sh)** ## Running the tests -The package includes a tool called [`test-Z80`](sources/test-Z80.c) capable of running the most relevant [CP/M](https://en.wikipedia.org/wiki/CP/M) and [ZX Spectrum](https://en.wikipedia.org/wiki/ZX_Spectrum) versions of the [major test suites](#major_test_suites). Configure the build system with -D[Z80_WITH_TESTS](#cmake_option_z80_with_tests)=YES to enable its compilation and -D[Z80_FETCH_TEST_FILES](#cmake_option_z80_fetch_test_files)=YES to download the firmware and software required. Also note that the Z80 library must be built with -D[Z80_WITH_Q](#cmake_option_z80_with_q)=YES to be able to pass [Patrik Rak's tests](#zilog-z80-cpu-test-suite-by-patrik-rak). +The package includes a tool called [`test-Z80`](sources/test-Z80.c) that runs the most relevant [CP/M](https://en.wikipedia.org/wiki/CP/M) and [ZX Spectrum](https://en.wikipedia.org/wiki/ZX_Spectrum) versions of the [major test suites](#major_test_suites). Configure the build system with -D[Z80_WITH_TESTING_TOOL](#cmake_option_z80_with_testing_tool)=YES to enable its compilation and -D[Z80_FETCH_TEST_FILES](#cmake_option_z80_fetch_test_files)=YES to download the firmware and software required. Also note that the Z80 library must be built with -D[Z80_WITH_Q](#cmake_option_z80_with_q)=YES to be able to pass [Patrik Rak's tests](#zilog-z80-cpu-test-suite-by-patrik-rak). Once you have built the package, type the following to run all tests: @@ -547,21 +527,16 @@ Once you have built the package, type the following to run all tests: ./test-Z80 -p depot/firmware -p depot/software/POSIX -p "depot/software/ZX Spectrum" -a ``` -The tool supports options and can run the tests individually (type ./test-Z80 -h for help). If you prefer to run all tests through [CTest](https://cmake.org/cmake/help/latest/manual/ctest.1.html), use this command: +The tool supports options and can run the tests individually (type ./test-Z80 -h for help). + +If you prefer to run all tests through [CTest](https://cmake.org/cmake/help/latest/manual/ctest.1.html), use this: ```shell -ctest --verbose --build-config (Debug|Release|RelWithDebInfo|MinSizeRel) +ctest -N # List available tests +ctest --verbose --build-config (Debug|Release|RelWithDebInfo|MinSizeRel) [-I ,] ``` -The complete logs generated by `test-Z80` emulating different CPU variants are available here: - -* [Zilog NMOS](https://zxe.io/software/Z80/tests/logs/test-Z80%20v0.2%20Results%20-%20Zilog%20NMOS.txt) -* [Zilog CMOS](https://zxe.io/software/Z80/tests/logs/test-Z80%20v0.2%20Results%20-%20Zilog%20CMOS.txt) -* [NEC NMOS](https://zxe.io/software/Z80/tests/logs/test-Z80%20v0.2%20Results%20-%20NEC%20NMOS.txt) -* [ST CMOS](https://zxe.io/software/Z80/tests/logs/test-Z80%20v0.2%20Results%20-%20ST%20CMOS.txt) - -> [!NOTE] -> The CRC errors in the logs of the NEC NMOS variant **are normal** and match the [values obtained on real hardware](https://jisanchez.com/test-a-dos-placas-de-zx-spectrum). The ST CMOS variant is currently [under investigation](https://github.com/redcode/Z80_XCF_Flavor/issues/2). +By default, if the build system has been configured with -D[Z80_WITH_EXECUTE](#cmake_option_z80_with_execute)=YES, CTest will run the tests twice to increase coverage. Using [`-I`](https://cmake.org/cmake/help/latest/manual/ctest.1.html#cmdoption-ctest-I) allows you to run only the test corresponding to the specified index. ### TL;DR @@ -576,7 +551,7 @@ mkdir build && cd build cmake \ -DCMAKE_BUILD_TYPE=Release \ -DZ80_FETCH_TEST_FILES=YES \ - -DZ80_WITH_TESTS=YES \ + -DZ80_WITH_TESTING_TOOL=YES \ -DZ80_WITH_EXECUTE=YES \ -DZ80_WITH_FULL_IM0=YES \ -DZ80_WITH_IM0_RETX_NOTIFICATIONS=YES \ @@ -587,7 +562,19 @@ cmake --build . --config Release ctest --verbose --build-config Release ``` -**[ build-and-test-Z80.sh](https://zxe.io/software/Z80/scripts/build-and-test-Z80.sh)    [ build-and-test-Z80.bat](https://zxe.io/software/Z80/scripts/build-and-test-Z80.bat)** +**[ build-and-test-Z80.sh](https://zxe.io/software/Z80/scripts/build-and-test-Z80.sh)    [ build-and-test-Z80.bat](https://zxe.io/software/Z80/scripts/build-and-test-Z80.bat)** + +### Results + +The complete logs generated by `test-Z80` emulating different CPU variants are available here: + +* [Zilog NMOS](https://zxe.io/software/Z80/tests/logs/test-Z80%20v0.2%20Results%20-%20Zilog%20NMOS.txt) +* [Zilog CMOS](https://zxe.io/software/Z80/tests/logs/test-Z80%20v0.2%20Results%20-%20Zilog%20CMOS.txt) +* [NEC NMOS](https://zxe.io/software/Z80/tests/logs/test-Z80%20v0.2%20Results%20-%20NEC%20NMOS.txt) +* [ST CMOS](https://zxe.io/software/Z80/tests/logs/test-Z80%20v0.2%20Results%20-%20ST%20CMOS.txt) + +> [!IMPORTANT] +> The CRC errors in the logs of the NEC NMOS variant **are normal** and match the [values obtained on real hardware](https://jisanchez.com/test-a-dos-placas-de-zx-spectrum). The ST CMOS variant is currently [under investigation](https://github.com/redcode/Z80_XCF_Flavor/issues/2). ## Integration @@ -606,9 +593,9 @@ When not specified as a component, the linking method is selected according to [ ### As a CMake subproject -To embed the Z80 library as a CMake subproject, extract the source code tarballs of [Zeta](https://zeta.st/download) and [Z80](https://zxe.io/software/Z80/download) (or clone their respective repositories) into a subdirectory of another project. Then use [`add_subdirectory`](https://cmake.org/cmake/help/latest/command/add_subdirectory.html) in the parent project to add the Z80 source code tree to the build process (N.B., the Z80 subproject will automatically find Zeta and import it as an [interface library](https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#interface-libraries)). +To embed the Z80 library as a CMake subproject, extract the source code tarballs of [Zeta](https://zxe.io/software/Zeta/download) and [Z80](https://zxe.io/software/Z80/download) (or clone their respective repositories) into a subdirectory of another project. Then use [`add_subdirectory`](https://cmake.org/cmake/help/latest/command/add_subdirectory.html) in the parent project to add the Z80 source code tree to the build process (N.B., the Z80 subproject will automatically find Zeta and import it as an [interface library](https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#interface-libraries)). -It is advisable to configure the Z80 library in the `CMakeLists.txt` of the parent project. This will prevent the user from having to specify [configuration options for the Z80 subproject](#cmake_package_options) through the command line when building the main project. +It is advisable to configure the Z80 library in the `CMakeLists.txt` of the parent project. This will eliminate the need for the user to specify [configuration options for the Z80 subproject](#cmake_package_options) through the command line when building the main project. Example: @@ -627,45 +614,59 @@ It is important to set the [`Z80_SHARED_LIBS`](#cmake_option_z80_shared_libs) op The source code of the emulator can be configured at compile time by predefining a series of macros. Both [`Z80.h`](API/Z80.h) and [`Z80.c`](sources/Z80.c) obey the first two explained below. The rest of the macros are only relevant when compiling `Z80.c`: -* **`#define Z80_DEPENDENCIES_HEADER "header-name.h"`** +* **`#define Z80_EXTERNAL_HEADER "header-name.h"`** Specifies the only external header to `#include`, replacing all others. - Predefine this macro to provide a header file that defines the external types and macros used by the emulator, thus preventing your project from depending on [Zeta](https://zeta.st). You can use this when compiling `Z80.c` as a part of your project or (if your types do not break the binary compatibility) when including `` and linking against a pre-built Z80 library. + Predefine this macro to provide a header file that defines the external types and macros used by the emulator, thus preventing your project from depending on [Zeta](https://zxe.io/software/Zeta). You can use this when compiling `Z80.c` within your project or (if your types do not break the binary compatibility) when including `` and linking against a pre-built Z80 library. * **`#define Z80_STATIC`** - Restricts the visibility of public symbols. - This macro is required if you are building `Z80.c` as a static library, compiling it directly as a part of your project, or linking your program against the static version of the Z80 library. In either of these cases, make sure this macro is defined before including `"Z80.h"` or ``. + Indicates that the emulator is a static library. + This macro must be predefined when building `Z80.c` as a static library. Additionally, if you compile `Z80.c` directly within your project or link your program against the static version of the Z80 library, ensure that this macro is defined before including `"Z80.h"` or ``. * **`#define Z80_WITH_LOCAL_HEADER`** Tells `Z80.c` to #include "Z80.h" instead of ``. -The optional features of the emulator mentioned in "[Installation from sources](#installation-from-sources)" are disabled by default. If you compile `Z80.c` as a part of your project, enable those features you need by predefining their respective activation macros. They have the same name as their [CMake equivalents](#cmake_package_source_code_options): +The optional features of the emulator mentioned in the "[Configure](#configure)" section of "[Installation from source code](#installation-from-source-code)" are disabled by default. If you compile `Z80.c` within your project, enable those features you need by predefining their respective activation macros. They have the same name as their [CMake equivalents](#cmake_package_source_code_options): * **#define [Z80_WITH_EXECUTE](#cmake_option_z80_with_execute)** * **#define [Z80_WITH_FULL_IM0](#cmake_option_z80_with_full_im0)** * **#define [Z80_WITH_IM0_RETX_NOTIFICATIONS](#cmake_option_z80_with_im0_retx_notifications)** +* **#define [Z80_WITH_PARITY_COMPUTATION](#cmake_option_z80_with_parity_computation)** +* **#define [Z80_WITH_PRECOMPUTED_DAA](#cmake_option_z80_with_precomputed_daa)** * **#define [Z80_WITH_Q](#cmake_option_z80_with_q)** * **#define [Z80_WITH_SPECIAL_RESET](#cmake_option_z80_with_special_reset)** * **#define [Z80_WITH_UNOFFICIAL_RETI](#cmake_option_z80_with_unofficial_reti)** * **#define [Z80_WITH_ZILOG_NMOS_LD_A_IR_BUG](#cmake_option_z80_with_zilog_nmos_ld_a_ir_bug)** -Except for [`Z80_DEPENDENCIES_HEADER`](#macro_z80_dependencies_header), the above macros can be empty; the source code only checks whether they are defined. +Except for [`Z80_EXTERNAL_HEADER`](#macro_z80_external_header), the above macros can be empty; the source code only checks whether they are defined. -> [!NOTE] -> The activation of some of the optional features affects the speed of the emulator due to various factors (read the [documentation](https://zxe.io/software/Z80/documentation/latest/Introduction.html#optional-features) for more details). +> [!IMPORTANT] +> The activation of some of the optional features affects the speed of the emulator due to various factors (read the [documentation](https://zxe.io/software/Z80/documentation/latest/introduction.html#optional-features) for more details). ## Showcase This emulator has been used by the following projects (listed in alphabetical order): * **[Augmentinel](https://simonowen.com/spectrum/augmentinel/)** _by [Simon Owen](https://simonowen.com)_ ⟩ [GitHub](https://github.com/simonowen/augmentinel) +* **ceda-cemu** _by [Retrofficina GLG Programs](https://retrofficina.glgprograms.it)_ ⟩ [GitHub](https://github.com/GLGPrograms/ceda-cemu) * **CPM-Emulator** _by [Marc Sibert](https://github.com/Marcussacapuces91)_ ⟩ [GitHub](https://github.com/Marcussacapuces91/CPM-Emulator) -* **F80: simple Z80 system running on an FPGA** _by [Richard J. Prinz](https://www.min.at/prinz)_ ⟩ [GitHub](https://github.com/rprinz08/f80) +* **f80** _by [Richard J. Prinz](https://www.min.at/prinz)_ ⟩ [GitHub](https://github.com/rprinz08/f80) * **[Google Capture the Flag (2021)](https://capturetheflag.withgoogle.com)** _by [Google](https://www.google.com)_ ⟩ [GitHub](https://github.com/google/google-ctf) +* **[King of the Grid](https://kingofthegrid.com)** _by [Alex Siryi](https://github.com/desertkun)_ ⟩ [GitHub](https://github.com/kingofthegrid/king-of-the-grid) +* **MSX1 Emulator for Raspberry Pi Pico** _by [shippoiincho](https://github.com/shippoiincho)_ ⟩ [GitHub](https://github.com/shippoiincho/msxemulator) +* **MZ-1500 Emulator for Raspberry Pi Pico** _by [shippoiincho](https://github.com/shippoiincho)_ ⟩ [GitHub](https://github.com/shippoiincho/mz1500emulator) +* **MZ-2000/80B Emulator for Raspberry Pi Pico** _by [shippoiincho](https://github.com/shippoiincho)_ ⟩ [GitHub](https://github.com/shippoiincho/mz2000emulator) +* **PASOPIA/PASOPIA 7 Emulator for Raspberry Pi Pico** _by [shippoiincho](https://github.com/shippoiincho)_ ⟩ [GitHub](https://github.com/shippoiincho/pasopiaemulator) +* **PC-6001mkII Emulator for Raspberry Pi Pico** _by [shippoiincho](https://github.com/shippoiincho)_ ⟩ [GitHub](https://github.com/shippoiincho/p6mk2emulator) * **pico-sorcerer-2** _by [fruit-bat](https://github.com/fruit-bat)_ ⟩ [GitHub](https://github.com/fruit-bat/pico-sorcerer-2) * **pico-zxspectrum** _by [fruit-bat](https://github.com/fruit-bat)_ ⟩ [GitHub](https://github.com/fruit-bat/pico-zxspectrum) -* **[tihle: a unique TI calculator emulator](https://www.taricorp.net/2020/introducing-tihle/)** _by [Peter Marheine](https://www.taricorp.net/about/)_ ⟩ [GitHub](https://github.com/tari/tihle) · [GitLab](https://gitlab.com/taricorp/tihle) +* **[picoZ80](https://eaw.app/picoz80)** _by [Philip Smart](https://eaw.app/contact)_ +* **RadZ80** _by [RadAd](https://github.com/RadAd)_ ⟩ [GitHub](https://github.com/RadAd/RadZ80) +* **SEGA SC-3000 Emulator for Raspberry Pi Pico** _by [shippoiincho](https://github.com/shippoiincho)_ ⟩ [GitHub](https://github.com/shippoiincho/sc3000emulator) +* **[SpeccyP](https://t.me/c/ZX_MURMULATOR/241406)** _by [Constantin](https://github.com/billgilbert7000)_ ⟩ [GitHub](https://github.com/billgilbert7000/SpeccyP) +* **[The Second-Worst ZX Spectrum Emulator in the World](https://fuzzix.org/building-the-secondworst-zx-spectrum-emulator-in-the-world-with-perl)** _by [John Barrett](https://fuzzix.org/about)_ ⟩ [GitHub Gist](https://gist.github.com/jbarrett/1dbcbd92d08af2f089bf6baff5cf065b) +* **[tihle](https://www.taricorp.net/2020/introducing-tihle/)** _by [Peter Marheine](https://www.taricorp.net/about/)_ ⟩ [GitHub](https://github.com/tari/tihle) · [GitLab](https://gitlab.com/taricorp/tihle) * **[TileMap](https://simonowen.com/spectrum/tilemap/)** _by [Simon Owen](https://simonowen.com/)_ ⟩ [GitHub](https://github.com/simonowen/tilemap) -* **tranZPUterFusionX** _by [Philip Smart](https://eaw.app/about/)_ ⟩ [GitHub](https://github.com/pdsmart/tzpuFusionX) +* **tranZPUterFusionX** _by [Philip Smart](https://eaw.app/contact)_ * **Zemu** _by [Jay Valentine](https://jayvalentine.github.io/)_ ⟩ [GitHub](https://github.com/jayvalentine/zemu) · [RubyGems](https://rubygems.org/gems/zemu) ## Thanks @@ -674,201 +675,231 @@ Many thanks to the following individuals (in alphabetical order): * **Akimov, Vadim (lvd)** * For testing the library on many different platforms and CPU architectures. +* **Anisimov, Alexey (SoftLight)** + * For testing the `ccf/scf` instructions on real hardware. [1](#r_1) * **azesmbog** :trophy: - 1. For validating tests on real hardware. [1](#r1) + 1. For validating tests on real hardware. [2.1](#r_2_1) 2. For discovering the unstable behavior of the `ccf/scf` instructions. - 3. For his invaluable help. + 3. For testing the `ccf/scf` instructions on real hardware. [1](#r_1), [3](#r_3) + 4. For his invaluable help. * **Banks, David (hoglet)** :trophy: - 1. For cracking the flag behavior of the block instructions. [2](#r2), [3](#r3) - 2. For his research on the behavior of the `ccf/scf` instructions. [3](#r3) + 1. For deciphering the additional flag changes of the block instructions. [4.1](#r_4_1), [4.2](#r_4_2), [5](#r_5) + 2. For his research on the `ccf/scf` instructions. [5](#r_5), [6](#r_6) * **Beliansky, Anatoly (Tolik_Trek)** - * For validating tests on real hardware. [4](#r4) -* **Bobrowski, Jan** - * For fixing the _"Z80 Full Instruction Set Exerciser for Spectrum"_. [5](#r5) + * For validating tests on real hardware. [2.2](#r_2_2) +* **Bobrowski, Jan** + * For fixing _"Z80 Full Instruction Set Exerciser for Spectrum"_. [7](#r_7) * **boo_boo** :trophy: - * For cracking the behavior of the MEMPTR register. [6](#r6), [7](#r7), [8](#r8), [9](#r9) + * For deciphering the behavior of MEMPTR. [8](#r_8), [9](#r_9), [10](#r_10), [11](#r_11) * **Brady, Stuart** - * For his research on the behavior of the `ccf/scf` instructions. [10](#r10) + * For his research on the `ccf/scf` instructions. [12](#r_12) * **Brewer, Tony** :trophy: - 1. For his research on the special RESET. [11](#r11), [12](#r12) - 2. For helping to crack the flag behavior of the block instructions. [2](#r2) - 3. For conducting low-level tests on real hardware. [2](#r2) + 1. For his research on the special RESET. [4.3](#r_4_3), [13](#r_13) + 2. For helping to decipher the additional flag changes of the block instructions. [4](#r_4) + 3. For conducting low-level tests on real hardware. [4](#r_4) 4. For helping me to test different undocumented behaviors of the Zilog Z80. + 5. For discovering that the `DD/FD` prefixes affect the behavior of the `ccf/scf` instructions. [4.4](#r_4_4) * **Bystrov, Dmitry (Alone Coder)** - * For validating tests on real hardware. [4](#r4) + * For validating tests on real hardware. [2.2](#r_2_2) +* **Chaikin, Mikhail (P321)** + * For testing the `ccf/scf` instructions on real hardware. [1](#r_1) * **Chandler, Richard** 1. For his corrections to the documentation. - 2. For validating tests on real hardware. [13](#r13) + 2. For validating tests on real hardware. [14](#r_14) * **Chunin, Roman (CHRV)** - * For testing the behavior of the MEMPTR register on real Z80 chips. [6](#r6), [7](#r7), [8](#r8), [9](#r9) + * For testing the behavior of MEMPTR on real hardware. [8](#r_8), [9](#r_9), [10](#r_10), [11](#r_11) * **Conway, Simon (BadBeard)** - * For validating the _"Z80 Test Suite"_ on several Z80 clones. [14](#r14) + * For validating _"Z80 Test Suite"_ on several Z80 clones. [15](#r_15) * **Cooke, Simon** :trophy: - * For discovering how the out (c),0 instruction behaves on the Zilog Z80 CMOS. [15](#r15) + * For discovering how the out (c),0 instruction behaves on the Zilog Z80 CMOS. [16](#r_16) * **Cringle, Frank D.** - * For writing the _"Z80 Instruction Set Exerciser"_. [16](#r16) + * For writing _"Z80 Instruction Set Exerciser"_. [17](#r_17) * **Devic, Goran** - * For his research on undocumented behaviors of the Z80 CPU. [17](#r17) + * For his research on undocumented behaviors of the Z80 CPU. [18](#r_18) +* **Dmitriev, Dmitry (DDp)** + * For testing the `ccf/scf` instructions on real hardware. [3](#r_3) * **Dunn, Paul (ZXDunny)** * For his corrections to the documentation. * **Equinox** * For his corrections to the documentation. * **Flammenkamp, Achim** - * For his article on Z80 interrupts. [18](#r18) + * For his article on Z80 interrupts. [19](#r_19) * **Gimeno Fortea, Pedro** :trophy: - 1. For his research work. [19](#r19) - 2. For writing the first-ever ZX Spectrum emulator. [20](#r20), [21](#r21) -* **goodboy** - * For testing the behavior of the MEMPTR register on real Z80 chips. [6](#r6), [7](#r7), [8](#r8), [9](#r9) + 1. For his research work. [20](#r_20) + 2. For writing the first-ever ZX Spectrum emulator. [21](#r_21), [22](#r_22) * **Greenway, Ian** - * For testing the behavior of the `ccf/scf` instructions on real hardware. [10](#r10), [22](#r22) + * For testing the `ccf/scf` instructions on real hardware. [12](#r_12), [23](#r_23) * **Harston, Jonathan Graham** 1. For his research work. - 2. For his technical documents about the Zilog Z80. [23](#r23), [24](#r24), [25](#r25) - 3. For porting the _"Z80 Instruction Set Exerciser"_ to the ZX Spectrum. [26](#r26) + 2. For his technical documents about the Zilog Z80. [24](#r_24), [25](#r_25), [26](#r_26) + 3. For porting _"Z80 Instruction Set Exerciser"_ to the ZX Spectrum. [27](#r_27) * **Helcmanovsky, Peter (Ped7g)** :medal_military: - 1. For helping me to write the _"IN-MEMPTR"_ test. - 2. For writing the _"Z80 Block Flags Test"_. [27](#r27), [28](#r28) - 3. For writing the _"Z80 CCF SCF Outcome Stability"_ test. [28](#r28) - 4. For writing the _"Z80 INT Skip"_ test. [28](#r28) - 5. For his research on the unstable behavior of the `ccf/scf` instructions. - 6. For his invaluable help. + 1. For helping me to write _"IN-MEMPTR"_. + 2. For writing _"Z80 Block Flags Test"_. [2](#r_2), [28](#r_28) + 3. For writing _"Z80 CCF SCF Outcome Stability"_. [28](#r_28) + 4. For writing _"Z80 INT Skip"_. [28](#r_28) + 5. For writing _"FDDD2"_, _"Z80 DDFD3"_, _"Z80 IM1 vs JR"_ and many other tests. + 6. For his research on the unstable behavior of the `ccf/scf` instructions. + 7. For his invaluable help. * **Iborra Debón, Víctor (Eremus)** * For validating tests on real hardware. * **icebear** - * For testing the behavior of the MEMPTR register on real Z80 chips. [6](#r6), [7](#r7), [8](#r8), [9](#r9) + * For testing the behavior of MEMPTR on real hardware. [8](#r_8), [9](#r_9), [10](#r_10), [11](#r_11) * **ICEknight** * For validating tests on real hardware. +* **Ilyichev, Ivan (ivang78)** + * For testing the behavior of MEMPTR on real hardware. [29](#r_29) * **Kladov, Vladimir** :trophy: - * For cracking the behavior of the MEMPTR register. [6](#r6), [7](#r7), [8](#r8), [9](#r9) + * For deciphering the behavior of MEMPTR. [8](#r_8), [9](#r_9), [10](#r_10), [11](#r_11) +* **Kovrigin, Alexey (creator)** + * For testing the `ccf/scf` instructions on real hardware. [1](#r_1), [3](#r_3) * **Krook, Magnus** - * For validating tests on real hardware. [29](#r29) + * For validating tests on real hardware. [2.3](#r_2_3) * **London, Matthew (mattinx)** * For validating tests on real hardware. * **Martínez Cantero, Ricardo (Kyp)** * For validating tests on real hardware. * **Molodtsov, Aleksandr** - * For testing the behavior of the MEMPTR register on real Z80 chips. [6](#r6), [7](#r7), [8](#r8), [9](#r9) + * For testing the behavior of MEMPTR on real hardware. [8](#r_8), [9](#r_9), [10](#r_10), [11](#r_11) * **Nair, Arjun** - * For validating tests on real hardware. [27](#r27) + * For validating tests on real hardware. [2](#r_2) * **Nicolás-González, César** * For helping me to investigate the unstable behavior of the `ccf/scf` instructions. * **Ortega Sosa, Sofía** 1. For optimizing the emulator. - 2. For her support. + 2. For her help and support. * **Owen, Simon** * For the idea of the hooking method used in this emulator. * **Ownby, Matthew P.** - * For his research on the state of the registers after POWER-ON. [30](#r30) + * For his research on the state of the registers after POWER-ON. [30](#r_30) * **Rak, Patrik** :trophy: - 1. For improving the _"Z80 Instruction Set Exerciser for Spectrum"_. [31](#r31) - 2. For cracking the behavior of the `ccf/scf` instructions. [14](#r14), [31](#r31) - 3. For writing the _"Zilog Z80 CPU Test Suite"_. [31](#r31), [32](#r32) + 1. For improving _"Z80 Instruction Set Exerciser for Spectrum"_. [31](#r_31) + 2. For deciphering the behavior of the `ccf/scf` instructions. [15](#r_15), [31](#r_31) + 3. For writing _"Zilog Z80 CPU Test Suite"_. [31](#r_31), [32](#r_32) 4. For his research on the unstable behavior of the `ccf/scf` instructions. * **Rodríguez Jódar, Miguel Ángel (mcleod_ideafix)** - * For his research on the state of the registers after POWER-ON/RESET. [33](#r33) + 1. For his research on the state of the registers after POWER-ON/RESET. [33](#r_33) + 2. For writing _"Z80 Initial Condition Retriever"_. [33.1](#r_33_1) * **Rodríguez Palomino, Mario (r-lyeh)** * For teaching me how emulators work. * **Sainz de Baranda y Romero, Manuel** * For teaching me programming and giving me my first computer. +* **Sanarin, Dmitry (haywire)** + * For testing the `ccf/scf` instructions on real hardware. [3](#r_3) * **Sánchez Ordiñana, José Ismael (Vaporatorius)** - * For validating tests on real hardware. [34](#r34), [35](#r35) + * For validating tests on real hardware. [32.1](#r_32_1), [34](#r_34) +* **Sapach, Michael (cafedead)** + * For writing _"CPD-Test"_. [29](#r_29) * **Sevillano Mancilla, Marta (TheMartian)** - * For validating tests on real hardware. [13](#r13) + * For validating tests on real hardware. [14.1](#r_14_1) * **Stevenson, Dave** - 1. For testing the special RESET on real hardware. [11](#r11) - 2. For conducting low-level tests on real hardware. [36](#r36) + 1. For testing the special RESET on real hardware. [13](#r_13) + 2. For conducting low-level tests on real hardware. [4.5](#r_4_5) +* **Titov, Andrey (Titus)** + * For his research on the `ccf/scf` instructions. [1](#r_1), [3](#r_3) +* **Vasin, Yuriy (goodboy)** + 1. For testing the behavior of MEMPTR on real hardware. [8](#r_8), [9](#r_9), [10](#r_10), [11](#r_11), [29](#r_29) + 2. For testing the `ccf/scf` instructions on real hardware. [1](#r_1), [29](#r_29) * **Vučenović, Zoran** * For writing the [Pascal binding](sources/Z80.pas). * **Weissflog, Andre (Floh)** :trophy: - 1. For discovering that the `reti/retn` instructions defer the acceptance of the maskable interrupt. [37](#r37) - 2. For writing the _"Visual Z80 Remix"_ simulator. [38](#r38) + 1. For discovering that the `reti/retn` instructions defer the acceptance of the maskable interrupt. [35](#r_35) + 2. For writing the _"Visual Z80 Remix"_ simulator. [36](#r_36) * **Wilkinson, Oli (evolutional)** - * For validating tests on real hardware. [27](#r27) + * For validating tests on real hardware. [2](#r_2) * **Wlodek** - * For testing the behavior of the MEMPTR register on real Z80 chips. [6](#r6), [7](#r7), [8](#r8), [9](#r9) + * For testing the behavior of MEMPTR on real hardware. [8](#r_8), [9](#r_9), [10](#r_10), [11](#r_11) * **Woodmass, Mark (Woody)** :medal_military: 1. For his invaluable contributions to the emuscene. - 2. For writing the _"Z80 Test Suite"_. [14](#r14) - 3. For his research on the behavior of the `ccf/scf` instructions. [39](#r39) - 4. For writing the _"HALT2INT"_ test. - 5. For writing the _"EIHALT"_ test. + 2. For writing _"Z80 Test Suite"_. [15](#r_15) + 3. For writing _"ED777F"_, _"FDDD"_, _"EI48K"_, _"EIHALT"_, _"HALT2INT"_, _"IFF2 Bug"_, _"Super HALT Invaders Test"_ and many other tests. + 4. For his research on the `ccf/scf` instructions. [37](#r_37) * **Young, Sean** :trophy: 1. For his research work. - 2. For his technical documents about the Zilog Z80. [19](#r19), [30](#r30), [40](#r40) + 2. For his technical documents about the Zilog Z80. [20](#r_20), [30](#r_30), [38](#r_38) +* **Zarubin, Stanislav (JeRrS)** + * For testing the `ccf/scf` instructions on real hardware. [3](#r_3), [29](#r_29) * **ZXGuesser** * For validating tests on real hardware. ### References -1. https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83384#p83384 -2. https://stardot.org.uk/forums/viewtopic.php?t=15464 - * https://stardot.org.uk/forums/viewtopic.php?p=211042#p211042 - * https://stardot.org.uk/forums/viewtopic.php?p=212021#p212021 -3. Banks, David (2018-08-21). _"Undocumented Z80 Flags"_ rev. 1.0. - * https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags +1. https://zx-pk.ru/threads/34173-revers-inzhiniring-z80.html +2. https://spectrumcomputing.co.uk/forums/viewtopic.php?t=6102 + 1. https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83384#p83384 + 2. https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83041#p83041 + 3. https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83157#p83157 +3. https://zx-pk.ru/threads/35936-zagadka-plavayushchikh-flagov-scf-ccf-raskryta!.html +4. https://stardot.org.uk/forums/viewtopic.php?t=15464 + 1. https://stardot.org.uk/forums/viewtopic.php?p=211042#p211042 + 2. https://stardot.org.uk/forums/viewtopic.php?p=212021#p212021 + 3. https://stardot.org.uk/forums/viewtopic.php?p=357136#p357136 + 4. https://stardot.org.uk/forums/viewtopic.php?p=481595#p481595 + 5. https://stardot.org.uk/forums/viewtopic.php?p=212360#p212360 +5. Banks, David (2018-08-21). _"Undocumented Z80 Flags"_ rev. 1.0. * https://stardot.org.uk/forums/download/file.php?id=39831 -4. https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83041#p83041 -5. http://wizard.ae.krakow.pl/~jb/qaop/tests.html -6. https://zxpress.ru/zxnet/zxnet.pc/5909 -7. https://zx-pk.ru/threads/2506-komanda-bit-n-(hl).html -8. https://zx-pk.ru/threads/2586-prosba-realshchikam-ot-emulyatorshchikov.html -9. boo_boo; Kladov, Vladimir (2006-03-29). _"MEMPTR, Esoteric Register of the Zilog Z80 CPU"_. + * https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags +6. https://github.com/hoglet67/Z80Decoder/wiki/Unstable-CCF-SCF-Behaviour +7. http://wizard.ae.krakow.pl/~jb/qaop/tests.html +8. https://zxpress.ru/zxnet/zxnet.pc/5909 +9. https://zx-pk.ru/threads/2506-komanda-bit-n-(hl).html +10. https://zx-pk.ru/threads/2586-prosba-realshchikam-ot-emulyatorshchikov.html +11. boo_boo; Kladov, Vladimir (2006-03-29). _"MEMPTR, Esoteric Register of the Zilog Z80 CPU"_. * https://zx-pk.ru/showpost.php?p=43688 * https://zx-pk.ru/attachment.php?attachmentid=2984 * https://zx-pk.ru/showpost.php?p=43800 * https://zx-pk.ru/attachment.php?attachmentid=2989 -10. https://sourceforge.net/p/fuse-emulator/mailman/message/6929573 -11. Brewer, Tony (2014-12). _"Z80 Special Reset"_. +12. https://sourceforge.net/p/fuse-emulator/mailman/message/6929573 +13. Brewer, Tony (2014-12). _"Z80 Special Reset"_. * http://primrosebank.net/computers/z80/z80_special_reset.htm -12. https://stardot.org.uk/forums/viewtopic.php?p=357136#p357136 -13. https://spectrumcomputing.co.uk/forums/viewtopic.php?t=10555 -14. https://worldofspectrum.org/forums/discussion/20345 -15. https://groups.google.com/g/comp.os.cpm/c/HfSTFpaIkuU/m/KotvMWu3bZoJ -16. Cringle, Frank D. (1998-01-28). _"Yaze - Yet Another Z80 Emulator"_ v1.10. +14. https://spectrumcomputing.co.uk/forums/viewtopic.php?t=10555 + 1. https://spectrumcomputing.co.uk/forums/viewtopic.php?p=132144#p132144 +15. https://worldofspectrum.org/forums/discussion/20345 +16. https://groups.google.com/g/comp.os.cpm/c/HfSTFpaIkuU/m/KotvMWu3bZoJ +17. Cringle, Frank D. (1998-01-28). _"Yaze - Yet Another Z80 Emulator"_ v1.10. * ftp://ftp.ping.de/pub/misc/emulators/yaze-1.10.tar.gz -17. https://baltazarstudios.com/zilog-z80-undocumented-behavior -18. Flammenkamp, Achim. _"Interrupt Behaviour of the Z80 CPU"_. +18. https://baltazarstudios.com/zilog-z80-undocumented-behavior +19. Flammenkamp, Achim. _"Interrupt Behaviour of the Z80 CPU"_. * http://z80.info/interrup.htm -19. Young, Sean (1998-10). _"Z80 Undocumented Features (in Software Behaviour)"_ v0.3. +20. Young, Sean (1998-10). _"Z80 Undocumented Features (in Software Behaviour)"_ v0.3. * http://www.msxnet.org/tech/Z80/z80undoc.txt -20. https://elmundodelspectrum.com/desenterrando-el-primer-emulador-de-spectrum -21. https://elmundodelspectrum.com/con-vosotros-el-emulador-de-pedro-gimeno-1989 -22. https://sourceforge.net/p/fuse-emulator/mailman/message/4502844 -23. Harston, Jonathan Graham (2008). _"Full Z80 Opcode List Including Undocumented Opcodes"_ v0.11 (revised). - * https://mdfs.net/Docs/Comp/Z80/OpList -24. Harston, Jonathan Graham (2012). _"Z80 Microprocessor Undocumented Instructions"_ v0.15. - * https://mdfs.net/Docs/Comp/Z80/UnDocOps -25. Harston, Jonathan Graham (2014). _"Z80 Opcode Map"_ v0.10 (revised). - * https://mdfs.net/Docs/Comp/Z80/OpCodeMap -26. https://mdfs.net/Software/Z80/Exerciser/Spectrum -27. https://spectrumcomputing.co.uk/forums/viewtopic.php?t=6102 -28. https://github.com/MrKWatkins/ZXSpectrumNextTests -29. https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83157#p83157 -30. Young, Sean (2005-09-18). _"Undocumented Z80 Documented, The"_ v0.91. +21. https://elmundodelspectrum.com/desenterrando-el-primer-emulador-de-spectrum +22. https://elmundodelspectrum.com/con-vosotros-el-emulador-de-pedro-gimeno-1989 +23. https://sourceforge.net/p/fuse-emulator/mailman/message/4502844 +24. Harston, Jonathan Graham (2008). _"Full Z80 Opcode List Including Undocumented Opcodes"_ v0.11 (revised). + * http://www.mdfsnet.f9.co.uk/Docs/Comp/Z80/OpList +25. Harston, Jonathan Graham (2012). _"Z80 Microprocessor Undocumented Instructions"_ v0.15. + * http://mdfs.net/Docs/Comp/Z80/UnDocOps +26. Harston, Jonathan Graham (2014). _"Z80 Opcode Map"_ v0.10 (revised). + * http://mdfs.net/Docs/Comp/Z80/OpCodeMap +27. http://mdfs.net/Software/Z80/Exerciser/Spectrum +28. https://github.com/MrKWatkins/ZXSpectrumNextTests +29. https://zx-pk.ru/threads/36139-cpd-test-dlya-proverki-izmeneniya-registra-memptr-instruktsiyami-proverte-na-reale-plz.html +30. Young, Sean (2005-09-18). _"Undocumented Z80 Documented, The"_ v0.91. * http://www.myquest.nl/z80undocumented * http://www.myquest.nl/z80undocumented/z80-documented-v0.91.pdf -31. https://worldofspectrum.org/forums/discussion/41704 +31. https://worldofspectrum.org/forums/discussion/41704 * http://zxds.raxoft.cz/taps/misc/zexall2.zip -32. https://worldofspectrum.org/forums/discussion/41834 +32. https://worldofspectrum.org/forums/discussion/41834 * http://zxds.raxoft.cz/taps/misc/z80test-1.0.zip * https://github.com/raxoft/z80test -33. https://worldofspectrum.org/forums/discussion/34574 -34. https://worldofspectrum.org/forums/discussion/comment/668760/#Comment_668760 -35. https://jisanchez.com/test-a-dos-placas-de-zx-spectrum -36. https://stardot.org.uk/forums/viewtopic.php?p=212360#p212360 -37. Weissflog, Andre (2021-12-17). _"New Cycle-Stepped Z80 Emulator, A"_. + 1. https://worldofspectrum.org/forums/discussion/comment/668760/#Comment_668760 +33. https://worldofspectrum.org/forums/discussion/34574 + 1. https://worldofspectrum.org/forums/discussion/comment/539714/#Comment_539714 + * http://zxprojects.com/images/stories/z80_startup/reg_start_value.zip +34. https://jisanchez.com/test-a-dos-placas-de-zx-spectrum +35. Weissflog, Andre (2021-12-17). _"New Cycle-Stepped Z80 Emulator, A"_. * https://floooh.github.io/2021/12/17/cycle-stepped-z80.html -38. https://github.com/floooh/v6502r -39. https://groups.google.com/g/comp.sys.sinclair/c/WPsPr6j6w5k/m/O_u1zNQf3VYJ -40. Young, Sean (1997-09-21). _"Zilog Z80 CPU Specifications"_. +36. https://github.com/floooh/v6502r +37. https://groups.google.com/g/comp.sys.sinclair/c/WPsPr6j6w5k/m/O_u1zNQf3VYJ +38. Young, Sean (1997-09-21). _"Zilog Z80 CPU Specifications"_. * http://www.msxnet.org/tech/Z80/z80.zip ## License -Copyright © 1999-2024 Manuel Sainz de Baranda y Goñi. +Copyright © 1999-2026 Manuel Sainz de Baranda y Goñi. - + This library is [free software](https://www.gnu.org/philosophy/free-sw.html): you can redistribute it and/or modify it under the terms of the [GNU Lesser General Public License](https://www.gnu.org/licenses/lgpl-3.0.html) as published by the [Free Software Foundation](https://www.fsf.org), either version 3 of the License, or (at your option) any later version. diff --git a/projects/Z80/THANKS b/projects/Z80/THANKS index 869636c..97709ab 100644 --- a/projects/Z80/THANKS +++ b/projects/Z80/THANKS @@ -2,85 +2,98 @@ Many thanks to the following individuals (in alphabetical order): * Akimov, Vadim (lvd) For testing the library on many different platforms and CPU architectures. +* Anisimov, Alexey (SoftLight) + For testing the `ccf/scf` instructions on real hardware [1]. * azesmbog - 1. For validating tests on real hardware [1]. + 1. For validating tests on real hardware [2.1]. 2. For discovering the unstable behavior of the `ccf/scf` instructions. - 3. For his invaluable help. + 3. For testing the `ccf/scf` instructions on real hardware [1, 3]. + 4. For his invaluable help. * Banks, David (hoglet) - 1. For cracking the flag behavior of the block instructions [2,3]. - 2. For his research on the behavior of the `ccf/scf` instructions [3]. + 1. For deciphering the additional flag changes of the block instructions + [4.1, 4.2, 5]. + 2. For his research on the `ccf/scf` instructions [5, 6]. * Beliansky, Anatoly (Tolik_Trek) - For validating tests on real hardware [4]. + For validating tests on real hardware [2.2]. * Bobrowski, Jan - For fixing the "Z80 Full Instruction Set Exerciser for Spectrum" [5]. + For fixing "Z80 Full Instruction Set Exerciser for Spectrum" [7]. * boo_boo - For cracking the behavior of the MEMPTR register [6,7,8,9]. + For deciphering the behavior of MEMPTR [8, 9, 10, 11]. * Brady, Stuart - For his research on the behavior of the `ccf/scf` instructions [10]. + For his research on the `ccf/scf` instructions [12]. * Brewer, Tony - 1. For his research on the special RESET [11,12]. - 2. For helping to crack the flag behavior of the block instructions [2]. - 3. For conducting low-level tests on real hardware [2]. + 1. For his research on the special RESET [4.3, 13]. + 2. For helping to decipher the additional flag changes of the block + instructions [4]. + 3. For conducting low-level tests on real hardware [4]. 4. For helping me to test different undocumented behaviors of the Zilog Z80. + 5. For discovering that the `DD/FD` prefixes affect the behavior of the + `ccf/scf` instructions [4.4]. * Bystrov, Dmitry (Alone Coder) - For validating tests on real hardware [4]. + For validating tests on real hardware [2.2]. +* Chaikin, Mikhail (P321) + For testing the `ccf/scf` instructions on real hardware [1]. * Chandler, Richard 1. For his corrections to the documentation. - 2. For validating tests on real hardware [13]. + 2. For validating tests on real hardware [14]. * Chunin, Roman (CHRV) - For testing the behavior of the MEMPTR register on real Z80 chips [6,7,8,9]. + For testing the behavior of MEMPTR on real hardware [8, 9, 10, 11]. * Conway, Simon (BadBeard) - For validating the "Z80 Test Suite" on several Z80 clones [14]. + For validating "Z80 Test Suite" on several Z80 clones [15]. * Cooke, Simon For discovering how the `out (c),0` instruction behaves on the Zilog Z80 - CMOS [15]. + CMOS [16]. * Cringle, Frank D. - For writing the "Z80 Instruction Set Exerciser" [16]. + For writing "Z80 Instruction Set Exerciser" [17]. * Devic, Goran - For his research on undocumented behaviors of the Z80 CPU [17]. + For his research on undocumented behaviors of the Z80 CPU [18]. +* Dmitriev, Dmitry (DDp) + For testing the `ccf/scf` instructions on real hardware [3]. * Dunn, Paul (ZXDunny) For his corrections to the documentation. * Equinox For his corrections to the documentation. * Flammenkamp, Achim - For his article on Z80 interrupts [18]. + For his article on Z80 interrupts [19]. * Gimeno Fortea, Pedro - 1. For his research work [19]. - 2. For writing the first-ever ZX Spectrum emulator [20,21]. -* goodboy - For testing the behavior of the MEMPTR register on real Z80 chips [6,7,8,9]. + 1. For his research work [20]. + 2. For writing the first-ever ZX Spectrum emulator [21, 22]. * Greenway, Ian - For testing the behavior of the `ccf/scf` instructions on real hardware [10, - 22]. + For testing the `ccf/scf` instructions on real hardware [12, 23]. * Harston, Jonathan Graham 1. For his research work. - 2. For his technical documents about the Zilog Z80 [23,24,25]. - 3. For porting the "Z80 Instruction Set Exerciser" to the ZX Spectrum [26]. + 2. For his technical documents about the Zilog Z80 [24, 25, 26]. + 3. For porting "Z80 Instruction Set Exerciser" to the ZX Spectrum [27]. * Helcmanovsky, Peter (Ped7g) - 1. For helping me to write the "IN-MEMPTR" test. - 2. For writing the "Z80 Block Flags Test" [27,28]. - 3. For writing the "Z80 CCF SCF Outcome Stability" test [28]. - 4. For writing the "Z80 INT Skip" test [28]. - 5. For his research on the unstable behavior of the `ccf/scf` instructions. - 6. For his invaluable help. + 1. For helping me to write "IN-MEMPTR". + 2. For writing "Z80 Block Flags Test" [2, 28]. + 3. For writing "Z80 CCF SCF Outcome Stability" [28]. + 4. For writing "Z80 INT Skip" [28]. + 5. For writing "FDDD2", "Z80 DDFD3", "Z80 IM1 vs JR" and many other tests. + 6. For his research on the unstable behavior of the `ccf/scf` instructions. + 7. For his invaluable help. * Iborra Debón, Víctor (Eremus) For validating tests on real hardware. * icebear - For testing the behavior of the MEMPTR register on real Z80 chips [6,7,8,9]. + For testing the behavior of MEMPTR on real hardware [8, 9, 10, 11]. * ICEknight For validating tests on real hardware. +* Ilyichev, Ivan (ivang78) + For testing the behavior of MEMPTR on real hardware [29]. * Kladov, Vladimir - For cracking the behavior of the MEMPTR register [6,7,8,9]. + For deciphering the behavior of MEMPTR [8, 9, 10, 11]. +* Kovrigin, Alexey (creator) + For testing the `ccf/scf` instructions on real hardware [1, 3]. * Krook, Magnus - For validating tests on real hardware [29]. + For validating tests on real hardware [2.3]. * London, Matthew (mattinx) For validating tests on real hardware. * Martínez Cantero, Ricardo (Kyp) For validating tests on real hardware. * Molodtsov, Aleksandr - For testing the behavior of the MEMPTR register on real Z80 chips [6,7,8,9]. + For testing the behavior of MEMPTR on real hardware [8, 9, 10, 11]. * Nair, Arjun - For validating tests on real hardware [27]. + For validating tests on real hardware [2]. * Nicolás-González, César For helping me to investigate the unstable behavior of the `ccf/scf` instructions. @@ -92,42 +105,54 @@ Many thanks to the following individuals (in alphabetical order): * Ownby, Matthew P. For his research on the state of the registers after POWER-ON [30]. * Rak, Patrik - 1. For improving the "Z80 Instruction Set Exerciser for Spectrum" [31]. - 2. For cracking the behavior of the `ccf/scf` instructions [14,31]. - 3. For writing the "Zilog Z80 CPU Test Suite" [31,32]. + 1. For improving "Z80 Instruction Set Exerciser for Spectrum" [31]. + 2. For deciphering the behavior of the `ccf/scf` instructions [15, 31]. + 3. For writing "Zilog Z80 CPU Test Suite" [31, 32]. 4. For his research on the unstable behavior of the `ccf/scf` instructions. * Rodríguez Jódar, Miguel Ángel (mcleod_ideafix) - For his research on the state of the registers after POWER-ON/RESET [33]. + 1. For his research on the state of the registers after POWER-ON/RESET [33]. + 2. For writing "Z80 Initial Condition Retriever" [33.1]. * Rodríguez Palomino, Mario (r-lyeh) For teaching me how emulators work. * Sainz de Baranda y Romero, Manuel For teaching me programming and giving me my first computer. +* Sanarin, Dmitry (haywire) + For testing the `ccf/scf` instructions on real hardware [3]. * Sánchez Ordiñana, José Ismael (Vaporatorius) - For validating tests on real hardware [34,35]. + For validating tests on real hardware [32.1, 34]. +* Sapach, Michael (cafedead) + For writing "CPD-Test" [29]. * Sevillano Mancilla, Marta (TheMartian) - For validating tests on real hardware [13]. + For validating tests on real hardware [14.1]. * Stevenson, Dave - 1. For testing the special RESET on real hardware [11]. - 2. For conducting low-level tests on real hardware [36]. + 1. For testing the special RESET on real hardware [13]. + 2. For conducting low-level tests on real hardware [4.5]. +* Titov, Andrey (Titus) + For his research on the `ccf/scf` instructions [1, 3]. +* Vasin, Yuriy (goodboy) + 1. For testing the behavior of MEMPTR on real hardware [8, 9, 10, 11, 29]. + 2. For testing the `ccf/scf` instructions on real hardware [1, 29]. * Vučenović, Zoran For writing the Pascal binding. * Weissflog, Andre (Floh) 1. For discovering that the `reti/retn` instructions defer the acceptance of - the maskable interrupt [37]. - 2. For writing the "Visual Z80 Remix" simulator [38]. + the maskable interrupt [35]. + 2. For writing the "Visual Z80 Remix" simulator [36]. * Wilkinson, Oli (evolutional) - For validating tests on real hardware [27]. + For validating tests on real hardware [2]. * Wlodek - For testing the behavior of the MEMPTR register on real Z80 chips [6,7,8,9]. + For testing the behavior of MEMPTR on real hardware [8, 9, 10, 11]. * Woodmass, Mark (Woody) 1. For his invaluable contributions to the emuscene. - 2. For writing the "Z80 Test Suite" [14]. - 3. For his research on the behavior of the `ccf/scf` instructions [39]. - 4. For writing the "HALT2INT" test. - 5. For writing the "EIHALT" test. + 2. For writing "Z80 Test Suite" [15]. + 3. For writing "ED777F", "FDDD", "EI48K", "EIHALT", "HALT2INT", "IFF2 Bug", + "Super HALT Invaders Test" and many other tests. + 4. For his research on the `ccf/scf` instructions [37]. * Young, Sean 1. For his research work. - 2. For his technical documents about the Zilog Z80 [19,30,40]. + 2. For his technical documents about the Zilog Z80 [20, 30, 38]. +* Zarubin, Stanislav (JeRrS) + For testing the `ccf/scf` instructions on real hardware [3, 29]. * ZXGuesser For validating tests on real hardware. @@ -135,54 +160,63 @@ Many thanks to the following individuals (in alphabetical order): References ========== - 1. https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83384#p83384 - 2. https://stardot.org.uk/forums/viewtopic.php?t=15464 - * https://stardot.org.uk/forums/viewtopic.php?p=211042#p211042 - * https://stardot.org.uk/forums/viewtopic.php?p=212021#p212021 - 3. Banks, David (2018-08-21). "Undocumented Z80 Flags" rev. 1.0. - * https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags + 1. https://zx-pk.ru/threads/34173-revers-inzhiniring-z80.html + 2. https://spectrumcomputing.co.uk/forums/viewtopic.php?t=6102 + 1. https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83384#p83384 + 2. https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83041#p83041 + 3. https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83157#p83157 + 3. https://zx-pk.ru/threads/35936-zagadka-plavayushchikh-flagov-scf-ccf-raskryt + a!.html + 4. https://stardot.org.uk/forums/viewtopic.php?t=15464 + 1. https://stardot.org.uk/forums/viewtopic.php?p=211042#p211042 + 2. https://stardot.org.uk/forums/viewtopic.php?p=212021#p212021 + 3. https://stardot.org.uk/forums/viewtopic.php?p=357136#p357136 + 4. https://stardot.org.uk/forums/viewtopic.php?p=481595#p481595 + 5. https://stardot.org.uk/forums/viewtopic.php?p=212360#p212360 + 5. Banks, David (2018-08-21). "Undocumented Z80 Flags" rev. 1.0. * https://stardot.org.uk/forums/download/file.php?id=39831 - 4. https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83041#p83041 - 5. http://wizard.ae.krakow.pl/~jb/qaop/tests.html - 6. https://zxpress.ru/zxnet/zxnet.pc/5909 - 7. https://zx-pk.ru/threads/2506-komanda-bit-n-(hl).html - 8. https://zx-pk.ru/threads/2586-prosba-realshchikam-ot-emulyatorshchikov.html - 9. boo_boo; Kladov, Vladimir (2006-03-29). "MEMPTR, Esoteric Register of the + * https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags + 6. https://github.com/hoglet67/Z80Decoder/wiki/Unstable-CCF-SCF-Behaviour + 7. http://wizard.ae.krakow.pl/~jb/qaop/tests.html + 8. https://zxpress.ru/zxnet/zxnet.pc/5909 + 9. https://zx-pk.ru/threads/2506-komanda-bit-n-(hl).html +10. https://zx-pk.ru/threads/2586-prosba-realshchikam-ot-emulyatorshchikov.html +11. boo_boo; Kladov, Vladimir (2006-03-29). "MEMPTR, Esoteric Register of the Zilog Z80 CPU". * https://zx-pk.ru/showpost.php?p=43688 * https://zx-pk.ru/attachment.php?attachmentid=2984 * https://zx-pk.ru/showpost.php?p=43800 * https://zx-pk.ru/attachment.php?attachmentid=2989 -10. https://sourceforge.net/p/fuse-emulator/mailman/message/6929573 -11. Brewer, Tony (2014-12). "Z80 Special Reset". +12. https://sourceforge.net/p/fuse-emulator/mailman/message/6929573 +13. Brewer, Tony (2014-12). "Z80 Special Reset". * http://primrosebank.net/computers/z80/z80_special_reset.htm -12. https://stardot.org.uk/forums/viewtopic.php?p=357136#p357136 -13. https://spectrumcomputing.co.uk/forums/viewtopic.php?t=10555 -14. https://worldofspectrum.org/forums/discussion/20345 -15. https://groups.google.com/g/comp.os.cpm/c/HfSTFpaIkuU/m/KotvMWu3bZoJ -16. Cringle, Frank D. (1998-01-28). "Yaze - Yet Another Z80 Emulator" v1.10. +14. https://spectrumcomputing.co.uk/forums/viewtopic.php?t=10555 + 1. https://spectrumcomputing.co.uk/forums/viewtopic.php?p=132144#p132144 +15. https://worldofspectrum.org/forums/discussion/20345 +16. https://groups.google.com/g/comp.os.cpm/c/HfSTFpaIkuU/m/KotvMWu3bZoJ +17. Cringle, Frank D. (1998-01-28). "Yaze - Yet Another Z80 Emulator" v1.10. * ftp://ftp.ping.de/pub/misc/emulators/yaze-1.10.tar.gz -17. https://baltazarstudios.com/zilog-z80-undocumented-behavior -18. Flammenkamp, Achim. "Interrupt Behaviour of the Z80 CPU". +18. https://baltazarstudios.com/zilog-z80-undocumented-behavior +19. Flammenkamp, Achim. "Interrupt Behaviour of the Z80 CPU". * http://z80.info/interrup.htm -19. Young, Sean (1998-10). "Z80 Undocumented Features (in Software Behaviour)" +20. Young, Sean (1998-10). "Z80 Undocumented Features (in Software Behaviour)" v0.3. * http://www.msxnet.org/tech/Z80/z80undoc.txt -20. https://elmundodelspectrum.com/desenterrando-el-primer-emulador-de-spectrum -21. https://elmundodelspectrum.com/con-vosotros-el-emulador-de-pedro-gimeno-1989 -22. https://sourceforge.net/p/fuse-emulator/mailman/message/4502844 -23. Harston, Jonathan Graham (2008). "Full Z80 Opcode List Including +21. https://elmundodelspectrum.com/desenterrando-el-primer-emulador-de-spectrum +22. https://elmundodelspectrum.com/con-vosotros-el-emulador-de-pedro-gimeno-1989 +23. https://sourceforge.net/p/fuse-emulator/mailman/message/4502844 +24. Harston, Jonathan Graham (2008). "Full Z80 Opcode List Including Undocumented Opcodes" v0.11 (revised). - * https://mdfs.net/Docs/Comp/Z80/OpList -24. Harston, Jonathan Graham (2012). "Z80 Microprocessor Undocumented + * http://www.mdfsnet.f9.co.uk/Docs/Comp/Z80/OpList +25. Harston, Jonathan Graham (2012). "Z80 Microprocessor Undocumented Instructions" v0.15. - * https://mdfs.net/Docs/Comp/Z80/UnDocOps -25. Harston, Jonathan Graham (2014). "Z80 Opcode Map" v0.10 (revised). - * https://mdfs.net/Docs/Comp/Z80/OpCodeMap -26. https://mdfs.net/Software/Z80/Exerciser/Spectrum -27. https://spectrumcomputing.co.uk/forums/viewtopic.php?t=6102 + * http://mdfs.net/Docs/Comp/Z80/UnDocOps +26. Harston, Jonathan Graham (2014). "Z80 Opcode Map" v0.10 (revised). + * http://mdfs.net/Docs/Comp/Z80/OpCodeMap +27. http://mdfs.net/Software/Z80/Exerciser/Spectrum 28. https://github.com/MrKWatkins/ZXSpectrumNextTests -29. https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83157#p83157 +29. https://zx-pk.ru/threads/36139-cpd-test-dlya-proverki-izmeneniya-registra-me + mptr-instruktsiyami-proverte-na-reale-plz.html 30. Young, Sean (2005-09-18). "Undocumented Z80 Documented, The" v0.91. * http://www.myquest.nl/z80undocumented * http://www.myquest.nl/z80undocumented/z80-documented-v0.91.pdf @@ -191,13 +225,16 @@ References 32. https://worldofspectrum.org/forums/discussion/41834 * http://zxds.raxoft.cz/taps/misc/z80test-1.0.zip * https://github.com/raxoft/z80test + 1. https://worldofspectrum.org/forums/discussion/comment/668760/#Comment_668 + 760 33. https://worldofspectrum.org/forums/discussion/34574 -34. https://worldofspectrum.org/forums/discussion/comment/668760/#Comment_668760 -35. https://jisanchez.com/test-a-dos-placas-de-zx-spectrum -36. https://stardot.org.uk/forums/viewtopic.php?p=212360#p212360 -37. Weissflog, Andre (2021-12-17). "New Cycle-Stepped Z80 Emulator, A". + 1. https://worldofspectrum.org/forums/discussion/comment/539714/#Comment_539 + 714 + * http://zxprojects.com/images/stories/z80_startup/reg_start_value.zip +34. https://jisanchez.com/test-a-dos-placas-de-zx-spectrum +35. Weissflog, Andre (2021-12-17). "New Cycle-Stepped Z80 Emulator, A". * https://floooh.github.io/2021/12/17/cycle-stepped-z80.html -38. https://github.com/floooh/v6502r -39. https://groups.google.com/g/comp.sys.sinclair/c/WPsPr6j6w5k/m/O_u1zNQf3VYJ -40. Young, Sean (1997-09-21). "Zilog Z80 CPU Specifications". +36. https://github.com/floooh/v6502r +37. https://groups.google.com/g/comp.sys.sinclair/c/WPsPr6j6w5k/m/O_u1zNQf3VYJ +38. Young, Sean (1997-09-21). "Zilog Z80 CPU Specifications". * http://www.msxnet.org/tech/Z80/z80.zip diff --git a/projects/Z80/documentation/CMakeLists.txt b/projects/Z80/documentation/CMakeLists.txt index b35bbae..5f47060 100644 --- a/projects/Z80/documentation/CMakeLists.txt +++ b/projects/Z80/documentation/CMakeLists.txt @@ -4,7 +4,7 @@ # \/__/ /\_\ __ \\ \/\ \ # /\_____\\_____\\_____\ # Zilog \/_____//_____//_____/ CPU Emulator -# Copyright (C) 1999-2024 Manuel Sainz de Baranda y Goñi. +# Copyright (C) 1999-2026 Manuel Sainz de Baranda y Goñi. # Released under the terms of the GNU Lesser General Public License v3. find_package(Doxygen REQUIRED) @@ -43,6 +43,12 @@ set(DOXYGEN_XML_PROGRAMLISTING YES ) get_target_property(DOXYGEN_INCLUDE_PATH Zeta INTERFACE_INCLUDE_DIRECTORIES) +file(READ "${PROJECT_SOURCE_DIR}/README" _) +string(REGEX MATCH ".*Copyright \\(C\\) ([^ ]+) (([^. \t\n]+ ?)*[^. \t\n]+).*" _ ${_}) +set(_copyright_year ${CMAKE_MATCH_1}) +set(_author ${CMAKE_MATCH_2}) +unset(_) + doxygen_add_docs( ${PROJECT_NAME}-API-XML "${PROJECT_SOURCE_DIR}/API" @@ -59,11 +65,18 @@ if(${PROJECT_NAME}_WITH_HTML_DOCUMENTATION) endif() add_custom_command( - OUTPUT "${_html_documentation_output}" - COMMAND "${SPHINX_BUILD_EXECUTABLE}" + OUTPUT "${_html_documentation_output}" + COMMAND "${Sphinx_BUILD_EXECUTABLE}" -b html + "-Dproject=${PROJECT_NAME}" + "-Dversion=${PROJECT_VERSION}" + "-Drelease=${PROJECT_VERSION}" + "-Dauthor=${_author}" + "-Dcopyright=${_copyright_year} ${_author}" ${_html_theme_option} - -Dbreathe_projects.${PROJECT_NAME}="${_api_xml_output}" + "-Dhtml_title=${PROJECT_NAME} Documentation" + "-Dbreathe_default_project=${PROJECT_NAME}" + "-Dbreathe_projects.${PROJECT_NAME}=${_api_xml_output}" "${CMAKE_CURRENT_SOURCE_DIR}" "${_html_documentation_output}" DEPENDS ${PROJECT_NAME}-API-XML @@ -87,10 +100,16 @@ if(${PROJECT_NAME}_WITH_PDF_DOCUMENTATION) set(_latex_documentation_output "${CMAKE_CURRENT_BINARY_DIR}/LaTeX") add_custom_command( - OUTPUT "${_latex_documentation_output}" - COMMAND "${SPHINX_BUILD_EXECUTABLE}" + OUTPUT "${_latex_documentation_output}" + COMMAND "${Sphinx_BUILD_EXECUTABLE}" -b latex - -Dbreathe_projects.${PROJECT_NAME}="${_api_xml_output}" + "-Dproject=${PROJECT_NAME}" + "-Dversion=${PROJECT_VERSION}" + "-Drelease=${PROJECT_VERSION}" + "-Dauthor=${_author}" + "-Dcopyright=${_copyright_year} ${_author}" + "-Dbreathe_default_project=${PROJECT_NAME}" + "-Dbreathe_projects.${PROJECT_NAME}=${_api_xml_output}" "${CMAKE_CURRENT_SOURCE_DIR}" "${_latex_documentation_output}" DEPENDS ${PROJECT_NAME}-API-XML @@ -107,7 +126,7 @@ if(${PROJECT_NAME}_WITH_PDF_DOCUMENTATION) set(_pdf_documentation_output "${_latex_documentation_output}/${_pdf_documentation_output}.pdf") add_custom_command( - OUTPUT "${_pdf_documentation_output}" + OUTPUT "${_pdf_documentation_output}" COMMAND "${CMAKE_MAKE_PROGRAM}" MAIN_DEPENDENCY "${_latex_documentation_output}" WORKING_DIRECTORY "${_latex_documentation_output}" @@ -121,7 +140,7 @@ if(${PROJECT_NAME}_WITH_PDF_DOCUMENTATION) install(FILES "${_pdf_documentation_output}" DESTINATION "${CMAKE_INSTALL_DOCDIR}" - RENAME "${PROJECT_NAME} v${PROJECT_VERSION}.pdf" + RENAME "${PROJECT_NAME}-${PROJECT_VERSION}-documentation.pdf" COMPONENT ${PROJECT_NAME}_Documentation) endif() diff --git a/projects/Z80/documentation/Makefile b/projects/Z80/documentation/Makefile deleted file mode 100644 index d4bb2cb..0000000 --- a/projects/Z80/documentation/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/projects/Z80/documentation/Thanks.rst b/projects/Z80/documentation/Thanks.rst deleted file mode 100644 index 34e2280..0000000 --- a/projects/Z80/documentation/Thanks.rst +++ /dev/null @@ -1,532 +0,0 @@ -====== -Thanks -====== - -.. only:: html - - .. |re| raw:: html - - - - .. |ren| raw:: html - - - -.. only:: latex - - .. |fe| raw:: latex - - \textsuperscript{ - - .. |ces| raw:: latex - - } - -Many thanks to the following individuals (in alphabetical order): - -* **Akimov, Vadim (lvd)** - - * For testing the library on many different platforms and CPU architectures. - -* **azesmbog** - - 1. For validating tests on real hardware. |re| |fe| :ref:`1` |ren| |ces| - 2. For discovering the unstable behavior of the ``ccf/scf`` instructions. - 3. For his invaluable help. - -* **Banks, David (hoglet)** - - 1. For cracking the flag behavior of the block instructions. |re| |fe| :ref:`2`, :ref:`3` |ren| |ces| - 2. For his research on the behavior of the ``ccf/scf`` instructions. |re| |fe| :ref:`3` |ren| |ces| - -* **Beliansky, Anatoly (Tolik_Trek)** - - * For validating tests on real hardware. |re| |fe| :ref:`4` |ren| |ces| - -* **Bobrowski, Jan** - - * For fixing the *"Z80 Full Instruction Set Exerciser for Spectrum"*. |re| |fe| :ref:`5` |ren| |ces| - -* **boo_boo** - - * For cracking the behavior of the MEMPTR register. |re| |fe| :ref:`6`, :ref:`7`, :ref:`8`, :ref:`9` |ren| |ces| - -* **Brady, Stuart** - - * For his research on the behavior of the ``ccf/scf`` instructions. |re| |fe| :ref:`10` |ren| |ces| - -* **Brewer, Tony** - - 1. For his research on the special RESET. |re| |fe| :ref:`11`, :ref:`12` |ren| |ces| - 2. For helping to crack the flag behavior of the block instructions. |re| |fe| :ref:`2` |ren| |ces| - 3. For conducting low-level tests on real hardware. |re| |fe| :ref:`2` |ren| |ces| - 4. For helping me to test different undocumented behaviors of the Zilog Z80. - -* **Bystrov, Dmitry (Alone Coder)** - - * For validating tests on real hardware. |re| |fe| :ref:`4` |ren| |ces| - -* **Chandler, Richard** - - 1. For his corrections to the documentation. - 2. For validating tests on real hardware. |re| |fe| :ref:`13` |ren| |ces| - -* **Chunin, Roman (CHRV)** - - * For testing the behavior of the MEMPTR register on real Z80 chips. |re| |fe| :ref:`6`, :ref:`7`, :ref:`8`, :ref:`9` |ren| |ces| - -* **Conway, Simon (BadBeard)** - - * For validating the *"Z80 Test Suite"* on several Z80 clones. |re| |fe| :ref:`14` |ren| |ces| - -* **Cooke, Simon** - - * For discovering how the ``out (c),0`` instruction behaves on the Zilog Z80 CMOS. |re| |fe| :ref:`15` |ren| |ces| - -* **Cringle, Frank D.** - - * For writing the *"Z80 Instruction Set Exerciser"*. |re| |fe| :ref:`16` |ren| |ces| - -* **Devic, Goran** - - * For his research on undocumented behaviors of the Z80 CPU. |re| |fe| :ref:`17` |ren| |ces| - -* **Dunn, Paul (ZXDunny)** - - * For his corrections to the documentation. - -* **Equinox** - - * For his corrections to the documentation. - -* **Flammenkamp, Achim** - - * For his article on Z80 interrupts. |re| |fe| :ref:`18` |ren| |ces| - -* **Gimeno Fortea, Pedro** - - 1. For his research work. |re| |fe| :ref:`19` |ren| |ces| - 2. For writing the first-ever ZX Spectrum emulator. |re| |fe| :ref:`20`, :ref:`21` |ren| |ces| - -* **goodboy** - - * For testing the behavior of the MEMPTR register on real Z80 chips. |re| |fe| :ref:`6`, :ref:`7`, :ref:`8`, :ref:`9` |ren| |ces| - -* **Greenway, Ian** - - * For testing the behavior of the ``ccf/scf`` instructions on real hardware. |re| |fe| :ref:`10`, :ref:`22` |ren| |ces| - -* **Harston, Jonathan Graham** - - 1. For his research work. - 2. For his technical documents about the Zilog Z80. |re| |fe| :ref:`23`, :ref:`24`, :ref:`25` |ren| |ces| - 3. For porting the *"Z80 Instruction Set Exerciser"* to the ZX Spectrum. |re| |fe| :ref:`26` |ren| |ces| - -* **Helcmanovsky, Peter (Ped7g)** - - 1. For helping me to write the *"IN-MEMPTR"* test. - 2. For writing the *"Z80 Block Flags Test"*. |re| |fe| :ref:`27`, :ref:`28` |ren| |ces| - 3. For writing the *"Z80 CCF SCF Outcome Stability"* test. |re| |fe| :ref:`28` |ren| |ces| - 4. For writing the *"Z80 INT Skip"* test. |re| |fe| :ref:`28` |ren| |ces| - 5. For his research on the unstable behavior of the ``ccf/scf`` instructions. - 6. For his invaluable help. - -* **Iborra Debón, Víctor (Eremus)** - - * For validating tests on real hardware. - -* **icebear** - - * For testing the behavior of the MEMPTR register on real Z80 chips. |re| |fe| :ref:`6`, :ref:`7`, :ref:`8`, :ref:`9` |ren| |ces| - -* **ICEknight** - - * For validating tests on real hardware. - -* **Kladov, Vladimir** - - * For cracking the behavior of the MEMPTR register. |re| |fe| :ref:`6`, :ref:`7`, :ref:`8`, :ref:`9` |ren| |ces| - -* **Krook, Magnus** - - * For validating tests on real hardware. |re| |fe| :ref:`29` |ren| |ces| - -* **London, Matthew (mattinx)** - - * For validating tests on real hardware. - -* **Martínez Cantero, Ricardo (Kyp)** - - * For validating tests on real hardware. - -* **Molodtsov, Aleksandr** - - * For testing the behavior of the MEMPTR register on real Z80 chips. |re| |fe| :ref:`6`, :ref:`7`, :ref:`8`, :ref:`9` |ren| |ces| - -* **Nair, Arjun** - - * For validating tests on real hardware. |re| |fe| :ref:`27` |ren| |ces| - -* **Nicolás-González, César** - - * For helping me to investigate the unstable behavior of the ``ccf/scf`` instructions. - -* **Ortega Sosa, Sofía** - - 1. For optimizing the emulator. - 2. For her help and support. - -* **Owen, Simon** - - * For the idea of the hooking method used in this emulator. - -* **Ownby, Matthew P.** - - * For his research on the state of the registers after POWER-ON. |re| |fe| :ref:`30` |ren| |ces| - -* **Rak, Patrik** - - 1. For improving the *"Z80 Instruction Set Exerciser for Spectrum"*. |re| |fe| :ref:`31` |ren| |ces| - 2. For cracking the behavior of the ``ccf/scf`` instructions. |re| |fe| :ref:`14`, :ref:`31` |ren| |ces| - 3. For writing the *"Zilog Z80 CPU Test Suite"*. |re| |fe| :ref:`31`, :ref:`32` |ren| |ces| - 4. For his research on the unstable behavior of the ``ccf/scf`` instructions. - -* **Rodríguez Jódar, Miguel Ángel (mcleod_ideafix)** - - * For his research on the state of the registers after POWER-ON/RESET. |re| |fe| :ref:`33` |ren| |ces| - -* **Rodríguez Palomino, Mario (r-lyeh)** - - * For teaching me how emulators work. - -* **Sainz de Baranda y Romero, Manuel** - - * For teaching me programming and giving me my first computer. - -* **Sánchez Ordiñana, José Ismael (Vaporatorius)** - - * For validating tests on real hardware. |re| |fe| :ref:`34`, :ref:`35` |ren| |ces| - -* **Sevillano Mancilla, Marta (TheMartian)** - - * For validating tests on real hardware. |re| |fe| :ref:`13` |ren| |ces| - -* **Stevenson, Dave** - - 1. For testing the special RESET on real hardware. |re| |fe| :ref:`11` |ren| |ces| - 2. For conducting low-level tests on real hardware. |re| |fe| :ref:`36` |ren| |ces| - -* **Vučenović, Zoran** - - * For writing the Pascal binding. - -* **Weissflog, Andre (Floh)** - - 1. For discovering that the ``reti/retn`` instructions defer the acceptance of the maskable interrupt. |re| |fe| :ref:`37` |ren| |ces| - 2. For writing the *"Visual Z80 Remix"* simulator. |re| |fe| :ref:`38` |ren| |ces| - -* **Wilkinson, Oli (evolutional)** - - * For validating tests on real hardware. |re| |fe| :ref:`27` |ren| |ces| - -* **Wlodek** - - * For testing the behavior of the MEMPTR register on real Z80 chips. |re| |fe| :ref:`6`, :ref:`7`, :ref:`8`, :ref:`9` |ren| |ces| - -* **Woodmass, Mark (Woody)** - - 1. For his invaluable contributions to the emuscene. - 2. For writing the *"Z80 Test Suite"*. |re| |fe| :ref:`14` |ren| |ces| - 3. For his research on the behavior of the `ccf/scf` instructions. |re| |fe| :ref:`39` |ren| |ces| - 4. For writing the *"HALT2INT"* test. - 5. For writing the *"EIHALT"* test. - -* **Young, Sean** - - 1. For his research work. - 2. For his technical documents about the Zilog Z80. |re| |fe| :ref:`19`, :ref:`30`, :ref:`40` |ren| |ces| - -* **ZXGuesser** - - * For validating tests on real hardware. - - -References -========== - -1. - - .. _r1: - - https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83384#p83384 - -2. - - .. _r2: - - https://stardot.org.uk/forums/viewtopic.php?t=15464 - - * https://stardot.org.uk/forums/viewtopic.php?p=211042#p211042 - * https://stardot.org.uk/forums/viewtopic.php?p=212021#p212021 - -3. - - .. _r3: - - Banks, David (2018-08-21). *"Undocumented Z80 Flags"* rev. 1.0. - - * https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags - * https://stardot.org.uk/forums/download/file.php?id=39831 - -4. - - .. _r4: - - https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83041#p83041 - -5. - - .. _r5: - - http://wizard.ae.krakow.pl/~jb/qaop/tests.html - -6. - - .. _r6: - - https://zxpress.ru/zxnet/zxnet.pc/5909 - -7. - - .. _r7: - - https://zx-pk.ru/threads/2506-komanda-bit-n-(hl).html - -8. - - .. _r8: - - https://zx-pk.ru/threads/2586-prosba-realshchikam-ot-emulyatorshchikov.html - -9. - - .. _r9: - - boo_boo; Kladov, Vladimir (2006-03-29). *"MEMPTR, Esoteric Register of the Zilog Z80 CPU"*. - - * https://zx-pk.ru/showpost.php?p=43688 - * https://zx-pk.ru/attachment.php?attachmentid=2984 - * https://zx-pk.ru/showpost.php?p=43800 - * https://zx-pk.ru/attachment.php?attachmentid=2989 - -10. - - .. _r10: - - https://sourceforge.net/p/fuse-emulator/mailman/message/6929573 - -11. - - .. _r11: - - Brewer, Tony (2014-12). *"Z80 Special Reset"*. - - * http://primrosebank.net/computers/z80/z80_special_reset.htm - -12. - - .. _r12: - - https://stardot.org.uk/forums/viewtopic.php?p=357136#p357136 - -13. - - .. _r13: - - https://spectrumcomputing.co.uk/forums/viewtopic.php?t=10555 - -14. - - .. _r14: - - https://worldofspectrum.org/forums/discussion/20345 - -15. - - .. _r15: - - https://groups.google.com/g/comp.os.cpm/c/HfSTFpaIkuU/m/KotvMWu3bZoJ - -16. - - .. _r16: - - Cringle, Frank D. (1998-01-28). *"Yaze - Yet Another Z80 Emulator"* v1.10. - - * ftp://ftp.ping.de/pub/misc/emulators/yaze-1.10.tar.gz - -17. - - .. _r17: - - https://baltazarstudios.com/zilog-z80-undocumented-behavior - -18. - - .. _r18: - - Flammenkamp, Achim. *"Interrupt Behaviour of the Z80 CPU"*. - - * http://z80.info/interrup.htm - -19. - - .. _r19: - - Young, Sean (1998-10). *"Z80 Undocumented Features (in Software Behaviour)"* v0.3. - - * http://www.msxnet.org/tech/Z80/z80undoc.txt - -20. - - .. _r20: - - https://elmundodelspectrum.com/desenterrando-el-primer-emulador-de-spectrum - -21. - - .. _r21: - - https://elmundodelspectrum.com/con-vosotros-el-emulador-de-pedro-gimeno-1989 - -22. - - .. _r22: - - https://sourceforge.net/p/fuse-emulator/mailman/message/4502844 - -23. - - .. _r23: - - Harston, Jonathan Graham (2008). *"Full Z80 Opcode List Including Undocumented Opcodes"* v0.11 (revised). - - * https://mdfs.net/Docs/Comp/Z80/OpList - -24. - - .. _r24: - - Harston, Jonathan Graham (2012). *"Z80 Microprocessor Undocumented Instructions"* v0.15. - - * https://mdfs.net/Docs/Comp/Z80/UnDocOps - -25. - - .. _r25: - - Harston, Jonathan Graham (2014). *"Z80 Opcode Map"* v0.10 (revised). - - * https://mdfs.net/Docs/Comp/Z80/OpCodeMap - -26. - - .. _r26: - - https://mdfs.net/Software/Z80/Exerciser/Spectrum - -27. - - .. _r27: - - https://spectrumcomputing.co.uk/forums/viewtopic.php?t=6102 - -28. - - .. _r28: - - https://github.com/MrKWatkins/ZXSpectrumNextTests - -29. - - .. _r29: - - https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83157#p83157 - -30. - - .. _r30: - - Young, Sean (2005-09-18). *"Undocumented Z80 Documented, The"* v0.91. - - * http://www.myquest.nl/z80undocumented - * http://www.myquest.nl/z80undocumented/z80-documented-v0.91.pdf - -31. - - .. _r31: - - https://worldofspectrum.org/forums/discussion/41704 - - * http://zxds.raxoft.cz/taps/misc/zexall2.zip - -32. - - .. _r32: - - https://worldofspectrum.org/forums/discussion/41834 - - * http://zxds.raxoft.cz/taps/misc/z80test-1.0.zip - * https://github.com/raxoft/z80test - -33. - - .. _r33: - - https://worldofspectrum.org/forums/discussion/34574 - -34. - - .. _r34: - - https://worldofspectrum.org/forums/discussion/comment/668760/#Comment_668760 - -35. - - .. _r35: - - https://jisanchez.com/test-a-dos-placas-de-zx-spectrum - -36. - - .. _r36: - - https://stardot.org.uk/forums/viewtopic.php?p=212360#p212360 - -37. - - .. _r37: - - Weissflog, Andre (2021-12-17). *"New Cycle-Stepped Z80 Emulator, A"*. - - * https://floooh.github.io/2021/12/17/cycle-stepped-z80.html - -38. - - .. _r38: - - https://github.com/floooh/v6502r - -39. - - .. _r39: - - https://groups.google.com/g/comp.sys.sinclair/c/WPsPr6j6w5k/m/O_u1zNQf3VYJ - -40. - - .. _r40: - - Young, Sean (1997-09-21). *"Zilog Z80 CPU Specifications"*. - - * http://www.msxnet.org/tech/Z80/z80.zip diff --git a/projects/Z80/documentation/VersionHistory.rst b/projects/Z80/documentation/VersionHistory.rst deleted file mode 100644 index d2b3996..0000000 --- a/projects/Z80/documentation/VersionHistory.rst +++ /dev/null @@ -1,75 +0,0 @@ -=============== -Version history -=============== - -Z80 v0.2-pre -============ - -*Released on 2024-04-18* - -This is an important update that addresses a number of issues and also includes new features. Please note that the changes introduced in this release break the binary compatibility with the previous version. - -**Changes:** - -1. Changed the :doc:`license ` from GPL to LGPL (by popular request). -2. Moved the public header from ```` to ````. -3. Removed the Xcode project. -4. Switched the build system from Premake to `CMake `_. -5. Switched to `Zeta `_ v0.1. -6. Added `pkg-config `_ support. -7. Added the following files to the project: :file:`.vimrc`, :file:`CITATION.cff`, :file:`file_id.diz` and :file:`THANKS`. -8. Added detailed documentation. -9. Added Pascal binding, courtesy of Zoran Vučenović. -10. Added tests. -11. Added :ref:`public macros ` for checking the library version, working with flags, accessing the 16-bit registers and other purposes. -12. Added the ability to end the emulation loop immediately, and the :c:func:`z80_break` function. -13. Added the :c:func:`z80_execute` function for running a simplified emulation without RESET and interrupts. -14. Added the :c:func:`z80_refresh_address` function for getting the refresh address of the current M1 cycle. -15. Added the :c:func:`z80_in_cycle` and :c:func:`z80_out_cycle` functions for obtaining the clock cycle at which the I/O M-cycle begins, relative to the start of the instruction. -16. Renamed the ``z80_reset`` function to :c:func:`z80_instant_reset`. -17. Added optional emulation of the special RESET, and the :c:func:`z80_special_reset` function. -18. Added the :c:data:`Z80::fetch_opcode` and :c:data:`Z80::fetch` callbacks for performing opcode fetch operations and memory read operations on instruction data, respectively. -19. Added the :c:data:`Z80::nop` callback for performing disregarded opcode fetch operations during internal NOP M-cycles. -20. Added emulation of the NMI acknowledge M-cycle through the new :c:data:`Z80::nmia` callback. -21. Added emulation of the INT acknowledge M-cycle through the new :c:data:`Z80::inta` callback, which replaces ``Z80::int_data``. -22. Added optional full emulation of the interrupt mode 0, along with the new :c:data:`Z80::int_fetch` callback for performing bus read operations on instruction data. If not enabled at compile-time, the old simplified emulation is built, which supports only the most typical instructions. -23. Added four callbacks for notifying the execution of important instructions: :c:data:`Z80::ld_i_a`, :c:data:`Z80::ld_r_a`, :c:data:`Z80::reti` and :c:data:`Z80::retn`. -24. Added hooking functionality through the ``ld h,h`` instruction and the new :c:data:`Z80::hook` callback. -25. Added the :c:data:`Z80::illegal` callback for delegating the emulation of illegal instructions. -26. Added :ref:`emulation options ` that can be configured at runtime. -27. Removed ``Z80::state``. Replaced with individual members for the registers, the interrupt enable flip-flops and the interrupt mode. -28. Removed the superfluous EI flag. The previous opcode is checked instead, which is faster and makes the :c:type:`Z80` object smaller. -29. Removed all module-related stuff. -30. Added emulation of the additional flag changes performed during the extra 5 clock cycles of the following instructions: ``ldir``, ``lddr``, ``cpir``, ``cpdr``, ``inir``, ``indr``, ``otir`` and ``otdr``. -31. Added emulation of the interrupt acceptance deferral that occurs during the ``reti`` and ``retn`` instructions. -32. Added MEMPTR emulation. The ``bit N,(hl)`` instruction now produces a correct value of F. -33. Added optional emulation of Q. If enabled at compile-time, the ``ccf`` and ``scf`` instructions will produce a correct value of F. -34. Added emulation of the ``out (c),255`` instruction (Zilog Z80 CMOS). -35. Added optional emulation of the bug affecting the ``ld a,{i|r}`` instructions (Zilog Z80 NMOS). If enabled at compile-time and configured at runtime, the P/V flag will be reset if an INT is accepted during the execution of these instructions. -36. Increased granularity. The emulator can now stop directly after fetching a prefix ``DDh`` or ``FDh`` if it runs out of clock cycles. This also works during the INT response in mode 0. -37. Reimplemented the HALT state. The emulation should now be fully accurate. HALTskip optimization is also supported. -38. Fixed a bug in the ``sll`` instruction. -39. Fixed a bug in the ``INX`` and ``OUTX`` macros affecting the S and N flags. -40. Fixed a bug in the ``OUTX`` macro affecting the MSByte of the port number. -41. Fixed the clock cycles of the ``dec XY`` and ``in (c)`` instructions. -42. Fixed the ``read_16`` function so that the order of the memory read operations is not determined by the order in which the compiler evaluates expressions. -43. Fixed the order in which the memory write operations are performed when the SP register is involved. This affects the NMI response, the INT response in modes 1 and 2, and the following instructions: ``ex (sp),{hl|XY}``, ``push TT``, ``push XY``, ``call WORD``, ``call Z,WORD`` and ``rst N``. -44. Fixed the handling of illegal instructions to avoid stack overflows in long sequences of ``DDh/FDh`` prefixes. -45. Fixed several implicit conversions to avoid warnings about loss of sign and precision. -46. Fixed some bitwise operations to avoid undefined behavior and arithmetic right shifts on signed integers. -47. Fixed violations of the C standard in several identifiers. -48. Renamed the 8-bit register lists: ``X/Y`` to ``J/K``; ``J/K`` and ``P/Q`` to ``O/P``. -49. Replaced all P/V overflow computation functions with a single, faster macro. -50. Replaced all register resolution functions with macros. -51. Replaced all ``ld {J,K|O,P}`` instructions that have the same destination and source register with NOPs. In addition, the "illegal" forms of the following instructions are now executed without using the illegal instruction handler: ``ld O,P``, ``ld O,BYTE``, ``U [a,]P`` and ``V O``. -52. Optimizations in flag computation and condition evaluation. -53. New source code comments and improvements to existing ones. -54. Improved code aesthetics. -55. Other improvements, optimizations and minor changes. - -Z80 v0.1 -======== - -*Released on 2018-11-10* - -Initial public release. diff --git a/projects/Z80/documentation/APIReference.rst b/projects/Z80/documentation/api-reference.rst similarity index 95% rename from projects/Z80/documentation/APIReference.rst rename to projects/Z80/documentation/api-reference.rst index 3076c20..5b55c20 100644 --- a/projects/Z80/documentation/APIReference.rst +++ b/projects/Z80/documentation/api-reference.rst @@ -43,13 +43,14 @@ Stopping the emulation .. doxygenfunction:: z80_break -Requesting interrupts ---------------------- +Sending signals +--------------- .. doxygenfunction:: z80_int .. doxygenfunction:: z80_nmi .. doxygenfunction:: z80_instant_reset .. doxygenfunction:: z80_special_reset +.. doxygenfunction:: z80_wait Obtaining information --------------------- @@ -80,7 +81,11 @@ Limits Opcodes ------- +.. doxygendefine:: Z80_HALT .. doxygendefine:: Z80_HOOK +.. doxygendefine:: Z80_JP_WORD +.. doxygendefine:: Z80_NOP +.. doxygendefine:: Z80_RET Flags ----- diff --git a/projects/Z80/documentation/conf.py b/projects/Z80/documentation/conf.py index 63e322b..21f326b 100644 --- a/projects/Z80/documentation/conf.py +++ b/projects/Z80/documentation/conf.py @@ -1,56 +1,13 @@ # Configuration file for the Sphinx documentation builder. # -# This file only contains a selection of the most common options. For a full -# list see the documentation: +# For the full list of built-in configuration values, see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - -# -- Project information ----------------------------------------------------- - -project = 'Z80' -copyright = u'1999-2024 Manuel Sainz de Baranda y Goñi' -author = u'Manuel Sainz de Baranda y Goñi' -version = '0.2' - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. extensions = ['sphinx.ext.autosectionlabel', 'breathe'] - -# sphinx.ext.autosectionlabel -autosectionlabel_prefix_document = True - -# Breathe -breathe_default_project = 'Z80' -breathe_domain_by_extension = {'h': 'c'} - -# Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# +autosectionlabel_prefix_document = True +breathe_domain_by_extension = {'h': 'c'} #html_theme = 'haiku' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = [] +latex_elements = {'releasename': 'Version'} diff --git a/projects/Z80/documentation/index.rst b/projects/Z80/documentation/index.rst index 8979801..5fa02dc 100644 --- a/projects/Z80/documentation/index.rst +++ b/projects/Z80/documentation/index.rst @@ -3,32 +3,21 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -=== -Z80 -=== +======== +Contents +======== .. toctree:: :maxdepth: 2 - :caption: Contents - - Introduction - Installation - Tests - Integration - Usage - APIReference - -.. toctree:: - :maxdepth: 2 - :caption: Project - - Thanks - VersionHistory - License - -.. toctree:: - :maxdepth: 2 - :caption: Indices and tables + introduction + installation-from-source-code + tests + integration + usage + api-reference + thanks + version-history + license genindex search diff --git a/projects/Z80/documentation/Installation.rst b/projects/Z80/documentation/installation-from-source-code.rst similarity index 69% rename from projects/Z80/documentation/Installation.rst rename to projects/Z80/documentation/installation-from-source-code.rst index 186c3a0..eac80c4 100644 --- a/projects/Z80/documentation/Installation.rst +++ b/projects/Z80/documentation/installation-from-source-code.rst @@ -1,6 +1,6 @@ -============ -Installation -============ +============================= +Installation from source code +============================= .. only:: html @@ -14,21 +14,30 @@ Installation \newline +.. |cmake_option_install_component| replace:: ``--component`` +.. _cmake_option_install_component: https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake-install-component + .. |cmake_option_build_config| replace:: ``--config`` .. _cmake_option_build_config: https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake-build-config .. |cmake_option_install_strip| replace:: ``--strip`` .. _cmake_option_install_strip: https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake-install-strip -.. |cmake_option_install_component| replace:: ``--component`` -.. _cmake_option_install_component: https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake-install-component +.. _config-file package: https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#config-file-packages +.. _CP/M: https://en.wikipedia.org/wiki/CP/M +.. _file: https://people.freedesktop.org/~dbn/pkg-config-guide.html +.. _pkg-config: https://www.freedesktop.org/wiki/Software/pkg-config +.. _unit tests in JSON format: https://github.com/SingleStepTests/z80 +.. _ZX Spectrum: https://en.wikipedia.org/wiki/ZX_Spectrum Prerequisites ============= You will need `CMake `_ v3.14 or later to build the package and, optionally, recent versions of `Doxygen `_, `Sphinx `_ and `Breathe `_ to compile the documentation. Also, make sure that you have `LaTeX `_ with PDF support installed on your system if you want to generate the documentation in PDF format. -The emulator requires some types and macros included in `Zeta `_, a dependency-free, `header-only `_ library used to retain compatibility with most C compilers. Install Zeta or extract its `source code tarball `_ to the root directory of the Z80 project or its parent directory. Zeta is the sole dependency; the emulator is a freestanding implementation and as such does not depend on the `C standard library `_. +The Z80 library requires some types and macros included in `Zeta `_, a `header-only `_, dependency-free library used for portability reasons. Install Zeta or extract its `source code tarball `_ to the root directory of the Z80 project or its parent directory. Zeta is the sole dependency; the emulator does not depend on the `C standard library `_. + +Lastly, the package includes two testing tools, which are optional to build. The first one runs various Z80-specific tests for `CP/M`_ and `ZX Spectrum`_, and will use `libzip `_ and `zlib `_ if they are available on your system. The second tool is for `unit tests in JSON format`_ and requires the `cJSON `_ and `Z80InsnClock `_ libraries. Configure ========= @@ -45,7 +54,7 @@ The resulting build files can be configured by passing options to ``cmake``. To .. code-block:: sh - cmake -LAH + cmake -LAH -N -B . If in doubt, read the `CMake documentation `_ for more information on configuration options. The following are some of the most relevant standard options of CMake: @@ -59,6 +68,11 @@ If in doubt, read the `CMake documentation `_ Choose the type of build (configuration) to generate. |br| |nl| The default is ``Release``. +.. option:: -DCMAKE_INSTALL_NAME_DIR="" + + Specify the `directory portion `_ of the `dynamic library install name `_ on Apple platforms (for installed shared libraries). |br| |nl| + Not defined by default. + .. option:: -DCMAKE_INSTALL_PREFIX="" Specify the installation prefix. |br| |nl| @@ -70,22 +84,22 @@ Package-specific options are prefixed with ``Z80_`` and can be divided into two .. option:: -DZ80_DEPOT_LOCATION="" - Specify the directory or URL of the depot containing the test files (i.e., the firmware and software required by the :doc:`testing tool `). |br| |nl| + Specify the directory or URL of the depot containing the test files (i.e., the firmware and software required by the :file:`test-Z80` tool). |br| |nl| The default is ``"http://zxe.io/depot"``. .. option:: -DZ80_FETCH_TEST_FILES=(YES|NO) - Copy or download the test files from the depot to the build directory. |br| |nl| + If :option:`Z80_WITH_TESTING_TOOL<-DZ80_WITH_TESTING_TOOL>` is ``YES``, copy or download the test files from the depot to the build directory. |br| |nl| The default is ``NO``. .. option:: -DZ80_INSTALL_CMAKEDIR="" - Specify the directory in which to install the CMake `config-file package `_. |br| |nl| + Specify the directory in which to install the CMake `config-file package`_. |br| |nl| The default is ``"${CMAKE_INSTALL_LIBDIR}/cmake/Z80"``. .. option:: -DZ80_INSTALL_PKGCONFIGDIR="" - Specify the directory in which to install the `pkg-config `_ `file `_. |br| |nl| + Specify the directory in which to install the `pkg-config`_ `file`_. |br| |nl| The default is ``"${CMAKE_INSTALL_LIBDIR}/pkgconfig"``. .. option:: -DZ80_NOSTDLIB_FLAGS=(Auto|"[[;...]]") @@ -112,7 +126,7 @@ Package-specific options are prefixed with ``Z80_`` and can be divided into two .. option:: -DZ80_WITH_CMAKE_SUPPORT=(YES|NO) - Generate and install the CMake `config-file package `_. |br| |nl| + Generate and install the CMake `config-file package`_. |br| |nl| The default is ``NO``. .. option:: -DZ80_WITH_HTML_DOCUMENTATION=(YES|NO) @@ -129,7 +143,7 @@ Package-specific options are prefixed with ``Z80_`` and can be divided into two .. option:: -DZ80_WITH_PKGCONFIG_SUPPORT=(YES|NO) - Generate and install the `pkg-config `_ `file `_. |br| |nl| + Generate and install the `pkg-config`_ `file`_. |br| |nl| The default is ``NO``. .. option:: -DZ80_WITH_STANDARD_DOCUMENTS=(YES|NO) @@ -137,14 +151,20 @@ Package-specific options are prefixed with ``Z80_`` and can be divided into two Install the standard text documents distributed with the package: :file:`AUTHORS`, :file:`COPYING`, :file:`COPYING.LESSER`, :file:`HISTORY`, :file:`README` and :file:`THANKS`. |br| |nl| The default is ``NO``. -.. option:: -DZ80_WITH_TESTS=(YES|NO) +.. option:: -DZ80_WITH_STEP_TESTING_TOOL=(YES|NO) - Build the :doc:`testing tool `. |br| |nl| + Build :file:`step-test-Z80`, a tool for `unit tests in JSON format`_. |br| |nl| + It requires cJSON and Z80InsnClock. |br| |nl| + The default is ``NO``. + +.. option:: -DZ80_WITH_TESTING_TOOL=(YES|NO) + + Build :file:`test-Z80`, a tool that runs various Z80-specific tests for `CP/M`_ and `ZX Spectrum`_. |br| |nl| The default is ``NO``. .. _cmake_package_source_code_options: -The second group of package-specific options configures the source code of the library by predefining macros that enable :ref:`optional features `: +The second group of package-specific options configures the source code of the library by predefining macros that enable :ref:`optional features `: .. option:: -DZ80_WITH_EXECUTE=(YES|NO) @@ -161,6 +181,16 @@ The second group of package-specific options configures the source code of the l Enable optional notifications for any ``reti`` or ``retn`` instruction executed during the interrupt mode 0 response. |br| |nl| The default is ``NO``. +.. option:: -DZ80_WITH_PARITY_COMPUTATION=(YES|NO) + + Enable actual parity calculation for the P/V flag instead of using a table of precomputed values (NOT RECOMMENDED for production builds). |br| |nl| + The default is ``NO``. + +.. option:: -DZ80_WITH_PRECOMPUTED_DAA=(YES|NO) + + Use a table of precomputed values to emulate the ``daa`` instruction (NOT RECOMMENDED for production builds). |br| |nl| + The default is ``NO``. + .. option:: -DZ80_WITH_Q=(YES|NO) Build the implementation of `Q `_. |br| |nl| @@ -201,7 +231,9 @@ Finally, once the build system is configured according to your needs, build and cmake --build . [--config (Debug|Release|RelWithDebInfo|MinSizeRel)] cmake --install . [--config ] [--strip] [--component ] -The |cmake_option_build_config|_ option is only necessary for those `CMake generators `_ that ignore :option:`CMAKE_BUILD_TYPE<-DCMAKE_BUILD_TYPE>` (e.g., Xcode and Visual Studio). Use |cmake_option_install_strip|_ to remove debugging information and non-public symbols when installing non-debug builds of the shared library. To install only a specific component of the package, use the |cmake_option_install_component|_ option. The project defines the following components: +The |cmake_option_build_config|_ option is only necessary for those `CMake generators `_ that ignore :option:`CMAKE_BUILD_TYPE<-DCMAKE_BUILD_TYPE>` (e.g., Xcode and Visual Studio). Use |cmake_option_install_strip|_ to remove debugging information and non-public symbols when installing non-debug builds of the shared library. To install only a specific component of the package, use the |cmake_option_install_component|_ option. + +The project defines the following components: .. option:: Z80_Runtime @@ -221,3 +253,9 @@ The |cmake_option_build_config|_ option is only necessary for those `CMake gener * Documentation in HTML format. * Documentation in PDF format. + +.. option:: Z80_Testing + + * Testing tools. + +By default, the build system will install ``Z80_Runtime``, ``Z80_Development`` and ``Z80_Documentation``. The ``Z80_Testing`` component can only be installed explicitly. diff --git a/projects/Z80/documentation/Integration.rst b/projects/Z80/documentation/integration.rst similarity index 63% rename from projects/Z80/documentation/Integration.rst rename to projects/Z80/documentation/integration.rst index cdbf677..f744ed7 100644 --- a/projects/Z80/documentation/Integration.rst +++ b/projects/Z80/documentation/integration.rst @@ -28,9 +28,9 @@ When not specified as a component, the linking method is selected according to : As a CMake subproject ===================== -To embed the Z80 library as a CMake subproject, extract the source code tarballs of `Zeta `_ and `Z80 `_ (or clone their respective repositories) into a subdirectory of another project. Then use |add_subdirectory|_ in the parent project to add the Z80 source code tree to the build process (N.B., the Z80 subproject will automatically find Zeta and import it as an `interface library `_). +To embed the Z80 library as a CMake subproject, extract the source code tarballs of `Zeta `__ and `Z80 `_ (or clone their respective repositories) into a subdirectory of another project. Then use |add_subdirectory|_ in the parent project to add the Z80 source code tree to the build process (N.B., the Z80 subproject will automatically find Zeta and import it as an `interface library `_). -It is advisable to configure the Z80 library in the :file:`CMakeLists.txt` of the parent project. This will prevent the user from having to specify :ref:`configuration options for the Z80 subproject ` through the command line when building the main project. +It is advisable to configure the Z80 library in the :file:`CMakeLists.txt` of the parent project. This will eliminate the need for the user to specify :ref:`configuration options for the Z80 subproject ` through the command line when building the main project. Example: @@ -50,29 +50,29 @@ Non-CMake-based projects The source code of the emulator can be configured at compile time by predefining a series of macros. Both :file:`Z80.h` and :file:`Z80.c` obey the first two explained below. The rest of the macros are only relevant when compiling :file:`Z80.c`: -.. c:macro:: Z80_DEPENDENCIES_HEADER +.. c:macro:: Z80_EXTERNAL_HEADER Specifies the only external header to ``#include``, replacing all others. - Predefine this macro to provide a header file that defines the external types and macros used by the emulator, thus preventing your project from depending on `Zeta `_: + Predefine this macro to provide a header file that defines the external types and macros used by the emulator, thus preventing your project from depending on `Zeta `__: * Macros: ``Z_ALWAYS_INLINE``, ``Z_API_EXPORT``, ``Z_API_IMPORT``, ``Z_CAST``, ``Z_EMPTY``, ``Z_EXTERN_C_BEGIN``, ``Z_EXTERN_C_END``, ``Z_MEMBER_OFFSET``, ``Z_NULL``, ``Z_UINT8_ROTATE_LEFT``, ``Z_UINT8_ROTATE_RIGHT``, ``Z_UINT16``, ``Z_UINT16_BIG_ENDIAN``, ``Z_UINT32``, ``Z_UINT32_BIG_ENDIAN``, ``Z_UNUSED``, ``Z_USIZE`` and ``Z_USIZE_MAXIMUM``. - * Types: ``zboolean``, ``zchar``, ``zsint``, ``zsint8``, ``zuint``, ``zuint8``, ``zuint16``, ``zuint32``, ``zusize``, ``ZInt16`` and ``ZInt32``. + * Types: ``zbool``, ``zchar``, ``zsint``, ``zsint8``, ``zuint``, ``zuint8``, ``zuint16``, ``zuint32``, ``zusize``, ``ZInt16`` and ``ZInt32``. - You can use this macro when compiling :file:`Z80.c` as a part of your project or (if your types do not break the binary compatibility) when including ```` and linking against a pre-built Z80 library. + You can use this macro when compiling :file:`Z80.c` within your project or (if your types do not break the binary compatibility) when including ```` and linking against a pre-built Z80 library. .. c:macro:: Z80_STATIC - Restricts the visibility of public symbols. + Indicates that the emulator is a static library. - This macro is required if you are building :file:`Z80.c` as a static library, compiling it directly as a part of your project, or linking your program against the static version of the Z80 library. In either of these cases, make sure this macro is defined before including ``"Z80.h"`` or ````. + This macro must be predefined when building :file:`Z80.c` as a static library. Additionally, if you compile :file:`Z80.c` directly within your project or link your program against the static version of the Z80 library, ensure that this macro is defined before including ``"Z80.h"`` or ````. .. c:macro:: Z80_WITH_LOCAL_HEADER Tells :file:`Z80.c` to ``#include "Z80.h"`` instead of ````. -The :ref:`optional features ` of the emulator mentioned in the ":doc:`Installation`" section are disabled by default. If you compile :file:`Z80.c` as a part of your project, enable those features you need by predefining their respective activation macros. They have the same name as their :ref:`CMake equivalents `: +The :ref:`optional features ` of the emulator mentioned in the ":ref:`Configure `" section of ":doc:`installation-from-source-code`" are disabled by default. If you compile :file:`Z80.c` within your project, enable those features you need by predefining their respective activation macros. They have the same name as their :ref:`CMake equivalents `: .. c:macro:: Z80_WITH_EXECUTE @@ -86,6 +86,14 @@ The :ref:`optional features ` of the emulator me Enables optional notifications for any ``reti`` or ``retn`` instruction executed during the interrupt mode 0 response. +.. c:macro:: Z80_WITH_PARITY_COMPUTATION + + Enables actual parity calculation for the P/V flag instead of using a table of precomputed values. + +.. c:macro:: Z80_WITH_PRECOMPUTED_DAA + + Enables the use of a table of precomputed values to emulate the ``daa`` instruction. + .. c:macro:: Z80_WITH_Q Enables the implementation of `Q `_. @@ -102,4 +110,4 @@ The :ref:`optional features ` of the emulator me Enables the implementation of the bug affecting the Zilog Z80 NMOS, which causes the P/V flag to be reset when a maskable interrupt is accepted during the execution of the ``ld a,{i|r}`` instructions. -Except for :c:macro:`Z80_DEPENDENCIES_HEADER`, the above macros can be empty; the source code only checks whether they are defined. +Except for :c:macro:`Z80_EXTERNAL_HEADER`, the above macros can be empty; the source code only checks whether they are defined. diff --git a/projects/Z80/documentation/Introduction.rst b/projects/Z80/documentation/introduction.rst similarity index 100% rename from projects/Z80/documentation/Introduction.rst rename to projects/Z80/documentation/introduction.rst diff --git a/projects/Z80/documentation/License.rst b/projects/Z80/documentation/license.rst similarity index 93% rename from projects/Z80/documentation/License.rst rename to projects/Z80/documentation/license.rst index 1a18021..8000fea 100644 --- a/projects/Z80/documentation/License.rst +++ b/projects/Z80/documentation/license.rst @@ -2,7 +2,7 @@ License ======= -Copyright © 1999-2024 Manuel Sainz de Baranda y Goñi. +Copyright © 1999-2026 Manuel Sainz de Baranda y Goñi. This library is `free software `_: you can redistribute it and/or modify it under the terms of the `GNU Lesser General Public License `_ as published by the `Free Software Foundation `_, either version 3 of the License, or (at your option) any later version. diff --git a/projects/Z80/documentation/make.bat b/projects/Z80/documentation/make.bat deleted file mode 100644 index 2119f51..0000000 --- a/projects/Z80/documentation/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/projects/Z80/documentation/Tests.rst b/projects/Z80/documentation/tests.rst similarity index 100% rename from projects/Z80/documentation/Tests.rst rename to projects/Z80/documentation/tests.rst diff --git a/projects/Z80/documentation/thanks.rst b/projects/Z80/documentation/thanks.rst new file mode 100644 index 0000000..0c922aa --- /dev/null +++ b/projects/Z80/documentation/thanks.rst @@ -0,0 +1,623 @@ +====== +Thanks +====== + +.. only:: html + + .. |re| raw:: html + + + + .. |ren| raw:: html + + + +.. only:: latex + + .. |fe| raw:: latex + + \textsuperscript{ + + .. |ces| raw:: latex + + } + +Many thanks to the following individuals (in alphabetical order): + +* **Akimov, Vadim (lvd)** + + * For testing the library on many different platforms and CPU architectures. + +* **Anisimov, Alexey (SoftLight)** + + * For testing the ``ccf/scf`` instructions on real hardware. |re| |fe| :ref:`1` |ren| |ces| + +* **azesmbog** + + 1. For validating tests on real hardware. |re| |fe| :ref:`2.1` |ren| |ces| + 2. For discovering the unstable behavior of the ``ccf/scf`` instructions. + 3. For testing the ``ccf/scf`` instructions on real hardware. |re| |fe| :ref:`1`, :ref:`3` |ren| |ces| + 4. For his invaluable help. + +* **Banks, David (hoglet)** + + 1. For deciphering the additional flag changes of the block instructions. |re| |fe| :ref:`4.1`, :ref:`4.2`, :ref:`5` |ren| |ces| + 2. For his research on the ``ccf/scf`` instructions. |re| |fe| :ref:`5`, :ref:`6` |ren| |ces| + +* **Beliansky, Anatoly (Tolik_Trek)** + + * For validating tests on real hardware. |re| |fe| :ref:`2.2` |ren| |ces| + +* **Bobrowski, Jan** + + * For fixing *"Z80 Full Instruction Set Exerciser for Spectrum"*. |re| |fe| :ref:`7` |ren| |ces| + +* **boo_boo** + + * For deciphering the behavior of MEMPTR. |re| |fe| :ref:`8`, :ref:`9`, :ref:`10`, :ref:`11` |ren| |ces| + +* **Brady, Stuart** + + * For his research on the ``ccf/scf`` instructions. |re| |fe| :ref:`12` |ren| |ces| + +* **Brewer, Tony** + + 1. For his research on the special RESET. |re| |fe| :ref:`4.3`, :ref:`13` |ren| |ces| + 2. For helping to decipher the additional flag changes of the block instructions. |re| |fe| :ref:`4` |ren| |ces| + 3. For conducting low-level tests on real hardware. |re| |fe| :ref:`4` |ren| |ces| + 4. For helping me to test different undocumented behaviors of the Zilog Z80. + 5. For discovering that the ``DD/FD`` prefixes affect the behavior of the ``ccf/scf`` instructions. |re| |fe| :ref:`4.4` |ren| |ces| + +* **Bystrov, Dmitry (Alone Coder)** + + * For validating tests on real hardware. |re| |fe| :ref:`2.2` |ren| |ces| + +* **Chaikin, Mikhail (P321)** + + * For testing the ``ccf/scf`` instructions on real hardware. |re| |fe| :ref:`1` |ren| |ces| + +* **Chandler, Richard** + + 1. For his corrections to the documentation. + 2. For validating tests on real hardware. |re| |fe| :ref:`14` |ren| |ces| + +* **Chunin, Roman (CHRV)** + + * For testing the behavior of MEMPTR on real hardware. |re| |fe| :ref:`8`, :ref:`9`, :ref:`10`, :ref:`11` |ren| |ces| + +* **Conway, Simon (BadBeard)** + + * For validating *"Z80 Test Suite"* on several Z80 clones. |re| |fe| :ref:`15` |ren| |ces| + +* **Cooke, Simon** + + * For discovering how the ``out (c),0`` instruction behaves on the Zilog Z80 CMOS. |re| |fe| :ref:`16` |ren| |ces| + +* **Cringle, Frank D.** + + * For writing *"Z80 Instruction Set Exerciser"*. |re| |fe| :ref:`17` |ren| |ces| + +* **Devic, Goran** + + * For his research on undocumented behaviors of the Z80 CPU. |re| |fe| :ref:`18` |ren| |ces| + +* **Dmitriev, Dmitry (DDp)** + + * For testing the ``ccf/scf`` instructions on real hardware. |re| |fe| :ref:`3` |ren| |ces| + +* **Dunn, Paul (ZXDunny)** + + * For his corrections to the documentation. + +* **Equinox** + + * For his corrections to the documentation. + +* **Flammenkamp, Achim** + + * For his article on Z80 interrupts. |re| |fe| :ref:`19` |ren| |ces| + +* **Gimeno Fortea, Pedro** + + 1. For his research work. |re| |fe| :ref:`20` |ren| |ces| + 2. For writing the first-ever ZX Spectrum emulator. |re| |fe| :ref:`21`, :ref:`22` |ren| |ces| + +* **Greenway, Ian** + + * For testing the ``ccf/scf`` instructions on real hardware. |re| |fe| :ref:`12`, :ref:`23` |ren| |ces| + +* **Harston, Jonathan Graham** + + 1. For his research work. + 2. For his technical documents about the Zilog Z80. |re| |fe| :ref:`24`, :ref:`25`, :ref:`26` |ren| |ces| + 3. For porting *"Z80 Instruction Set Exerciser"* to the ZX Spectrum. |re| |fe| :ref:`27` |ren| |ces| + +* **Helcmanovsky, Peter (Ped7g)** + + 1. For helping me to write *"IN-MEMPTR"*. + 2. For writing *"Z80 Block Flags Test"*. |re| |fe| :ref:`2`, :ref:`28` |ren| |ces| + 3. For writing *"Z80 CCF SCF Outcome Stability"*. |re| |fe| :ref:`28` |ren| |ces| + 4. For writing *"Z80 INT Skip"*. |re| |fe| :ref:`28` |ren| |ces| + 5. For writing *"FDDD2"*, *"Z80 DDFD3"*, *"Z80 IM1 vs JR"* and many other tests. + 6. For his research on the unstable behavior of the ``ccf/scf`` instructions. + 7. For his invaluable help. + +* **Iborra Debón, Víctor (Eremus)** + + * For validating tests on real hardware. + +* **icebear** + + * For testing the behavior of MEMPTR on real hardware. |re| |fe| :ref:`8`, :ref:`9`, :ref:`10`, :ref:`11` |ren| |ces| + +* **ICEknight** + + * For validating tests on real hardware. + +* **Ilyichev, Ivan (ivang78)** + + * For testing the behavior of MEMPTR on real hardware. |re| |fe| :ref:`29` |ren| |ces| + +* **Kladov, Vladimir** + + * For deciphering the behavior of MEMPTR. |re| |fe| :ref:`8`, :ref:`9`, :ref:`10`, :ref:`11` |ren| |ces| + +* **Kovrigin, Alexey (creator)** + + * For testing the ``ccf/scf`` instructions on real hardware. |re| |fe| :ref:`1`, :ref:`3` |ren| |ces| + +* **Krook, Magnus** + + * For validating tests on real hardware. |re| |fe| :ref:`2.3` |ren| |ces| + +* **London, Matthew (mattinx)** + + * For validating tests on real hardware. + +* **Martínez Cantero, Ricardo (Kyp)** + + * For validating tests on real hardware. + +* **Molodtsov, Aleksandr** + + * For testing the behavior of MEMPTR on real hardware. |re| |fe| :ref:`8`, :ref:`9`, :ref:`10`, :ref:`11` |ren| |ces| + +* **Nair, Arjun** + + * For validating tests on real hardware. |re| |fe| :ref:`2` |ren| |ces| + +* **Nicolás-González, César** + + * For helping me to investigate the unstable behavior of the ``ccf/scf`` instructions. + +* **Ortega Sosa, Sofía** + + 1. For optimizing the emulator. + 2. For her help and support. + +* **Owen, Simon** + + * For the idea of the hooking method used in this emulator. + +* **Ownby, Matthew P.** + + * For his research on the state of the registers after POWER-ON. |re| |fe| :ref:`30` |ren| |ces| + +* **Rak, Patrik** + + 1. For improving *"Z80 Instruction Set Exerciser for Spectrum"*. |re| |fe| :ref:`31` |ren| |ces| + 2. For deciphering the behavior of the ``ccf/scf`` instructions. |re| |fe| :ref:`15`, :ref:`31` |ren| |ces| + 3. For writing *"Zilog Z80 CPU Test Suite"*. |re| |fe| :ref:`31`, :ref:`32` |ren| |ces| + 4. For his research on the unstable behavior of the ``ccf/scf`` instructions. + +* **Rodríguez Jódar, Miguel Ángel (mcleod_ideafix)** + + 1. For his research on the state of the registers after POWER-ON/RESET. |re| |fe| :ref:`33` |ren| |ces| + 2. For writing *"Z80 Initial Condition Retriever"*. |re| |fe| :ref:`33.1` |ren| |ces| + +* **Rodríguez Palomino, Mario (r-lyeh)** + + * For teaching me how emulators work. + +* **Sainz de Baranda y Romero, Manuel** + + * For teaching me programming and giving me my first computer. + +* **Sanarin, Dmitry (haywire)** + + * For testing the ``ccf/scf`` instructions on real hardware. |re| |fe| :ref:`3` |ren| |ces| + +* **Sánchez Ordiñana, José Ismael (Vaporatorius)** + + * For validating tests on real hardware. |re| |fe| :ref:`32.1`, :ref:`34` |ren| |ces| + +* **Sapach, Michael (cafedead)** + + * For writing *"CPD-Test"*. |re| |fe| :ref:`29` |ren| |ces| + +* **Sevillano Mancilla, Marta (TheMartian)** + + * For validating tests on real hardware. |re| |fe| :ref:`14.1` |ren| |ces| + +* **Stevenson, Dave** + + 1. For testing the special RESET on real hardware. |re| |fe| :ref:`13` |ren| |ces| + 2. For conducting low-level tests on real hardware. |re| |fe| :ref:`4.5` |ren| |ces| + +* **Titov, Andrey (Titus)** + + * For his research on the ``ccf/scf`` instructions. |re| |fe| :ref:`1`, :ref:`3` |ren| |ces| + +* **Vasin, Yuriy (goodboy)** + + 1. For testing the behavior of MEMPTR on real hardware. |re| |fe| :ref:`8`, :ref:`9`, :ref:`10`, :ref:`11`, :ref:`29` |ren| |ces| + 2. For testing the ``ccf/scf`` instructions on real hardware. |re| |fe| :ref:`1`, :ref:`29` |ren| |ces| + +* **Vučenović, Zoran** + + * For writing the Pascal binding. + +* **Weissflog, Andre (Floh)** + + 1. For discovering that the ``reti/retn`` instructions defer the acceptance of the maskable interrupt. |re| |fe| :ref:`35` |ren| |ces| + 2. For writing the *"Visual Z80 Remix"* simulator. |re| |fe| :ref:`36` |ren| |ces| + +* **Wilkinson, Oli (evolutional)** + + * For validating tests on real hardware. |re| |fe| :ref:`2` |ren| |ces| + +* **Wlodek** + + * For testing the behavior of MEMPTR on real hardware. |re| |fe| :ref:`8`, :ref:`9`, :ref:`10`, :ref:`11` |ren| |ces| + +* **Woodmass, Mark (Woody)** + + 1. For his invaluable contributions to the emuscene. + 2. For writing *"Z80 Test Suite"*. |re| |fe| :ref:`15` |ren| |ces| + 3. For writing *"ED777F"*, *"FDDD"*, *"EI48K"*, *"EIHALT"*, *"HALT2INT"*, *"IFF2 Bug"*, *"Super HALT Invaders Test"* and many other tests. + 4. For his research on the ``ccf/scf`` instructions. |re| |fe| :ref:`37` |ren| |ces| + +* **Young, Sean** + + 1. For his research work. + 2. For his technical documents about the Zilog Z80. |re| |fe| :ref:`20`, :ref:`30`, :ref:`38` |ren| |ces| + +* **Zarubin, Stanislav (JeRrS)** + + * For testing the ``ccf/scf`` instructions on real hardware. |re| |fe| :ref:`3`, :ref:`29` |ren| |ces| + +* **ZXGuesser** + + * For validating tests on real hardware. + +References +========== + +1. + + .. _r_1: + + https://zx-pk.ru/threads/34173-revers-inzhiniring-z80.html + +2. + + .. _r_2: + + https://spectrumcomputing.co.uk/forums/viewtopic.php?t=6102 + + 1. + + .. _r_2_1: + + https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83384#p83384 + + 2. + + .. _r_2_2: + + https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83041#p83041 + + 3. + + .. _r_2_3: + + https://spectrumcomputing.co.uk/forums/viewtopic.php?p=83157#p83157 +3. + + .. _r_3: + + https://zx-pk.ru/threads/35936-zagadka-plavayushchikh-flagov-scf-ccf-raskryta!.html + +4. + + .. _r_4: + + https://stardot.org.uk/forums/viewtopic.php?t=15464 + + 1. + + .. _r_4_1: + + https://stardot.org.uk/forums/viewtopic.php?p=211042#p211042 + + 2. + + .. _r_4_2: + + https://stardot.org.uk/forums/viewtopic.php?p=212021#p212021 + + 3. + + .. _r_4_3: + + https://stardot.org.uk/forums/viewtopic.php?p=357136#p357136 + + 4. + + .. _r_4_4: + + https://stardot.org.uk/forums/viewtopic.php?p=481595#p481595 + + 5. + + .. _r_4_5: + + https://stardot.org.uk/forums/viewtopic.php?p=212360#p212360 + +5. + + .. _r_5: + + Banks, David (2018-08-21). *"Undocumented Z80 Flags"* rev. 1.0. + + * https://stardot.org.uk/forums/download/file.php?id=39831 + * https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags + +6. + + .. _r_6: + + https://github.com/hoglet67/Z80Decoder/wiki/Unstable-CCF-SCF-Behaviour + +7. + + .. _r_7: + + http://wizard.ae.krakow.pl/~jb/qaop/tests.html + +8. + + .. _r_8: + + https://zxpress.ru/zxnet/zxnet.pc/5909 + +9. + + .. _r_9: + + https://zx-pk.ru/threads/2506-komanda-bit-n-(hl).html + +10. + + .. _r_10: + + https://zx-pk.ru/threads/2586-prosba-realshchikam-ot-emulyatorshchikov.html + +11. + + .. _r_11: + + boo_boo; Kladov, Vladimir (2006-03-29). *"MEMPTR, Esoteric Register of the Zilog Z80 CPU"*. + + * https://zx-pk.ru/showpost.php?p=43688 + * https://zx-pk.ru/attachment.php?attachmentid=2984 + * https://zx-pk.ru/showpost.php?p=43800 + * https://zx-pk.ru/attachment.php?attachmentid=2989 + +12. + + .. _r_12: + + https://sourceforge.net/p/fuse-emulator/mailman/message/6929573 + +13. + + .. _r_13: + + Brewer, Tony (2014-12). *"Z80 Special Reset"*. + + * http://primrosebank.net/computers/z80/z80_special_reset.htm + +14. + + .. _r_14: + + https://spectrumcomputing.co.uk/forums/viewtopic.php?t=10555 + + 1. + + .. _r_14_1: + + https://spectrumcomputing.co.uk/forums/viewtopic.php?p=132144#p132144 + +15. + + .. _r_15: + + https://worldofspectrum.org/forums/discussion/20345 + +16. + + .. _r_16: + + https://groups.google.com/g/comp.os.cpm/c/HfSTFpaIkuU/m/KotvMWu3bZoJ + +17. + + .. _r_17: + + Cringle, Frank D. (1998-01-28). *"Yaze - Yet Another Z80 Emulator"* v1.10. + + * ftp://ftp.ping.de/pub/misc/emulators/yaze-1.10.tar.gz + +18. + + .. _r_18: + + https://baltazarstudios.com/zilog-z80-undocumented-behavior + +19. + + .. _r_19: + + Flammenkamp, Achim. *"Interrupt Behaviour of the Z80 CPU"*. + + * http://z80.info/interrup.htm + +20. + + .. _r_20: + + Young, Sean (1998-10). *"Z80 Undocumented Features (in Software Behaviour)"* v0.3. + + * http://www.msxnet.org/tech/Z80/z80undoc.txt + +21. + + .. _r_21: + + https://elmundodelspectrum.com/desenterrando-el-primer-emulador-de-spectrum + +22. + + .. _r_22: + + https://elmundodelspectrum.com/con-vosotros-el-emulador-de-pedro-gimeno-1989 + +23. + + .. _r_23: + + https://sourceforge.net/p/fuse-emulator/mailman/message/4502844 + +24. + + .. _r_24: + + Harston, Jonathan Graham (2008). *"Full Z80 Opcode List Including Undocumented Opcodes"* v0.11 (revised). + + * http://www.mdfsnet.f9.co.uk/Docs/Comp/Z80/OpList + +25. + + .. _r_25: + + Harston, Jonathan Graham (2012). *"Z80 Microprocessor Undocumented Instructions"* v0.15. + + * http://mdfs.net/Docs/Comp/Z80/UnDocOps + +26. + + .. _r_26: + + Harston, Jonathan Graham (2014). *"Z80 Opcode Map"* v0.10 (revised). + + * http://mdfs.net/Docs/Comp/Z80/OpCodeMap + +27. + + .. _r_27: + + http://mdfs.net/Software/Z80/Exerciser/Spectrum + +28. + + .. _r_28: + + https://github.com/MrKWatkins/ZXSpectrumNextTests + +29. + + .. _r_29: + + https://zx-pk.ru/threads/36139-cpd-test-dlya-proverki-izmeneniya-registra-memptr-instruktsiyami-proverte-na-reale-plz.html + +30. + + .. _r_30: + + Young, Sean (2005-09-18). *"Undocumented Z80 Documented, The"* v0.91. + + * http://www.myquest.nl/z80undocumented + * http://www.myquest.nl/z80undocumented/z80-documented-v0.91.pdf + +31. + + .. _r_31: + + https://worldofspectrum.org/forums/discussion/41704 + + * http://zxds.raxoft.cz/taps/misc/zexall2.zip + +32. + + .. _r_32: + + https://worldofspectrum.org/forums/discussion/41834 + + * http://zxds.raxoft.cz/taps/misc/z80test-1.0.zip + * https://github.com/raxoft/z80test + + 1. + + .. _r_32_1: + + https://worldofspectrum.org/forums/discussion/comment/668760/#Comment_668760 + +33. + + .. _r_33: + + https://worldofspectrum.org/forums/discussion/34574 + + 1. + + .. _r_33_1: + + https://worldofspectrum.org/forums/discussion/comment/539714/#Comment_539714 + + * http://zxprojects.com/images/stories/z80_startup/reg_start_value.zip + +34. + + .. _r_34: + + https://jisanchez.com/test-a-dos-placas-de-zx-spectrum + +35. + + .. _r_35: + + Weissflog, Andre (2021-12-17). *"New Cycle-Stepped Z80 Emulator, A"*. + + * https://floooh.github.io/2021/12/17/cycle-stepped-z80.html + +36. + + .. _r_36: + + https://github.com/floooh/v6502r + +37. + + .. _r_37: + + https://groups.google.com/g/comp.sys.sinclair/c/WPsPr6j6w5k/m/O_u1zNQf3VYJ + +38. + + .. _r_38: + + Young, Sean (1997-09-21). *"Zilog Z80 CPU Specifications"*. + + * http://www.msxnet.org/tech/Z80/z80.zip diff --git a/projects/Z80/documentation/Usage.rst b/projects/Z80/documentation/usage.rst similarity index 98% rename from projects/Z80/documentation/Usage.rst rename to projects/Z80/documentation/usage.rst index a69bc5a..19d2464 100644 --- a/projects/Z80/documentation/Usage.rst +++ b/projects/Z80/documentation/usage.rst @@ -96,7 +96,7 @@ Usage } - void machine_power(Machine *self, zboolean state) + void machine_power(Machine *self, zbool state) { if (state) { diff --git a/projects/Z80/documentation/version-history.rst b/projects/Z80/documentation/version-history.rst new file mode 100644 index 0000000..07909ba --- /dev/null +++ b/projects/Z80/documentation/version-history.rst @@ -0,0 +1,81 @@ +=============== +Version history +=============== + +Z80 v0.2-pre +============ + +*Released on 2025-07-02* + +This is an important update that addresses a number of issues and also includes new features. Please note that the changes introduced in this release break the binary compatibility with the previous version. + +**Changes:** + +1. Changed the :doc:`license ` from GPL to LGPL (by popular request). +2. Moved the public header from ```` to ````. +3. Removed the Xcode project. +4. Switched the build system from Premake to `CMake `_. +5. Switched to `Zeta `_ v0.1. +6. Added `pkg-config `_ support. +7. Added the following files to the project: :file:`.vimrc`, :file:`CITATION.cff` and :file:`THANKS`. +8. Added detailed documentation. +9. Added Pascal binding, courtesy of Zoran Vučenović. +10. Added :file:`test-Z80`, a tool that runs various Z80-specific tests for CP/M and ZX Spectrum. +11. Added :file:`step-test-Z80`, a tool for unit tests in JSON format. +12. Renamed the macros ``CPU_Z80_DEPENDENCIES_H`` and ``CPU_Z80_STATIC`` to :c:macro:`Z80_EXTERNAL_HEADER` and :c:macro:`Z80_STATIC`, respectively. +13. Added :ref:`public macros ` for checking the library version, working with flags, accessing the 16-bit registers and other purposes. +14. Added the ability to end the emulation loop immediately, and the :c:func:`z80_break` function. +15. Added the :c:func:`z80_execute` function for running a simplified emulation without RESET and interrupts. +16. Added the :c:func:`z80_in_cycle` and :c:func:`z80_out_cycle` functions for obtaining the clock cycle at which the I/O M-cycle begins, relative to the start of the instruction. +17. Added the :c:func:`z80_r` function for getting the current value of the R register. +18. Added the :c:func:`z80_refresh_address` function for getting the refresh address of the current M1 cycle. +19. Added the :c:func:`z80_wait` function for inserting wait states. +20. Renamed the ``z80_reset`` function to :c:func:`z80_instant_reset`. +21. Added optional emulation of the special RESET, and the :c:func:`z80_special_reset` function. +22. Added the :c:data:`Z80::fetch_opcode` and :c:data:`Z80::fetch` callbacks for performing, respectively, opcode fetch operations and memory read operations on instruction data. +23. Added the :c:data:`Z80::nop` callback for performing disregarded opcode fetch operations during internal NOP M-cycles. +24. Added emulation of the NMI acknowledge M-cycle through the new :c:data:`Z80::nmia` callback. +25. Added emulation of the INT acknowledge M-cycle through the new :c:data:`Z80::inta` callback, which replaces ``Z80::int_data``. +26. Added optional full emulation of the interrupt mode 0, along with the new :c:data:`Z80::int_fetch` callback for performing bus read operations on instruction data. If not enabled at compile-time, the old simplified emulation is built, which supports only the most typical instructions. +27. Added four callbacks for notifying the execution of important instructions: :c:data:`Z80::ld_i_a`, :c:data:`Z80::ld_r_a`, :c:data:`Z80::reti` and :c:data:`Z80::retn`. +28. Added hooking functionality through the ``ld h,h`` instruction and the new :c:data:`Z80::hook` callback. +29. Added the :c:data:`Z80::illegal` callback for delegating the emulation of illegal instructions. +30. Added :ref:`emulation options ` that can be configured at runtime. +31. Removed ``Z80::state``. Replaced with individual members for the registers, the interrupt enable flip-flops and the interrupt mode. +32. Removed the superfluous EI flag. The previous opcode is checked instead, which is faster and makes the :c:type:`Z80` object smaller. +33. Removed all module-related stuff. +34. Added emulation of the additional flag changes performed during the extra 5 clock cycles of the following instructions: ``ldir``, ``lddr``, ``cpir``, ``cpdr``, ``inir``, ``indr``, ``otir`` and ``otdr``. +35. Added emulation of the interrupt acceptance deferral that occurs during the ``reti`` and ``retn`` instructions. +36. Added MEMPTR emulation. The ``bit N,(hl)`` instruction now produces a correct value of F. +37. Added optional emulation of Q. If enabled at compile-time, the ``ccf`` and ``scf`` instructions will produce a correct value of F. +38. Added emulation of the ``out (c),255`` instruction (Zilog Z80 CMOS). +39. Added optional emulation of the bug affecting the ``ld a,{i|r}`` instructions (Zilog Z80 NMOS). If enabled at compile-time and configured at runtime, the P/V flag will be reset if an INT is accepted during the execution of these instructions. +40. Added an optional implementation of the parity calculation for the P/V flag that performs the actual computation instead of using a table of precomputed values. +41. Added an optional implementation of the ``daa`` instruction that uses a table of precomputed values. +42. Increased granularity. The emulator can now stop directly after fetching a prefix ``DDh`` or ``FDh`` if it runs out of clock cycles. This also works during the INT response in mode 0. +43. Reimplemented the HALT state. The emulation should now be fully accurate. HALTskip optimization is also supported. +44. Fixed a bug in the ``sll`` instruction. +45. Fixed a bug in the ``INX`` and ``OUTX`` macros affecting the S and N flags. +46. Fixed a bug in the ``OUTX`` macro affecting the MSByte of the port number. +47. Fixed the clock cycles of the ``dec XY`` and ``in (c)`` instructions. +48. Fixed the ``read_16`` function so that the order of the memory read operations is not determined by the order in which the compiler evaluates expressions. +49. Fixed the order in which the memory write operations are performed when the SP register is involved. This affects the NMI response, the INT response in modes 1 and 2, and the following instructions: ``ex (sp),{hl|XY}``, ``push TT``, ``push XY``, ``call WORD``, ``call Z,WORD`` and ``rst N``. +50. Fixed the handling of illegal instructions to avoid stack overflows in long sequences of ``DDh/FDh`` prefixes. +51. Fixed several implicit conversions to avoid warnings about loss of sign and precision. +52. Fixed some bitwise operations to avoid undefined behavior and arithmetic right shifts on signed integers. +53. Fixed violations of the C standard in several identifiers. +54. Renamed the 8-bit register lists: ``X/Y`` to ``J/K``; ``J/K`` and ``P/Q`` to ``O/P``. +55. Replaced all P/V overflow computation functions with a single, faster macro. +56. Replaced all register resolution functions with macros. +57. Replaced all ``ld {J,K|O,P}`` instructions that have the same destination and source register with NOPs. In addition, the "illegal" forms of the following instructions are now executed without using the illegal instruction handler: ``ld O,P``, ``ld O,BYTE``, ``U [a,]P`` and ``V O``. +58. Optimizations in flag computation and condition evaluation. +59. New source code comments and improvements to existing ones. +60. Improved code aesthetics. +61. Other improvements, optimizations and minor changes. + +Z80 v0.1 +======== + +*Released on 2018-11-10* + +Initial public release. diff --git a/projects/Z80/sources/Z80.c b/projects/Z80/sources/Z80.c index 8db84f1..3d9d847 100644 --- a/projects/Z80/sources/Z80.c +++ b/projects/Z80/sources/Z80.c @@ -4,7 +4,7 @@ ____ \/__/ /\_\ __ \\ \/\ \ ________________________________________________ | /\_____\\_____\\_____\ | | Zilog \/_____//_____//_____/ CPU Emulator | -| Copyright (C) 1999-2024 Manuel Sainz de Baranda y Goñi. | +| Copyright (C) 1999-2026 Manuel Sainz de Baranda y Goñi. | | | | This emulator is free software: you can redistribute it and/or modify it | | under the terms of the GNU Lesser General Public License as published by | @@ -54,7 +54,7 @@ | | '=============================================================================*/ -#ifndef Z80_DEPENDENCIES_HEADER +#ifndef Z80_EXTERNAL_HEADER # include # include # include @@ -73,6 +73,169 @@ #endif +/* MARK: - Precomputed Values of AF for `daa` */ +/*---------------------------------------------------------------------------. +| Enabling `Z80_WITH_PRECOMPUTED_DAA` makes the `daa` instruction faster by | +| using a lookup table. However, this instruction is rarely used in typical | +| programs, so the overall speedup is minimal, and incresing the size of the | +| emulator by 2 KiB may negatively impact cache efficiency. It is therefore | +| recommended to leave this option disabled unless serious profiling on the | +| target platform shows a significant benefit. | +'===========================================================================*/ + +#ifdef Z80_WITH_PRECOMPUTED_DAA +# define H(value) Z_UINT16(0x##value) + + static zuint16 const daa_af_table[2048] = { + /* HNC */ + /* 000 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /* 0 */ H(0044), H(0100), H(0200), H(0304), H(0400), H(0504), H(0604), H(0700), H(0808), H(090C), H(1010), H(1114), H(1214), H(1310), H(1414), H(1510), + /* 1 */ H(1000), H(1104), H(1204), H(1300), H(1404), H(1500), H(1600), H(1704), H(180C), H(1908), H(2030), H(2134), H(2234), H(2330), H(2434), H(2530), + /* 2 */ H(2020), H(2124), H(2224), H(2320), H(2424), H(2520), H(2620), H(2724), H(282C), H(2928), H(3034), H(3130), H(3230), H(3334), H(3430), H(3534), + /* 3 */ H(3024), H(3120), H(3220), H(3324), H(3420), H(3524), H(3624), H(3720), H(3828), H(392C), H(4010), H(4114), H(4214), H(4310), H(4414), H(4510), + /* 4 */ H(4000), H(4104), H(4204), H(4300), H(4404), H(4500), H(4600), H(4704), H(480C), H(4908), H(5014), H(5110), H(5210), H(5314), H(5410), H(5514), + /* 5 */ H(5004), H(5100), H(5200), H(5304), H(5400), H(5504), H(5604), H(5700), H(5808), H(590C), H(6034), H(6130), H(6230), H(6334), H(6430), H(6534), + /* 6 */ H(6024), H(6120), H(6220), H(6324), H(6420), H(6524), H(6624), H(6720), H(6828), H(692C), H(7030), H(7134), H(7234), H(7330), H(7434), H(7530), + /* 7 */ H(7020), H(7124), H(7224), H(7320), H(7424), H(7520), H(7620), H(7724), H(782C), H(7928), H(8090), H(8194), H(8294), H(8390), H(8494), H(8590), + /* 8 */ H(8080), H(8184), H(8284), H(8380), H(8484), H(8580), H(8680), H(8784), H(888C), H(8988), H(9094), H(9190), H(9290), H(9394), H(9490), H(9594), + /* 9 */ H(9084), H(9180), H(9280), H(9384), H(9480), H(9584), H(9684), H(9780), H(9888), H(998C), H(0055), H(0111), H(0211), H(0315), H(0411), H(0515), + /* A */ H(0045), H(0101), H(0201), H(0305), H(0401), H(0505), H(0605), H(0701), H(0809), H(090D), H(1011), H(1115), H(1215), H(1311), H(1415), H(1511), + /* B */ H(1001), H(1105), H(1205), H(1301), H(1405), H(1501), H(1601), H(1705), H(180D), H(1909), H(2031), H(2135), H(2235), H(2331), H(2435), H(2531), + /* C */ H(2021), H(2125), H(2225), H(2321), H(2425), H(2521), H(2621), H(2725), H(282D), H(2929), H(3035), H(3131), H(3231), H(3335), H(3431), H(3535), + /* D */ H(3025), H(3121), H(3221), H(3325), H(3421), H(3525), H(3625), H(3721), H(3829), H(392D), H(4011), H(4115), H(4215), H(4311), H(4415), H(4511), + /* E */ H(4001), H(4105), H(4205), H(4301), H(4405), H(4501), H(4601), H(4705), H(480D), H(4909), H(5015), H(5111), H(5211), H(5315), H(5411), H(5515), + /* F */ H(5005), H(5101), H(5201), H(5305), H(5401), H(5505), H(5605), H(5701), H(5809), H(590D), H(6035), H(6131), H(6231), H(6335), H(6431), H(6535), + /* HNC */ + /* 001 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /* 0 */ H(6025), H(6121), H(6221), H(6325), H(6421), H(6525), H(6625), H(6721), H(6829), H(692D), H(7031), H(7135), H(7235), H(7331), H(7435), H(7531), + /* 1 */ H(7021), H(7125), H(7225), H(7321), H(7425), H(7521), H(7621), H(7725), H(782D), H(7929), H(8091), H(8195), H(8295), H(8391), H(8495), H(8591), + /* 2 */ H(8081), H(8185), H(8285), H(8381), H(8485), H(8581), H(8681), H(8785), H(888D), H(8989), H(9095), H(9191), H(9291), H(9395), H(9491), H(9595), + /* 3 */ H(9085), H(9181), H(9281), H(9385), H(9481), H(9585), H(9685), H(9781), H(9889), H(998D), H(A0B5), H(A1B1), H(A2B1), H(A3B5), H(A4B1), H(A5B5), + /* 4 */ H(A0A5), H(A1A1), H(A2A1), H(A3A5), H(A4A1), H(A5A5), H(A6A5), H(A7A1), H(A8A9), H(A9AD), H(B0B1), H(B1B5), H(B2B5), H(B3B1), H(B4B5), H(B5B1), + /* 5 */ H(B0A1), H(B1A5), H(B2A5), H(B3A1), H(B4A5), H(B5A1), H(B6A1), H(B7A5), H(B8AD), H(B9A9), H(C095), H(C191), H(C291), H(C395), H(C491), H(C595), + /* 6 */ H(C085), H(C181), H(C281), H(C385), H(C481), H(C585), H(C685), H(C781), H(C889), H(C98D), H(D091), H(D195), H(D295), H(D391), H(D495), H(D591), + /* 7 */ H(D081), H(D185), H(D285), H(D381), H(D485), H(D581), H(D681), H(D785), H(D88D), H(D989), H(E0B1), H(E1B5), H(E2B5), H(E3B1), H(E4B5), H(E5B1), + /* 8 */ H(E0A1), H(E1A5), H(E2A5), H(E3A1), H(E4A5), H(E5A1), H(E6A1), H(E7A5), H(E8AD), H(E9A9), H(F0B5), H(F1B1), H(F2B1), H(F3B5), H(F4B1), H(F5B5), + /* 9 */ H(F0A5), H(F1A1), H(F2A1), H(F3A5), H(F4A1), H(F5A5), H(F6A5), H(F7A1), H(F8A9), H(F9AD), H(0055), H(0111), H(0211), H(0315), H(0411), H(0515), + /* A */ H(0045), H(0101), H(0201), H(0305), H(0401), H(0505), H(0605), H(0701), H(0809), H(090D), H(1011), H(1115), H(1215), H(1311), H(1415), H(1511), + /* B */ H(1001), H(1105), H(1205), H(1301), H(1405), H(1501), H(1601), H(1705), H(180D), H(1909), H(2031), H(2135), H(2235), H(2331), H(2435), H(2531), + /* C */ H(2021), H(2125), H(2225), H(2321), H(2425), H(2521), H(2621), H(2725), H(282D), H(2929), H(3035), H(3131), H(3231), H(3335), H(3431), H(3535), + /* D */ H(3025), H(3121), H(3221), H(3325), H(3421), H(3525), H(3625), H(3721), H(3829), H(392D), H(4011), H(4115), H(4215), H(4311), H(4415), H(4511), + /* E */ H(4001), H(4105), H(4205), H(4301), H(4405), H(4501), H(4601), H(4705), H(480D), H(4909), H(5015), H(5111), H(5211), H(5315), H(5411), H(5515), + /* F */ H(5005), H(5101), H(5201), H(5305), H(5401), H(5505), H(5605), H(5701), H(5809), H(590D), H(6035), H(6131), H(6231), H(6335), H(6431), H(6535), + /* HNC */ + /* 010 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /* 0 */ H(0046), H(0102), H(0202), H(0306), H(0402), H(0506), H(0606), H(0702), H(080A), H(090E), H(0402), H(0506), H(0606), H(0702), H(080A), H(090E), + /* 1 */ H(1002), H(1106), H(1206), H(1302), H(1406), H(1502), H(1602), H(1706), H(180E), H(190A), H(1406), H(1502), H(1602), H(1706), H(180E), H(190A), + /* 2 */ H(2022), H(2126), H(2226), H(2322), H(2426), H(2522), H(2622), H(2726), H(282E), H(292A), H(2426), H(2522), H(2622), H(2726), H(282E), H(292A), + /* 3 */ H(3026), H(3122), H(3222), H(3326), H(3422), H(3526), H(3626), H(3722), H(382A), H(392E), H(3422), H(3526), H(3626), H(3722), H(382A), H(392E), + /* 4 */ H(4002), H(4106), H(4206), H(4302), H(4406), H(4502), H(4602), H(4706), H(480E), H(490A), H(4406), H(4502), H(4602), H(4706), H(480E), H(490A), + /* 5 */ H(5006), H(5102), H(5202), H(5306), H(5402), H(5506), H(5606), H(5702), H(580A), H(590E), H(5402), H(5506), H(5606), H(5702), H(580A), H(590E), + /* 6 */ H(6026), H(6122), H(6222), H(6326), H(6422), H(6526), H(6626), H(6722), H(682A), H(692E), H(6422), H(6526), H(6626), H(6722), H(682A), H(692E), + /* 7 */ H(7022), H(7126), H(7226), H(7322), H(7426), H(7522), H(7622), H(7726), H(782E), H(792A), H(7426), H(7522), H(7622), H(7726), H(782E), H(792A), + /* 8 */ H(8082), H(8186), H(8286), H(8382), H(8486), H(8582), H(8682), H(8786), H(888E), H(898A), H(8486), H(8582), H(8682), H(8786), H(888E), H(898A), + /* 9 */ H(9086), H(9182), H(9282), H(9386), H(9482), H(9586), H(9686), H(9782), H(988A), H(998E), H(3423), H(3527), H(3627), H(3723), H(382B), H(392F), + /* A */ H(4003), H(4107), H(4207), H(4303), H(4407), H(4503), H(4603), H(4707), H(480F), H(490B), H(4407), H(4503), H(4603), H(4707), H(480F), H(490B), + /* B */ H(5007), H(5103), H(5203), H(5307), H(5403), H(5507), H(5607), H(5703), H(580B), H(590F), H(5403), H(5507), H(5607), H(5703), H(580B), H(590F), + /* C */ H(6027), H(6123), H(6223), H(6327), H(6423), H(6527), H(6627), H(6723), H(682B), H(692F), H(6423), H(6527), H(6627), H(6723), H(682B), H(692F), + /* D */ H(7023), H(7127), H(7227), H(7323), H(7427), H(7523), H(7623), H(7727), H(782F), H(792B), H(7427), H(7523), H(7623), H(7727), H(782F), H(792B), + /* E */ H(8083), H(8187), H(8287), H(8383), H(8487), H(8583), H(8683), H(8787), H(888F), H(898B), H(8487), H(8583), H(8683), H(8787), H(888F), H(898B), + /* F */ H(9087), H(9183), H(9283), H(9387), H(9483), H(9587), H(9687), H(9783), H(988B), H(998F), H(9483), H(9587), H(9687), H(9783), H(988B), H(998F), + /* HNC */ + /* 011 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /* 0 */ H(A0A7), H(A1A3), H(A2A3), H(A3A7), H(A4A3), H(A5A7), H(A6A7), H(A7A3), H(A8AB), H(A9AF), H(A4A3), H(A5A7), H(A6A7), H(A7A3), H(A8AB), H(A9AF), + /* 1 */ H(B0A3), H(B1A7), H(B2A7), H(B3A3), H(B4A7), H(B5A3), H(B6A3), H(B7A7), H(B8AF), H(B9AB), H(B4A7), H(B5A3), H(B6A3), H(B7A7), H(B8AF), H(B9AB), + /* 2 */ H(C087), H(C183), H(C283), H(C387), H(C483), H(C587), H(C687), H(C783), H(C88B), H(C98F), H(C483), H(C587), H(C687), H(C783), H(C88B), H(C98F), + /* 3 */ H(D083), H(D187), H(D287), H(D383), H(D487), H(D583), H(D683), H(D787), H(D88F), H(D98B), H(D487), H(D583), H(D683), H(D787), H(D88F), H(D98B), + /* 4 */ H(E0A3), H(E1A7), H(E2A7), H(E3A3), H(E4A7), H(E5A3), H(E6A3), H(E7A7), H(E8AF), H(E9AB), H(E4A7), H(E5A3), H(E6A3), H(E7A7), H(E8AF), H(E9AB), + /* 5 */ H(F0A7), H(F1A3), H(F2A3), H(F3A7), H(F4A3), H(F5A7), H(F6A7), H(F7A3), H(F8AB), H(F9AF), H(F4A3), H(F5A7), H(F6A7), H(F7A3), H(F8AB), H(F9AF), + /* 6 */ H(0047), H(0103), H(0203), H(0307), H(0403), H(0507), H(0607), H(0703), H(080B), H(090F), H(0403), H(0507), H(0607), H(0703), H(080B), H(090F), + /* 7 */ H(1003), H(1107), H(1207), H(1303), H(1407), H(1503), H(1603), H(1707), H(180F), H(190B), H(1407), H(1503), H(1603), H(1707), H(180F), H(190B), + /* 8 */ H(2023), H(2127), H(2227), H(2323), H(2427), H(2523), H(2623), H(2727), H(282F), H(292B), H(2427), H(2523), H(2623), H(2727), H(282F), H(292B), + /* 9 */ H(3027), H(3123), H(3223), H(3327), H(3423), H(3527), H(3627), H(3723), H(382B), H(392F), H(3423), H(3527), H(3627), H(3723), H(382B), H(392F), + /* A */ H(4003), H(4107), H(4207), H(4303), H(4407), H(4503), H(4603), H(4707), H(480F), H(490B), H(4407), H(4503), H(4603), H(4707), H(480F), H(490B), + /* B */ H(5007), H(5103), H(5203), H(5307), H(5403), H(5507), H(5607), H(5703), H(580B), H(590F), H(5403), H(5507), H(5607), H(5703), H(580B), H(590F), + /* C */ H(6027), H(6123), H(6223), H(6327), H(6423), H(6527), H(6627), H(6723), H(682B), H(692F), H(6423), H(6527), H(6627), H(6723), H(682B), H(692F), + /* D */ H(7023), H(7127), H(7227), H(7323), H(7427), H(7523), H(7623), H(7727), H(782F), H(792B), H(7427), H(7523), H(7623), H(7727), H(782F), H(792B), + /* E */ H(8083), H(8187), H(8287), H(8383), H(8487), H(8583), H(8683), H(8787), H(888F), H(898B), H(8487), H(8583), H(8683), H(8787), H(888F), H(898B), + /* F */ H(9087), H(9183), H(9283), H(9387), H(9483), H(9587), H(9687), H(9783), H(988B), H(998F), H(9483), H(9587), H(9687), H(9783), H(988B), H(998F), + /* HNC */ + /* 100 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /* 0 */ H(0604), H(0700), H(0808), H(090C), H(0A0C), H(0B08), H(0C0C), H(0D08), H(0E08), H(0F0C), H(1010), H(1114), H(1214), H(1310), H(1414), H(1510), + /* 1 */ H(1600), H(1704), H(180C), H(1908), H(1A08), H(1B0C), H(1C08), H(1D0C), H(1E0C), H(1F08), H(2030), H(2134), H(2234), H(2330), H(2434), H(2530), + /* 2 */ H(2620), H(2724), H(282C), H(2928), H(2A28), H(2B2C), H(2C28), H(2D2C), H(2E2C), H(2F28), H(3034), H(3130), H(3230), H(3334), H(3430), H(3534), + /* 3 */ H(3624), H(3720), H(3828), H(392C), H(3A2C), H(3B28), H(3C2C), H(3D28), H(3E28), H(3F2C), H(4010), H(4114), H(4214), H(4310), H(4414), H(4510), + /* 4 */ H(4600), H(4704), H(480C), H(4908), H(4A08), H(4B0C), H(4C08), H(4D0C), H(4E0C), H(4F08), H(5014), H(5110), H(5210), H(5314), H(5410), H(5514), + /* 5 */ H(5604), H(5700), H(5808), H(590C), H(5A0C), H(5B08), H(5C0C), H(5D08), H(5E08), H(5F0C), H(6034), H(6130), H(6230), H(6334), H(6430), H(6534), + /* 6 */ H(6624), H(6720), H(6828), H(692C), H(6A2C), H(6B28), H(6C2C), H(6D28), H(6E28), H(6F2C), H(7030), H(7134), H(7234), H(7330), H(7434), H(7530), + /* 7 */ H(7620), H(7724), H(782C), H(7928), H(7A28), H(7B2C), H(7C28), H(7D2C), H(7E2C), H(7F28), H(8090), H(8194), H(8294), H(8390), H(8494), H(8590), + /* 8 */ H(8680), H(8784), H(888C), H(8988), H(8A88), H(8B8C), H(8C88), H(8D8C), H(8E8C), H(8F88), H(9094), H(9190), H(9290), H(9394), H(9490), H(9594), + /* 9 */ H(9684), H(9780), H(9888), H(998C), H(9A8C), H(9B88), H(9C8C), H(9D88), H(9E88), H(9F8C), H(0055), H(0111), H(0211), H(0315), H(0411), H(0515), + /* A */ H(0605), H(0701), H(0809), H(090D), H(0A0D), H(0B09), H(0C0D), H(0D09), H(0E09), H(0F0D), H(1011), H(1115), H(1215), H(1311), H(1415), H(1511), + /* B */ H(1601), H(1705), H(180D), H(1909), H(1A09), H(1B0D), H(1C09), H(1D0D), H(1E0D), H(1F09), H(2031), H(2135), H(2235), H(2331), H(2435), H(2531), + /* C */ H(2621), H(2725), H(282D), H(2929), H(2A29), H(2B2D), H(2C29), H(2D2D), H(2E2D), H(2F29), H(3035), H(3131), H(3231), H(3335), H(3431), H(3535), + /* D */ H(3625), H(3721), H(3829), H(392D), H(3A2D), H(3B29), H(3C2D), H(3D29), H(3E29), H(3F2D), H(4011), H(4115), H(4215), H(4311), H(4415), H(4511), + /* E */ H(4601), H(4705), H(480D), H(4909), H(4A09), H(4B0D), H(4C09), H(4D0D), H(4E0D), H(4F09), H(5015), H(5111), H(5211), H(5315), H(5411), H(5515), + /* F */ H(5605), H(5701), H(5809), H(590D), H(5A0D), H(5B09), H(5C0D), H(5D09), H(5E09), H(5F0D), H(6035), H(6131), H(6231), H(6335), H(6431), H(6535), + /* HNC */ + /* 101 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /* 0 */ H(6625), H(6721), H(6829), H(692D), H(6A2D), H(6B29), H(6C2D), H(6D29), H(6E29), H(6F2D), H(7031), H(7135), H(7235), H(7331), H(7435), H(7531), + /* 1 */ H(7621), H(7725), H(782D), H(7929), H(7A29), H(7B2D), H(7C29), H(7D2D), H(7E2D), H(7F29), H(8091), H(8195), H(8295), H(8391), H(8495), H(8591), + /* 2 */ H(8681), H(8785), H(888D), H(8989), H(8A89), H(8B8D), H(8C89), H(8D8D), H(8E8D), H(8F89), H(9095), H(9191), H(9291), H(9395), H(9491), H(9595), + /* 3 */ H(9685), H(9781), H(9889), H(998D), H(9A8D), H(9B89), H(9C8D), H(9D89), H(9E89), H(9F8D), H(A0B5), H(A1B1), H(A2B1), H(A3B5), H(A4B1), H(A5B5), + /* 4 */ H(A6A5), H(A7A1), H(A8A9), H(A9AD), H(AAAD), H(ABA9), H(ACAD), H(ADA9), H(AEA9), H(AFAD), H(B0B1), H(B1B5), H(B2B5), H(B3B1), H(B4B5), H(B5B1), + /* 5 */ H(B6A1), H(B7A5), H(B8AD), H(B9A9), H(BAA9), H(BBAD), H(BCA9), H(BDAD), H(BEAD), H(BFA9), H(C095), H(C191), H(C291), H(C395), H(C491), H(C595), + /* 6 */ H(C685), H(C781), H(C889), H(C98D), H(CA8D), H(CB89), H(CC8D), H(CD89), H(CE89), H(CF8D), H(D091), H(D195), H(D295), H(D391), H(D495), H(D591), + /* 7 */ H(D681), H(D785), H(D88D), H(D989), H(DA89), H(DB8D), H(DC89), H(DD8D), H(DE8D), H(DF89), H(E0B1), H(E1B5), H(E2B5), H(E3B1), H(E4B5), H(E5B1), + /* 8 */ H(E6A1), H(E7A5), H(E8AD), H(E9A9), H(EAA9), H(EBAD), H(ECA9), H(EDAD), H(EEAD), H(EFA9), H(F0B5), H(F1B1), H(F2B1), H(F3B5), H(F4B1), H(F5B5), + /* 9 */ H(F6A5), H(F7A1), H(F8A9), H(F9AD), H(FAAD), H(FBA9), H(FCAD), H(FDA9), H(FEA9), H(FFAD), H(0055), H(0111), H(0211), H(0315), H(0411), H(0515), + /* A */ H(0605), H(0701), H(0809), H(090D), H(0A0D), H(0B09), H(0C0D), H(0D09), H(0E09), H(0F0D), H(1011), H(1115), H(1215), H(1311), H(1415), H(1511), + /* B */ H(1601), H(1705), H(180D), H(1909), H(1A09), H(1B0D), H(1C09), H(1D0D), H(1E0D), H(1F09), H(2031), H(2135), H(2235), H(2331), H(2435), H(2531), + /* C */ H(2621), H(2725), H(282D), H(2929), H(2A29), H(2B2D), H(2C29), H(2D2D), H(2E2D), H(2F29), H(3035), H(3131), H(3231), H(3335), H(3431), H(3535), + /* D */ H(3625), H(3721), H(3829), H(392D), H(3A2D), H(3B29), H(3C2D), H(3D29), H(3E29), H(3F2D), H(4011), H(4115), H(4215), H(4311), H(4415), H(4511), + /* E */ H(4601), H(4705), H(480D), H(4909), H(4A09), H(4B0D), H(4C09), H(4D0D), H(4E0D), H(4F09), H(5015), H(5111), H(5211), H(5315), H(5411), H(5515), + /* F */ H(5605), H(5701), H(5809), H(590D), H(5A0D), H(5B09), H(5C0D), H(5D09), H(5E09), H(5F0D), H(6035), H(6131), H(6231), H(6335), H(6431), H(6535), + /* HNC */ + /* 110 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /* 0 */ H(FABE), H(FBBA), H(FCBE), H(FDBA), H(FEBA), H(FFBE), H(0046), H(0102), H(0202), H(0306), H(0402), H(0506), H(0606), H(0702), H(080A), H(090E), + /* 1 */ H(0A1E), H(0B1A), H(0C1E), H(0D1A), H(0E1A), H(0F1E), H(1002), H(1106), H(1206), H(1302), H(1406), H(1502), H(1602), H(1706), H(180E), H(190A), + /* 2 */ H(1A1A), H(1B1E), H(1C1A), H(1D1E), H(1E1E), H(1F1A), H(2022), H(2126), H(2226), H(2322), H(2426), H(2522), H(2622), H(2726), H(282E), H(292A), + /* 3 */ H(2A3A), H(2B3E), H(2C3A), H(2D3E), H(2E3E), H(2F3A), H(3026), H(3122), H(3222), H(3326), H(3422), H(3526), H(3626), H(3722), H(382A), H(392E), + /* 4 */ H(3A3E), H(3B3A), H(3C3E), H(3D3A), H(3E3A), H(3F3E), H(4002), H(4106), H(4206), H(4302), H(4406), H(4502), H(4602), H(4706), H(480E), H(490A), + /* 5 */ H(4A1A), H(4B1E), H(4C1A), H(4D1E), H(4E1E), H(4F1A), H(5006), H(5102), H(5202), H(5306), H(5402), H(5506), H(5606), H(5702), H(580A), H(590E), + /* 6 */ H(5A1E), H(5B1A), H(5C1E), H(5D1A), H(5E1A), H(5F1E), H(6026), H(6122), H(6222), H(6326), H(6422), H(6526), H(6626), H(6722), H(682A), H(692E), + /* 7 */ H(6A3E), H(6B3A), H(6C3E), H(6D3A), H(6E3A), H(6F3E), H(7022), H(7126), H(7226), H(7322), H(7426), H(7522), H(7622), H(7726), H(782E), H(792A), + /* 8 */ H(7A3A), H(7B3E), H(7C3A), H(7D3E), H(7E3E), H(7F3A), H(8082), H(8186), H(8286), H(8382), H(8486), H(8582), H(8682), H(8786), H(888E), H(898A), + /* 9 */ H(8A9A), H(8B9E), H(8C9A), H(8D9E), H(8E9E), H(8F9A), H(9086), H(9182), H(9282), H(9386), H(3423), H(3527), H(3627), H(3723), H(382B), H(392F), + /* A */ H(3A3F), H(3B3B), H(3C3F), H(3D3B), H(3E3B), H(3F3F), H(4003), H(4107), H(4207), H(4303), H(4407), H(4503), H(4603), H(4707), H(480F), H(490B), + /* B */ H(4A1B), H(4B1F), H(4C1B), H(4D1F), H(4E1F), H(4F1B), H(5007), H(5103), H(5203), H(5307), H(5403), H(5507), H(5607), H(5703), H(580B), H(590F), + /* C */ H(5A1F), H(5B1B), H(5C1F), H(5D1B), H(5E1B), H(5F1F), H(6027), H(6123), H(6223), H(6327), H(6423), H(6527), H(6627), H(6723), H(682B), H(692F), + /* D */ H(6A3F), H(6B3B), H(6C3F), H(6D3B), H(6E3B), H(6F3F), H(7023), H(7127), H(7227), H(7323), H(7427), H(7523), H(7623), H(7727), H(782F), H(792B), + /* E */ H(7A3B), H(7B3F), H(7C3B), H(7D3F), H(7E3F), H(7F3B), H(8083), H(8187), H(8287), H(8383), H(8487), H(8583), H(8683), H(8787), H(888F), H(898B), + /* F */ H(8A9B), H(8B9F), H(8C9B), H(8D9F), H(8E9F), H(8F9B), H(9087), H(9183), H(9283), H(9387), H(9483), H(9587), H(9687), H(9783), H(988B), H(998F), + /* HNC */ + /* 111 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /* 0 */ H(9A9F), H(9B9B), H(9C9F), H(9D9B), H(9E9B), H(9F9F), H(A0A7), H(A1A3), H(A2A3), H(A3A7), H(A4A3), H(A5A7), H(A6A7), H(A7A3), H(A8AB), H(A9AF), + /* 1 */ H(AABF), H(ABBB), H(ACBF), H(ADBB), H(AEBB), H(AFBF), H(B0A3), H(B1A7), H(B2A7), H(B3A3), H(B4A7), H(B5A3), H(B6A3), H(B7A7), H(B8AF), H(B9AB), + /* 2 */ H(BABB), H(BBBF), H(BCBB), H(BDBF), H(BEBF), H(BFBB), H(C087), H(C183), H(C283), H(C387), H(C483), H(C587), H(C687), H(C783), H(C88B), H(C98F), + /* 3 */ H(CA9F), H(CB9B), H(CC9F), H(CD9B), H(CE9B), H(CF9F), H(D083), H(D187), H(D287), H(D383), H(D487), H(D583), H(D683), H(D787), H(D88F), H(D98B), + /* 4 */ H(DA9B), H(DB9F), H(DC9B), H(DD9F), H(DE9F), H(DF9B), H(E0A3), H(E1A7), H(E2A7), H(E3A3), H(E4A7), H(E5A3), H(E6A3), H(E7A7), H(E8AF), H(E9AB), + /* 5 */ H(EABB), H(EBBF), H(ECBB), H(EDBF), H(EEBF), H(EFBB), H(F0A7), H(F1A3), H(F2A3), H(F3A7), H(F4A3), H(F5A7), H(F6A7), H(F7A3), H(F8AB), H(F9AF), + /* 6 */ H(FABF), H(FBBB), H(FCBF), H(FDBB), H(FEBB), H(FFBF), H(0047), H(0103), H(0203), H(0307), H(0403), H(0507), H(0607), H(0703), H(080B), H(090F), + /* 7 */ H(0A1F), H(0B1B), H(0C1F), H(0D1B), H(0E1B), H(0F1F), H(1003), H(1107), H(1207), H(1303), H(1407), H(1503), H(1603), H(1707), H(180F), H(190B), + /* 8 */ H(1A1B), H(1B1F), H(1C1B), H(1D1F), H(1E1F), H(1F1B), H(2023), H(2127), H(2227), H(2323), H(2427), H(2523), H(2623), H(2727), H(282F), H(292B), + /* 9 */ H(2A3B), H(2B3F), H(2C3B), H(2D3F), H(2E3F), H(2F3B), H(3027), H(3123), H(3223), H(3327), H(3423), H(3527), H(3627), H(3723), H(382B), H(392F), + /* A */ H(3A3F), H(3B3B), H(3C3F), H(3D3B), H(3E3B), H(3F3F), H(4003), H(4107), H(4207), H(4303), H(4407), H(4503), H(4603), H(4707), H(480F), H(490B), + /* B */ H(4A1B), H(4B1F), H(4C1B), H(4D1F), H(4E1F), H(4F1B), H(5007), H(5103), H(5203), H(5307), H(5403), H(5507), H(5607), H(5703), H(580B), H(590F), + /* C */ H(5A1F), H(5B1B), H(5C1F), H(5D1B), H(5E1B), H(5F1F), H(6027), H(6123), H(6223), H(6327), H(6423), H(6527), H(6627), H(6723), H(682B), H(692F), + /* D */ H(6A3F), H(6B3B), H(6C3F), H(6D3B), H(6E3B), H(6F3F), H(7023), H(7127), H(7227), H(7323), H(7427), H(7523), H(7623), H(7727), H(782F), H(792B), + /* E */ H(7A3B), H(7B3F), H(7C3B), H(7D3F), H(7E3F), H(7F3B), H(8083), H(8187), H(8287), H(8383), H(8487), H(8583), H(8683), H(8787), H(888F), H(898B), + /* F */ H(8A9B), H(8B9F), H(8C9B), H(8D9F), H(8E9F), H(8F9B), H(9087), H(9183), H(9283), H(9387), H(9483), H(9587), H(9687), H(9783), H(988B), H(998F)}; + +# undef H +#endif + + /* MARK: - Types */ typedef zuint8 (* Insn)(Z80 *self); @@ -95,7 +258,7 @@ typedef zuint8 (* Insn)(Z80 *self); #endif -/* MARK: - Instance Variable and Callback Shortcuts */ +/* MARK: - Shortcuts for Instance Variables and Callbacks */ #define MEMPTR self->memptr.uint16_value #define PC self->pc.uint16_value @@ -144,7 +307,7 @@ typedef zuint8 (* Insn)(Z80 *self); #define NOTIFY(callback) if (self->callback != Z_NULL) self->callback(CONTEXT) -/* MARK: - Callbacks: 16-bit Operations */ +/* MARK: - 16-bit Callback Operations */ static inline zuint16 fetch_16(Z80 *self, zuint16 address) { @@ -189,6 +352,78 @@ static inline void write_16b(Z80 *self, zuint16 address, zuint16 value) #define WRITE_16B(address, value) write_16b(self, address, value) +/* MARK: - Interrupt Mode 0: Callback Trampolines */ + +#ifdef Z80_WITH_FULL_IM0 + static zuint8 im0_fetch(IM0 const *self, zuint16 address) + { + Z_UNUSED(address) + return self->z80->int_fetch(CONTEXT, self->pc); + } + + + static zuint8 im0_read(IM0 const *self, zuint16 address) + {return READ(address);} + + + static void im0_write(IM0 const *self, zuint16 address, zuint8 value) + {WRITE(address, value);} + + + static zuint8 im0_in(IM0 const *self, zuint16 port) + {return IN(port);} + + + static void im0_out(IM0 const *self, zuint16 port, zuint8 value) + {OUT(port, value);} + + + static void im0_ld_i_a(IM0 const *self) {NOTIFY(ld_i_a);} + static void im0_ld_r_a(IM0 const *self) {NOTIFY(ld_r_a);} + + +# ifdef Z80_WITH_IM0_RETX_NOTIFICATIONS +# define IM0_NOTIFY_RETX(callback) \ + if ( self->callback != Z_NULL && \ + (self->z80->options & \ + Z80_OPTION_IM0_RETX_NOTIFICATIONS) \ + ) \ + { \ + self->z80->data.uint8_array[2] |= 4; \ + self->callback(CONTEXT); \ + } + + + static void im0_reti(IM0 const *self) {IM0_NOTIFY_RETX(reti)} + static void im0_retn(IM0 const *self) {IM0_NOTIFY_RETX(retn)} +# endif +#endif + + +/* MARK: - Interrupt Mode 0: PC Decrements for Unprefixed Instructions */ + +#ifdef Z80_WITH_FULL_IM0 + static zuint8 const im0_pc_decrement_table[256] = { + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 1 */ 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + /* 2 */ 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + /* 3 */ 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + /* 4 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 5 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 6 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 7 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* A */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* B */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* C */ 1, 0, 3, 3, 3, 0, 0, 1, 1, 1, 3, 0, 3, 3, 0, 1, + /* D */ 1, 0, 3, 0, 3, 0, 0, 1, 1, 0, 3, 0, 3, 0, 0, 1, + /* E */ 1, 0, 3, 0, 3, 0, 0, 1, 1, 1, 3, 0, 3, 0, 0, 1, + /* F */ 1, 0, 3, 0, 3, 0, 0, 1, 1, 0, 3, 0, 3, 0, 0, 1}; +#endif + + /* MARK: - Flags */ /*----------------. @@ -231,9 +466,18 @@ static inline void write_16b(Z80 *self, zuint16 address, zuint16 value) #define ZF_ZERO(value) (!(value) << 6) +/*---------------------------------------------------------------------. +| `PF_PARITY` computes PF according to the parity of the given byte. | +| Enabling `Z80_WITH_PARITY_COMPUTATION` is strongly discouraged and | +| is provided only for benchmarking and educational purposes. | +| | +| For an explanation of the parity computation formula, check: | +| * http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel | +'=====================================================================*/ + #ifdef Z80_WITH_PARITY_COMPUTATION static inline zuint8 pf_parity(zuint8 value) - {return (((0x9669U >> ((value ^ (value >> 4)) & 0xF)) & 1) << 2);} + {return (zuint8)(((0x9669U >> ((value ^ (value >> 4)) & 0xF)) & 1) << 2);} # define PF_PARITY pf_parity #else @@ -262,7 +506,9 @@ static inline void write_16b(Z80 *self, zuint16 address, zuint16 value) /*-----------------------------------------------------------------------------. | `PF_OVERFLOW` computes PF according to whether signed overflow occurs in the | | addition or subtraction of two integers. For additions, `rhs` must be passed | -| bit-wise ~inverted. For an explanation of the formula, check: | +| bitwise ~inverted. | +| | +| For an explanation of the formula, check: | | * https://stackoverflow.com/a/199668 | | * http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Comb/overflow.html | '=============================================================================*/ @@ -647,9 +893,8 @@ static inline zuint8 m(Z80 *self, zuint8 offset, zuint8 value) zuint8 t; Q_0 - t = DATA[offset]; - return (zuint8)((t & 64) + return (zuint8)(((t = DATA[offset]) & 64) ? value | (1U << ((t >> 3) & 7)) : value & ~(1U << ((t >> 3) & 7))); } @@ -689,6 +934,23 @@ static inline zuint8 m(Z80 *self, zuint8 offset, zuint8 value) return 9 +#define LD_VWORD_COMMON(insn_size) \ + zuint16 n; \ + \ + Q_0 \ + MEMPTR = (n = FETCH_16((PC += insn_size) - 2)) + 1 + + +#define EX_VSP(rhs, pc_increment) \ + zuint16 sp, t = rhs; \ + \ + Q_0 \ + pc_increment; \ + rhs = MEMPTR = READ_16(sp = SP); \ + WRITE_16B(sp, t); \ + return 19 + + #define LDX(operator) \ zuint8 t = READ(HL operator); \ \ @@ -809,7 +1071,7 @@ static inline zuint8 m(Z80 *self, zuint8 offset, zuint8 value) /* HF = high-half-carry (adc), high-half-borrow (sbc) */ \ | (((HL ^ ss ^ t) >> 8) & HF) \ /* PF = overflow */ \ - | PF_OVERFLOW(16, t, HL, pf_overflow_rhs) \ + | PF_OVERFLOW(16, (zuint16)t, HL, pf_overflow_rhs) \ | ((t >> 16) & 1) /* CF = carry (adc), borrow (sbc) */ \ or_nf); /* NF = 0 (adc), 1 (sbc) */ \ \ @@ -860,19 +1122,19 @@ static inline zuint8 m(Z80 *self, zuint8 offset, zuint8 value) return 18 -#define DJNZ_JR_Z_OFFSET(condition, cycles_if_true, cycles_if_false) \ - zsint8 offset; \ - \ - Q_0 \ - offset = (zsint8)FETCH(PC + 1); /* Always read */ \ - \ - if (condition) \ - { \ - MEMPTR = (PC += 2 + offset); \ - return cycles_if_true; \ - } \ - \ - PC += 2; \ +#define DJNZ_JR_Z(condition, cycles_if_true, cycles_if_false) \ + zsint8 offset; \ + \ + Q_0 \ + offset = (zsint8)FETCH(PC + 1); /* Always read */ \ + \ + if (condition) \ + { \ + MEMPTR = (PC += 2 + offset); \ + return cycles_if_true; \ + } \ + \ + PC += 2; \ return cycles_if_false @@ -938,7 +1200,7 @@ static inline zuint8 m(Z80 *self, zuint8 offset, zuint8 value) | Block instructions produce an extra M-cycle of 5 T-states to decrement PC if | | the loop condition is met. In 2018, David Banks (AKA hoglet) discovered that | | the Z80 CPU performs additional flag changes during this M-cycle and managed | -| to decipher the behaviors. All block instructions copy bits 13 and 11 of PCi | +| to decipher the behaviors: All block instructions copy bits 13 and 11 of PCi | | to YF and XF, respectively [1.1], but `inir`, `indr`, `otir` and `otdr` also | | modify HF and PF in a very complicated way [1.2]. These latter two flags are | | not commented here because the explanation would not be simpler than the | @@ -957,13 +1219,13 @@ static inline zuint8 m(Z80 *self, zuint8 offset, zuint8 value) | | | References: | | 1. https://stardot.org.uk/forums/viewtopic.php?t=15464 | -| 1. https://stardot.org.uk/forums/viewtopic.php?p=211042#p211042 | -| 2. https://stardot.org.uk/forums/viewtopic.php?p=212021#p212021 | +| 1. https://stardot.org.uk/forums/viewtopic.php?p=211042#p211042 | +| 2. https://stardot.org.uk/forums/viewtopic.php?p=212021#p212021 | | 2. Banks, David (2018-08-21). "Undocumented Z80 Flags" rev. 1.0. | -| * https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags | -| * https://stardot.org.uk/forums/download/file.php?id=39831 | +| * https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags | +| * https://stardot.org.uk/forums/download/file.php?id=39831 | | 3. Helcmanovsky, Peter (2021/2022). "Z80 Block Flags Test". | -| * https://github.com/MrKWatkins/ZXSpectrumNextTests | +| * https://github.com/MrKWatkins/ZXSpectrumNextTests | | 4. https://github.com/hoglet67/Z80Decoder/issues/2 | | 5. https://spectrumcomputing.co.uk/forums/viewtopic.php?t=10555 | '=============================================================================*/ @@ -1028,6 +1290,15 @@ static inline zuint8 m(Z80 *self, zuint8 offset, zuint8 value) if (self->halt != Z_NULL) self->halt(CONTEXT, 0) +/* MARK: - Forward Declarations */ + +static Insn const insn_table [256]; +static Insn const cb_insn_table [256]; +static Insn const ed_insn_table [256]; +static Insn const xy_insn_table [256]; +static Insn const xy_cb_insn_table[256]; + + /* MARK: - Instructions: 8-Bit Load Group */ /*----------------------------------------------------------------------------. | 0 1 2 3 Flags T-states | @@ -1057,24 +1328,24 @@ static inline zuint8 m(Z80 *self, zuint8 offset, zuint8 value) | (*) Undocumented instruction. | '============================================================================*/ -INSN(ld_J_K ) {Q_0 J0 = K0; PC++; return 4;} -INSN(ld_O_P ) {Q_0 O = P; PC += 2; return 4;} -INSN(ld_J_BYTE ) {Q_0 J0 = FETCH((PC += 2) - 1); return 7;} -INSN(ld_O_BYTE ) {Q_0 O = FETCH((PC += 3) - 1); return 7;} -INSN(ld_J_vhl ) {Q_0 J0 = READ(HL); PC++; return 7;} -INSN(ld_J_vXYpOFFSET) {Q_0 J1 = READ(FETCH_XY_EA((PC += 3) - 1)); return 15;} -INSN(ld_vhl_K ) {Q_0 WRITE(HL, K0); PC++; return 7;} -INSN(ld_vXYpOFFSET_K) {Q_0 WRITE(FETCH_XY_EA((PC += 3) - 1), K1); return 15;} -INSN(ld_vhl_BYTE ) {Q_0 WRITE(HL, FETCH((PC += 2) - 1)); return 10;} -INSN(ld_a_vbc ) {Q_0 MEMPTR = BC + 1; A = READ(BC); PC++; return 7;} -INSN(ld_a_vde ) {Q_0 MEMPTR = DE + 1; A = READ(DE); PC++; return 7;} -INSN(ld_a_vWORD ) {Q_0 MEMPTR = FETCH_16((PC += 3) - 2); A = READ(MEMPTR++); return 13;} -INSN(ld_vbc_a ) {Q_0 MEMPTRL = C + 1; WRITE(BC, MEMPTRH = A); PC++; return 7;} -INSN(ld_vde_a ) {Q_0 MEMPTRL = E + 1; WRITE(DE, MEMPTRH = A); PC++; return 7;} -INSN(ld_a_i ) {LD_A_IR(I); } -INSN(ld_a_r ) {LD_A_IR(R_ALL); } -INSN(ld_i_a ) {NOTIFY(ld_i_a); Q_0 I = A; PC += 2; return 9;} -INSN(ld_r_a ) {NOTIFY(ld_r_a); Q_0 R = R7 = A; PC += 2; return 9;} +INSN(ld_J_K ) {Q_0 J0 = K0; PC++; return 4;} +INSN(ld_O_P ) {Q_0 O = P; PC += 2; return 4;} +INSN(ld_J_BYTE ) {Q_0 J0 = FETCH((PC += 2) - 1); return 7;} +INSN(ld_O_BYTE ) {Q_0 O = FETCH((PC += 3) - 1); return 7;} +INSN(ld_J_vhl ) {Q_0 J0 = READ(HL); PC++; return 7;} +INSN(ld_J_vXYpOFFSET) {Q_0 J1 = READ(FETCH_XY_EA((PC += 3) - 1)); return 15;} +INSN(ld_vhl_K ) {Q_0 PC++; WRITE(HL, K0); return 7;} +INSN(ld_vXYpOFFSET_K) {Q_0 WRITE(FETCH_XY_EA((PC += 3) - 1), K1); return 15;} +INSN(ld_vhl_BYTE ) {Q_0 WRITE(HL, FETCH((PC += 2) - 1)); return 10;} +INSN(ld_a_vbc ) {Q_0 MEMPTR = BC + 1; A = READ(BC); PC++; return 7;} +INSN(ld_a_vde ) {Q_0 MEMPTR = DE + 1; A = READ(DE); PC++; return 7;} +INSN(ld_a_vWORD ) {Q_0 MEMPTR = FETCH_16((PC += 3) - 2); A = READ(MEMPTR++); return 13;} +INSN(ld_vbc_a ) {Q_0 PC++; MEMPTRL = C + 1; WRITE(BC, MEMPTRH = A); return 7;} +INSN(ld_vde_a ) {Q_0 PC++; MEMPTRL = E + 1; WRITE(DE, MEMPTRH = A); return 7;} +INSN(ld_a_i ) {LD_A_IR(I); } +INSN(ld_a_r ) {LD_A_IR(R_ALL); } +INSN(ld_i_a ) {NOTIFY(ld_i_a); Q_0 I = A; PC += 2; return 9;} +INSN(ld_r_a ) {NOTIFY(ld_r_a); Q_0 R = R7 = A; PC += 2; return 9;} INSN(ld_vXYpOFFSET_BYTE) @@ -1123,20 +1394,20 @@ INSN(ld_vWORD_a) | M-cycles of the instruction. | '======================================================================*/ -INSN(ld_SS_WORD ) {Q_0 SS0 = FETCH_16((PC += 3) - 2); return 10;} -INSN(ld_XY_WORD ) {Q_0 XY = FETCH_16((PC += 4) - 2); return 10;} -INSN(ld_hl_vWORD) {Q_0 MEMPTR = FETCH_16((PC += 3) - 2); HL = READ_16(MEMPTR++); return 16;} -INSN(ld_SS_vWORD) {Q_0 MEMPTR = FETCH_16((PC += 4) - 2); SS1 = READ_16(MEMPTR++); return 20;} -INSN(ld_XY_vWORD) {Q_0 MEMPTR = FETCH_16((PC += 4) - 2); XY = READ_16(MEMPTR++); return 16;} -INSN(ld_vWORD_hl) {Q_0 MEMPTR = FETCH_16((PC += 3) - 2); WRITE_16F(MEMPTR++, HL ); return 16;} -INSN(ld_vWORD_SS) {Q_0 MEMPTR = FETCH_16((PC += 4) - 2); WRITE_16F(MEMPTR++, SS1); return 20;} -INSN(ld_vWORD_XY) {Q_0 MEMPTR = FETCH_16((PC += 4) - 2); WRITE_16F(MEMPTR++, XY ); return 16;} -INSN(ld_sp_hl ) {Q_0 SP = HL; PC++; return 6;} -INSN(ld_sp_XY ) {Q_0 SP = XY; PC += 2; return 6;} -INSN(push_TT ) {Q_0 PUSH(TT); PC++; return 11;} -INSN(push_XY ) {Q_0 PUSH(XY); PC += 2; return 11;} -INSN(pop_TT ) {Q_0 TT = READ_16(SP); SP += 2; PC++; return 10;} -INSN(pop_XY ) {Q_0 XY = READ_16(SP); SP += 2; PC += 2; return 10;} +INSN(ld_SS_WORD ) {Q_0 SS0 = FETCH_16((PC += 3) - 2); return 10;} +INSN(ld_XY_WORD ) {Q_0 XY = FETCH_16((PC += 4) - 2); return 10;} +INSN(ld_hl_vWORD) {LD_VWORD_COMMON(3); HL = READ_16(n); return 16;} +INSN(ld_SS_vWORD) {LD_VWORD_COMMON(4); SS1 = READ_16(n); return 20;} +INSN(ld_XY_vWORD) {LD_VWORD_COMMON(4); XY = READ_16(n); return 16;} +INSN(ld_vWORD_hl) {LD_VWORD_COMMON(3); WRITE_16F(n, HL ); return 16;} +INSN(ld_vWORD_SS) {LD_VWORD_COMMON(4); WRITE_16F(n, SS1); return 20;} +INSN(ld_vWORD_XY) {LD_VWORD_COMMON(4); WRITE_16F(n, XY ); return 16;} +INSN(ld_sp_hl ) {Q_0 SP = HL; PC++; return 6;} +INSN(ld_sp_XY ) {Q_0 SP = XY; PC += 2; return 6;} +INSN(push_TT ) {Q_0 PC++; PUSH(TT); return 11;} +INSN(push_XY ) {Q_0 PC += 2; PUSH(XY); return 11;} +INSN(pop_TT ) {Q_0 TT = READ_16(SP); SP += 2; PC++; return 10;} +INSN(pop_XY ) {Q_0 XY = READ_16(SP); SP += 2; PC += 2; return 10;} /* MARK: - Instructions: Exchange, Block Transfer and Search Groups */ @@ -1159,19 +1430,19 @@ INSN(pop_XY ) {Q_0 XY = READ_16(SP); SP += 2; PC += 2; return 10;} | cpdr <--ED--><--B9--> sz*b**1. 21:44355 16:4435 | '=============================================================*/ -INSN(ex_de_hl ) {zuint16 t; Q_0 EX(DE, HL ); PC++; return 4;} -INSN(ex_af_af_) {zuint16 t; Q_0 EX(AF, AF_); PC++; return 4;} -INSN(exx ) {zuint16 t; Q_0 EX(BC, BC_); EX(DE, DE_); EX(HL, HL_); PC++; return 4;} -INSN(ex_vsp_hl) {Q_0 MEMPTR = READ_16(SP); WRITE_16B(SP, HL); HL = MEMPTR; PC++; return 19;} -INSN(ex_vsp_XY) {Q_0 MEMPTR = READ_16(SP); WRITE_16B(SP, XY); XY = MEMPTR; PC += 2; return 19;} -INSN(ldi ) {LDX (++); } -INSN(ldir ) {LDXR(++); } -INSN(ldd ) {LDX (--); } -INSN(lddr ) {LDXR(--); } -INSN(cpi ) {CPX (++); } -INSN(cpir ) {CPXR(++); } -INSN(cpd ) {CPX (--); } -INSN(cpdr ) {CPXR(--); } +INSN(ex_de_hl ) {zuint16 t; Q_0 EX(DE, HL ); PC++; return 4;} +INSN(ex_af_af_) {zuint16 t; Q_0 EX(AF, AF_); PC++; return 4;} +INSN(exx ) {zuint16 t; Q_0 EX(BC, BC_); EX(DE, DE_); EX(HL, HL_); PC++; return 4;} +INSN(ex_vsp_hl) {EX_VSP(HL, PC++ ); } +INSN(ex_vsp_XY) {EX_VSP(XY, PC += 2); } +INSN(ldi ) {LDX (++); } +INSN(ldir ) {LDXR(++); } +INSN(ldd ) {LDX (--); } +INSN(lddr ) {LDXR(--); } +INSN(cpi ) {CPX (++); } +INSN(cpir ) {CPXR(++); } +INSN(cpd ) {CPX (--); } +INSN(cpdr ) {CPXR(--); } /* MARK: - Instructions: 8-Bit Arithmetic and Logical Group */ @@ -1193,14 +1464,14 @@ INSN(cpdr ) {CPXR(--); } | (|) The flag is explained in table U/V. | '===================================================================*/ -INSN(U_a_K ) {U0(K0); PC++; return 4;} -INSN(U_a_P ) {U1(P); PC += 2; return 4;} +INSN(U_a_K ) {U0(K0); PC++; return 4;} +INSN(U_a_P ) {U1(P ); PC += 2; return 4;} INSN(U_a_BYTE ) {U0(FETCH((PC += 2) - 1)); return 7;} -INSN(U_a_vhl ) {U0(READ(HL)); PC++; return 7;} +INSN(U_a_vhl ) {U0(READ(HL)); PC++; return 7;} INSN(U_a_vXYpOFFSET) {U1(READ(FETCH_XY_EA((PC += 3) - 1))); return 15;} -INSN(V_J ) {zuint8 *j = &J0; *j = V0(*j); PC++; return 4;} -INSN(V_O ) {zuint8 *o = &O; *o = V1(*o); PC += 2; return 4;} -INSN(V_vhl ) {WRITE(HL, V0(READ(HL))); PC++; return 11;} +INSN(V_J ) {zuint8 *j = &J0; *j = V0(*j); PC++; return 4;} +INSN(V_O ) {zuint8 *o = &O; *o = V1(*o); PC += 2; return 4;} +INSN(V_vhl ) {PC++; WRITE(HL, V0(READ(HL))); return 11;} INSN(V_vXYpOFFSET ) {zuint16 ea = FETCH_XY_EA((PC += 3) - 1); WRITE(ea, V1(READ(ea))); return 19;} @@ -1225,7 +1496,7 @@ INSN(V_vXYpOFFSET ) {zuint16 ea = FETCH_XY_EA((PC += 3) - 1); WRITE(ea, V1(READ | (-) The instruction has undocumented opcodes. | '=================================================*/ -INSN(nop ) {Q_0 PC++; return 4;} +INSN(nop ) {Q_0 PC++; return 4;} INSN(im_0) {Q_0 IM = 0; PC += 2; return 8;} INSN(im_1) {Q_0 IM = 1; PC += 2; return 8;} INSN(im_2) {Q_0 IM = 2; PC += 2; return 8;} @@ -1233,20 +1504,33 @@ INSN(im_2) {Q_0 IM = 2; PC += 2; return 8;} INSN(daa) { - zuint8 cf = A > 0x99, t = ((F & HF) || (A & 0xF) > 9) ? 6 : 0; +# ifdef Z80_WITH_PRECOMPUTED_DAA + zuint16 afi = AF; - if (F_C || cf) t |= 0x60; - t = (F & NF) ? A - t : A + t; +# ifdef Z80_WITH_Q + Q = (zuint8) +# endif + (AF = daa_af_table[ + ( afi >> 8) | + ((afi & (CF | NF)) << 8) | + ((afi & HF) << 6)]); +# else + zuint8 cf = A > 0x99, t = ((F & HF) || (A & 0xF) > 9) ? 6 : 0; - FLAGS = (zuint8)( - (F & (NF | CF)) | /* NF unchanged; CF dominant */ - (t & SYXF) | /* SF = sign; YF = Y; XF = X */ - ZF_ZERO(t) | /* ZF = zero */ - ((A ^ t) & HF) | /* HF = Ai.4 != Ao.4 */ - PF_PARITY(t) | /* PF = parity */ - cf); /* CF |= 1 (if BCD carry) */ + if (F_C || cf) t |= 0x60; + t = (F & NF) ? A - t : A + t; + + FLAGS = (zuint8)( + (F & (NF | CF)) | /* NF unchanged; CF dominant */ + (t & SYXF) | /* SF = sign; YF = Y; XF = X */ + ZF_ZERO(t) | /* ZF = zero */ + ((A ^ t) & HF) | /* HF = Ai.4 != Ao.4 */ + PF_PARITY(t) | /* PF = parity */ + cf); /* CF |= 1 (if BCD carry) */ + + A = t; +# endif - A = t; PC++; return 4; } @@ -1254,9 +1538,9 @@ INSN(daa) INSN(cpl) { - FLAGS = F_SZPC | /* SF, ZF, PF, CF unchanged */ - ((A = ~A) & YXF) | /* YF = Y; XF = X */ - HF | NF; /* HF, NF = 1 */ + FLAGS = F_SZPC | /* SF, ZF, PF, CF unchanged */ + ((A = (zuint8)~A) & YXF) | /* YF = Y; XF = X */ + HF | NF; /* HF, NF = 1 */ PC++; return 4; @@ -1285,7 +1569,7 @@ INSN(neg) | `ccf` and `scf` are the only instructions in which Q affects the flags. | | Patrik Rak cracked the behavior of YF and XF in 2012, confirming that they | | are taken, respectively, from bits 5 and 3 of the result of `(Q ^ F) | A` | -| [1,2]. This applies to all Zilog Z80 models, both NMOS and CMOS. In 2018, | +| [1, 2]. This applies to all Zilog Z80 models, both NMOS and CMOS. In 2018, | | David Banks (AKA hoglet) discovered that at least some ST CMOS models do | | not set XF according to this formula and instead take this flag from bit 3 | | of A, whereas NEC NMOS models take both flags from A [3]. | @@ -1341,12 +1625,13 @@ INSN(scf) | that the instruction is re-executed" as Sean Young writes in section 5.4 of | | "The Undocumented Z80 Documented". During the HALT state, the CPU repeatedly | | executes an internal NOP operation. Each NOP consists of 1 M1 cycle of 4 | -| T-states that fetches and disregards the next opcode after `halt` without | +| T-states that fetches (and disregards) the next opcode after `halt` without | | incrementing PC. This opcode is read again and again until an exit condition | | occurs (i.e., INT, NMI or RESET). | | | -| This was first documented by Tony Brewer in 2014, and was later re-confirmed | -| by the HALT2INT test written by Mark Woodmass (AKA Woody) in 2021. | +| This was first documented by Tony Brewer in 2014, and was later verified on | +| real hardware with the HALT2INT test written by Mark Woodmass (AKA Woody) in | +| 2021. | | | | References: | | * Brewer, Tony (2014-12). "Z80 Special Reset". | @@ -1354,10 +1639,6 @@ INSN(scf) | * https://stardot.org.uk/forums/viewtopic.php?p=357136#p357136 | '=============================================================================*/ -#ifdef Z80_WITH_SPECIAL_RESET - static Insn const insn_table[256]; -#endif - INSN(halt) { if (!HALT_LINE) @@ -1400,6 +1681,11 @@ INSN(halt) zuint8 opcode; do { +# ifdef Z80_WITH_RESET_SIGNAL + if (self->reset_signal != Z_NULL && (*self->reset_signal & self->reset_signal_mask)) + return 0; +# endif + R++; opcode = self->nop(CONTEXT, PC); self->cycles += 4; @@ -1415,7 +1701,7 @@ INSN(halt) if (self->halt != Z_NULL) self->halt(CONTEXT, Z80_HALT_EXIT_EARLY); - if ((DATA[0] = opcode) != 0x76) + if ((DATA[0] = opcode) != Z80_HALT) { self->cycles -= 4; PC--; @@ -1433,6 +1719,11 @@ INSN(halt) # else else do { +# ifdef Z80_WITH_RESET_SIGNAL + if (self->reset_signal != Z_NULL && (*self->reset_signal & self->reset_signal_mask)) + return 0; +# endif + R++; (void)self->nop(CONTEXT, PC); self->cycles += 4; @@ -1515,7 +1806,7 @@ INSN(dec_XY ) {Q_0 XY--; PC += 2; return 6;} | (*) Undocumented instruction. | '=========================================================================*/ -INSN(rlca ) {A = ROL(A); FLAGS = F_SZP | (A & YXCF); PC++; return 4;} +INSN(rlca ) {A = ROL(A); FLAGS = F_SZP | (A & YXCF); PC++; return 4;} INSN(rla ) {RXA(A >> 7, <<, F_C); } INSN(rrca ) {A = ROR(A); FLAGS = F_SZP | A_YX | (A >> 7); PC++; return 4;} INSN(rra ) {RXA(A & 1, >>, (F << 7)); } @@ -1634,10 +1925,10 @@ INSN(bit_N_vXYpOFFSET) INSN(jp_WORD ) {Q_0 MEMPTR = PC = FETCH_16(PC + 1); return 10;} INSN(jp_Z_WORD ) {Q_0 MEMPTR = FETCH_16(PC + 1); PC = Z(7) ? MEMPTR : PC + 3; return 10;} INSN(jr_OFFSET ) {Q_0 MEMPTR = (PC += 2 + (zsint8)FETCH(PC + 1)); return 12;} -INSN(jr_Z_OFFSET) {DJNZ_JR_Z_OFFSET(Z(3), 12, 7); } +INSN(jr_Z_OFFSET) {DJNZ_JR_Z(Z(3), 12, 7); } INSN(jp_hl ) {Q_0 PC = HL; return 4;} INSN(jp_XY ) {Q_0 PC = XY; return 4;} -INSN(djnz_OFFSET) {DJNZ_JR_Z_OFFSET(--B, 13, 8); } +INSN(djnz_OFFSET) {DJNZ_JR_Z(--B, 13, 8); } /* MARK: - Instructions: Call and Return Group */ @@ -1657,23 +1948,25 @@ INSN(djnz_OFFSET) {DJNZ_JR_Z_OFFSET(--B, 13, 8); } | the Z80 CTC chip. All other opcodes are represented as `retn`. | '====================================================================*/ -INSN(call_WORD) {Q_0 MEMPTR = FETCH_16(PC + 1); PUSH(PC + 3); PC = MEMPTR; return 17;} -INSN(ret ) {Q_0 RET; return 10;} -INSN(ret_Z ) {Q_0 if (Z(7)) {RET; return 11;} PC++; return 5;} -INSN(reti ) {RETX(reti); } -INSN(retn ) {RETX(retn); } -INSN(rst_N ) {Q_0 PUSH(PC + 1); MEMPTR = PC = DATA[0] & 56; return 11;} +INSN(call_WORD) {zuint16 pci = PC; Q_0 MEMPTR = PC = FETCH_16(pci + 1); PUSH(pci + 3); return 17;} +INSN(ret ) {Q_0 RET; return 10;} +INSN(ret_Z ) {Q_0 if (Z(7)) {RET; return 11;} PC++; return 5;} +INSN(reti ) {RETX(reti); } +INSN(retn ) {RETX(retn); } +INSN(rst_N ) {zuint16 pci = PC; Q_0 MEMPTR = PC = DATA[0] & 56; PUSH(pci + 1); return 11;} INSN(call_Z_WORD) { + zuint16 pci; + Q_0 - MEMPTR = FETCH_16(PC + 1); /* Always read */ + MEMPTR = FETCH_16((pci = PC) + 1); /* Always read */ if (Z(7)) { - PUSH(PC + 3); PC = MEMPTR; + PUSH(pci + 3); return 17; } @@ -1714,7 +2007,7 @@ INSN(ini ) {INX (++, +); } INSN(inir ) {INXR(++, +); } INSN(ind ) {INX (--, -); } INSN(indr ) {INXR(--, -); } -INSN(out_vc_J) {Q_0 MEMPTR = BC + 1; OUT(BC, J1); PC += 2; return 12;} +INSN(out_vc_J) {Q_0 PC += 2; MEMPTR = BC + 1; OUT(BC, J1); return 12;} INSN(outi ) {OUTX(++, +); } INSN(otir ) {OTXR(++, +); } INSN(outd ) {OUTX(--, -); } @@ -1753,19 +2046,19 @@ INSN(out_vBYTE_a) } -/*----------------------------------------------------------------------------. -| The `out (c),0` instruction behaves as `out (c),255` on the Zilog Z80 CMOS. | -| This was first discovered by Simon Cooke, who reported it on Usenet in 1996 | -| [1,2]. Later, in 2004, Colin Piggot rediscovered it with his SAM Coupé when | -| running a demo for SCPDU 6, coincidentally written by Simon Cooke [1]. In | -| 2008, this was once again rediscovered by the MSX community [1,3]. | -| | -| References: | -| 1. https://sinclair.wiki.zxnet.co.uk/wiki/Z80 | -| 2. https://groups.google.com/g/comp.os.cpm/c/HfSTFpaIkuU/m/KotvMWu3bZoJ | -| 3. https://msx.org/forum/development/msx-development/bug-z80-emulation-or- | -| tr-hw | -'============================================================================*/ +/*-----------------------------------------------------------------------------. +| The `out (c),0` instruction behaves as `out (c),255` on the Zilog Z80 CMOS. | +| This was first discovered by Simon Cooke, who reported it on Usenet in 1996 | +| [1, 2]. Later, in 2004, Colin Piggot rediscovered it with his SAM Coupé when | +| running a demo for SCPDU 6, coincidentally written by Simon Cooke [1]. In | +| 2008, this was once again rediscovered by the MSX community [1, 3]. | +| | +| References: | +| 1. https://sinclair.wiki.zxnet.co.uk/wiki/Z80 | +| 2. https://groups.google.com/g/comp.os.cpm/c/HfSTFpaIkuU/m/KotvMWu3bZoJ | +| 3. https://msx.org/forum/development/msx-development/bug-z80-emulation-or-tr | +| -hw | +'=============================================================================*/ INSN(out_vc_0) { @@ -1779,21 +2072,159 @@ INSN(out_vc_0) /* MARK: - Instructions: Optimizations */ -INSN(nop_nop) {Q_0; PC += 2; return 4;} +INSN(nop_nop) {Q_0 PC += 2; return 4;} + + +/* MARK: - Instructions: Prefix Handling */ + +INSN(cb_prefix) + { + R++; + return cb_insn_table[DATA[1] = FETCH_OPCODE((PC += 2) - 1)](self); + } + + +INSN(ed_prefix) + { + R++; + return ed_insn_table[DATA[1] = FETCH_OPCODE(PC + 1)](self); + } + + +#define XY_PREFIX(index_register) \ + zuint8 cycles; \ + \ + if ((self->cycles += 4) >= self->cycle_limit) \ + { \ + RESUME = Z80_RESUME_XY; \ + return 0; \ + } \ + \ + R++; \ + XY = index_register; \ + cycles = xy_insn_table[DATA[1] = FETCH_OPCODE(PC + 1)](self); \ + index_register = XY; \ + return cycles; + + +INSN(dd_prefix) {XY_PREFIX(IX)} +INSN(fd_prefix) {XY_PREFIX(IY)} + + +/*-----------------------------------------------------------------------. +| Instructions with the two-byte prefix DDCBh or FDCBh increment R by 2, | +| as only the prefix is fetched by opcode fetch operations (M1 cycles). | +| The remaining two bytes are fetched by normal memory read operations. | +'=======================================================================*/ + +INSN(xy_cb_prefix) + { + FETCH_XY_EA((PC += 4) - 2); + return xy_cb_insn_table[DATA[3] = FETCH(PC - 1)](self); + } + + +/*-----------------------------------------------------------------------------. +| In a sequence of DDh and/or FDh prefixes, it is the last one that counts, as | +| each prefix overrides the previous one. No matter how long the sequence is, | +| interrupts can only be responded to after executing the final instruction | +| once all the prefixes have been fetched. Each prefix takes 4 T-states. | +'=============================================================================*/ + +INSN(xy_xy) + { + ZInt16 *xy; + zuint16 t; + zuint8 cycles; + + do { + PC++; + DATA[0] = DATA[1]; + + if ((self->cycles += 4) >= self->cycle_limit) + { + RESUME = Z80_RESUME_XY; + return 0; + } + + R++; + } + while (IS_XY_PREFIX(DATA[1] = FETCH_OPCODE(PC + 1))); + + t = XY; + XY = (xy = &self->ix_iy[(DATA[0] >> 5) & 1])->uint16_value; + cycles = xy_insn_table[DATA[1]](self); + xy->uint16_value = XY; + XY = t; + return cycles; + } + + +/* MARK: - Instructions: Illegal */ + +/*------------------------------------------------------------------------. +| Illegal opcodes prefixed with EDh are ignored by the CPU. Functionally, | +| these instructions are equivalent to two consecutive `nop` instructions | +| and take a total of 8 T-states. | +'========================================================================*/ + +INSN(ed_illegal) + { + if (self->illegal != Z_NULL) + { + DATA[2] = 0; + return self->illegal(self, DATA[1]); + } + + Q_0 + PC += 2; + return 8; + } + + +/*-------------------------------------------------------------------------. +| Illegal opcodes prefixed with DDh or FDh make the CPU ignore the prefix, | +| As a result, the byte that immediately follows the prefix is treated as | +| the first byte of a new instruction. The prefix takes 4 T-states. | +'=========================================================================*/ + +INSN(xy_illegal) + { + PC++; + return insn_table[DATA[0] = DATA[1]](self); + } + + +#ifdef Z80_WITH_Q + INSN(xy_xcf) + { + Q_0 + PC++; + return insn_table[DATA[0] = DATA[1]](self); + } +#else +# define xy_xcf xy_illegal +#endif + + +/* MARK: - Instructions: Hooking */ + +INSN(hook) + { + if (self->hook == Z_NULL) + { + Q_0 + PC++; + return 4; + } + + return ((DATA[0] = self->hook(CONTEXT, PC)) != Z80_HOOK) + ? insn_table[DATA[0]](self) : 0; + } /* MARK: - Instruction Function Tables */ -INSN(cb_prefix ); -INSN(ed_prefix ); -INSN(dd_prefix ); -INSN(fd_prefix ); -INSN(xy_cb_prefix); -INSN(xy_xy ); -INSN(ed_illegal ); -INSN(xy_illegal ); -INSN(hook ); - #ifdef Z80_WITH_UNOFFICIAL_RETI # define reti_retn reti #else @@ -1862,7 +2293,7 @@ static Insn const xy_insn_table[256] = { /* 0 */ nop_nop, xy_illegal, xy_illegal, xy_illegal, V_O, V_O, ld_O_BYTE, xy_illegal, xy_illegal, add_XY_WW, xy_illegal, xy_illegal, V_O, V_O, ld_O_BYTE, xy_illegal, /* 1 */ xy_illegal, xy_illegal, xy_illegal, xy_illegal, V_O, V_O, ld_O_BYTE, xy_illegal, xy_illegal, add_XY_WW, xy_illegal, xy_illegal, V_O, V_O, ld_O_BYTE, xy_illegal, /* 2 */ xy_illegal, ld_XY_WORD, ld_vWORD_XY, inc_XY, V_O, V_O, ld_O_BYTE, xy_illegal, xy_illegal, add_XY_WW, ld_XY_vWORD, dec_XY, V_O, V_O, ld_O_BYTE, xy_illegal, -/* 3 */ xy_illegal, xy_illegal, xy_illegal, xy_illegal, V_vXYpOFFSET, V_vXYpOFFSET, ld_vXYpOFFSET_BYTE, xy_illegal, xy_illegal, add_XY_WW, xy_illegal, xy_illegal, V_O, V_O, ld_O_BYTE, xy_illegal, +/* 3 */ xy_illegal, xy_illegal, xy_illegal, xy_illegal, V_vXYpOFFSET, V_vXYpOFFSET, ld_vXYpOFFSET_BYTE, xy_xcf, xy_illegal, add_XY_WW, xy_illegal, xy_illegal, V_O, V_O, ld_O_BYTE, xy_xcf, /* 4 */ nop_nop, ld_O_P, ld_O_P, ld_O_P, ld_O_P, ld_O_P, ld_J_vXYpOFFSET, ld_O_P, ld_O_P, nop_nop, ld_O_P, ld_O_P, ld_O_P, ld_O_P, ld_J_vXYpOFFSET, ld_O_P, /* 5 */ ld_O_P, ld_O_P, nop_nop, ld_O_P, ld_O_P, ld_O_P, ld_J_vXYpOFFSET, ld_O_P, ld_O_P, ld_O_P, ld_O_P, nop_nop, ld_O_P, ld_O_P, ld_J_vXYpOFFSET, ld_O_P, /* 6 */ ld_O_P, ld_O_P, ld_O_P, ld_O_P, nop_nop, ld_O_P, ld_J_vXYpOFFSET, ld_O_P, ld_O_P, ld_O_P, ld_O_P, ld_O_P, ld_O_P, nop_nop, ld_J_vXYpOFFSET, ld_O_P, @@ -1896,256 +2327,43 @@ static Insn const xy_cb_insn_table[256] = { /* F */ M_N_vXYpOFFSET_K, M_N_vXYpOFFSET_K, M_N_vXYpOFFSET_K, M_N_vXYpOFFSET_K, M_N_vXYpOFFSET_K, M_N_vXYpOFFSET_K, M_N_vXYpOFFSET, M_N_vXYpOFFSET_K, M_N_vXYpOFFSET_K, M_N_vXYpOFFSET_K, M_N_vXYpOFFSET_K, M_N_vXYpOFFSET_K, M_N_vXYpOFFSET_K, M_N_vXYpOFFSET_K, M_N_vXYpOFFSET, M_N_vXYpOFFSET_K}; -/* MARK: - Instructions: Prefix Handling */ - -INSN(cb_prefix) - { - R++; - return cb_insn_table[DATA[1] = FETCH_OPCODE((PC += 2) - 1)](self); - } - - -INSN(ed_prefix) - { - R++; - return ed_insn_table[DATA[1] = FETCH_OPCODE(PC + 1)](self); - } - - -#define XY_PREFIX(index_register) \ - zuint8 cycles; \ - \ - if ((self->cycles += 4) >= self->cycle_limit) \ - { \ - RESUME = Z80_RESUME_XY; \ - return 0; \ - } \ - \ - R++; \ - XY = index_register; \ - cycles = xy_insn_table[DATA[1] = FETCH_OPCODE(PC + 1)](self); \ - index_register = XY; \ - return cycles; - - -INSN(dd_prefix) {XY_PREFIX(IX)} -INSN(fd_prefix) {XY_PREFIX(IY)} - - -/*-----------------------------------------------------------------------. -| Instructions with the two-byte prefix DDCBh or FDCBh increment R by 2, | -| as only the prefix is fetched by opcode fetch operations (M1 cycles). | -| The remaining two bytes are fetched by normal memory read operations. | -'=======================================================================*/ - -INSN(xy_cb_prefix) - { - FETCH_XY_EA((PC += 4) - 2); - return xy_cb_insn_table[DATA[3] = FETCH(PC - 1)](self); - } - - -/*-----------------------------------------------------------------------------. -| In a sequence of DDh and/or FDh prefixes, it is the last one that counts, as | -| each prefix overrides the previous one. No matter how long the sequence is, | -| interrupts can only be responded to after executing the final instruction | -| once all the prefixes have been fetched. Each prefix takes 4 T-states. | -'=============================================================================*/ - -INSN(xy_xy) - { - zuint8 cycles; - zuint8 first_prefix = DATA[0]; - - do { - PC++; - DATA[0] = DATA[1]; - - if ((self->cycles += 4) >= self->cycle_limit) - { - RESUME = Z80_RESUME_XY; - return 0; - } - - R++; - } - while (IS_XY_PREFIX(DATA[1] = FETCH_OPCODE(PC + 1))); - - if (DATA[0] == first_prefix) return xy_insn_table[DATA[1]](self); - - if (first_prefix == 0xFD) - { - XY = IX; - cycles = xy_insn_table[DATA[1]](self); - IX = XY; - XY = IY; - } - - else { - XY = IY; - cycles = xy_insn_table[DATA[1]](self); - IY = XY; - XY = IX; - } - - return cycles; - } - - -/* MARK: - Instructions: Illegal */ - -/*----------------------------------------------------------------. -| The CPU ignores illegal opcodes prefixed with EDh. In practice, | -| they are all equivalent to two `nop` instructions (8 T-states). | -'================================================================*/ - -INSN(ed_illegal) - { - if (self->illegal != Z_NULL) - { - DATA[2] = 0; - return self->illegal(self, DATA[1]); - } - - Q_0 - PC += 2; - return 8; - } - - -/*-----------------------------------------------------------------------. -| Illegal opcodes with the prefix DDh or FDh cause the CPU to ignore the | -| prefix, i.e., the byte immediately following the prefix is interpreted | -| as the first byte of a new instruction. The prefix takes 4 T-states. | -'=======================================================================*/ - -INSN(xy_illegal) - { - PC++; - return insn_table[DATA[0] = DATA[1]](self); - } - - -/* MARK: - Instructions: Hooking */ - -INSN(hook) - { - if (self->hook == Z_NULL) - { - Q_0 - PC++; - return 4; - } - - return ((DATA[0] = self->hook(CONTEXT, PC)) != Z80_HOOK) - ? insn_table[DATA[0]](self) : 0; - } - - -/* MARK: - Interrupt Mode 0: PC Decrements for Unprefixed Instructions */ - -#ifdef Z80_WITH_FULL_IM0 - static zuint8 const im0_pc_decrement_table[256] = { - /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ - /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 1 */ 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, - /* 2 */ 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, - /* 3 */ 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, - /* 4 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 5 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 6 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 7 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* A */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* B */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* C */ 1, 0, 3, 3, 3, 0, 0, 1, 1, 1, 3, 0, 3, 3, 0, 1, - /* D */ 1, 0, 3, 0, 3, 0, 0, 1, 1, 0, 3, 0, 3, 0, 0, 1, - /* E */ 1, 0, 3, 0, 3, 0, 0, 1, 1, 1, 3, 0, 3, 0, 0, 1, - /* F */ 1, 0, 3, 0, 3, 0, 0, 1, 1, 0, 3, 0, 3, 0, 0, 1}; -#endif - - -/* MARK: - Interrupt Mode 0: Callback Trampolines */ - -#ifdef Z80_WITH_FULL_IM0 - static zuint8 im0_fetch(IM0 const *self, zuint16 address) - { - Z_UNUSED(address) - return self->z80->int_fetch(CONTEXT, self->pc); - } - - - static zuint8 im0_read(IM0 const *self, zuint16 address) - {return READ(address);} - - - static void im0_write(IM0 const *self, zuint16 address, zuint8 value) - {WRITE(address, value);} - - - static zuint8 im0_in(IM0 const *self, zuint16 port) - {return IN(port);} - - - static void im0_out(IM0 const *self, zuint16 port, zuint8 value) - {OUT(port, value);} - - - static void im0_ld_i_a(IM0 const *self) {NOTIFY(ld_i_a);} - static void im0_ld_r_a(IM0 const *self) {NOTIFY(ld_r_a);} - - -# ifdef Z80_WITH_IM0_RETX_NOTIFICATIONS - #define IM0_NOTIFY_RETX(callback) \ - if ( self->callback != Z_NULL && \ - (self->z80->options & \ - Z80_OPTION_IM0_RETX_NOTIFICATIONS) \ - ) \ - { \ - self->z80->data.uint8_array[2] |= 2; \ - self->callback(CONTEXT); \ - } - - - static void im0_reti(IM0 const *self) {IM0_NOTIFY_RETX(reti)} - static void im0_retn(IM0 const *self) {IM0_NOTIFY_RETX(retn)} -# endif -#endif - - /* MARK: - Public Functions */ -/*----------------------------------------------------------------------. -| On POWER-ON, the CPU zeroes PC, I and R, sets SP, IX, IY, AF, BC, DE, | -| HL, AF', BC', DE' and HL' to FFFFh [1,2], resets the interrupt enable | -| flip-flops (IFF1 and IFF2) and selects interrupt mode 0 [3]. On Zilog | -| NMOS models, F is sometimes set to FDh (NF reset) [1]. | -| | -| There is no information about the initial state of MEMPTR and Q, so | -| they are assumed to be 0. | -| | -| References: | -| 1. https://baltazarstudios.com/webshare/Z80-undocumented-behavior.htm | -| 2. https://worldofspectrum.org/forums/discussion/34574 | -| 3. Young, Sean (2005-09-18). "Undocumented Z80 Documented, The" | -| v0.91, p. 20. | -'======================================================================*/ +/*-----------------------------------------------------------------------. +| On POWER-ON, the CPU zeroes PC, I and R, sets SP, IX, IY, AF, BC, DE, | +| HL, AF', BC', DE' and HL' to FFFFh [1, 2], resets the interrupt enable | +| flip-flops (IFF1 and IFF2) and selects interrupt mode 0 [3]. On Zilog | +| NMOS models, F is sometimes set to FDh (NF reset) [1]. | +| | +| There is no information about the initial state of MEMPTR and Q, so | +| they are assumed to be 0. | +| | +| References: | +| 1. https://baltazarstudios.com/webshare/Z80-undocumented-behavior.htm | +| 2. https://worldofspectrum.org/forums/discussion/34574 | +| 3. Young, Sean (2005-09-18). "Undocumented Z80 Documented, The" v0.91, | +| p. 20. | +'=======================================================================*/ -Z80_API void z80_power(Z80 *self, zboolean state) +Z80_API void z80_power(Z80 *self, zbool state) { MEMPTR = PC = R = I = IFF1 = IFF2 = IM = Q = DATA[0] = HALT_LINE = INT_LINE = RESUME = REQUEST = 0; SP = IX = IY = AF = BC = DE = HL = AF_ = BC_ = DE_ = HL_ = state ? Z_UINT16(0xFFFF) : 0; + +# ifdef Z80_WITH_RESET_SIGNAL + self->reset_signal = Z_NULL; + self->reset_signal_mask = 0; +# endif } /*-------------------------------------------------------------------------. -| The normal RESET zeroes PC, I, and R [1,2,3,4,5,6], resets the interrupt | -| enable flip-flops (IFF1 and IFF2) [1,2,3,4,5] and selects interrupt mode | -| 0 [1,2,3,4,7]. | +| The normal RESET zeroes PC, I, and R [1, 2, 3, 4, 5, 6], resets the | +| interrupt enable flip-flops (IFF1 and IFF2) [1, 2, 3, 4, 5] and selects | +| interrupt mode 0 [1, 2, 3, 4, 7]. | | | | References: | | 1. Zilog (2016-09). "Z80 CPU User Manual" rev. 11, p. 6. | @@ -2174,7 +2392,7 @@ Z80_API void z80_instant_reset(Z80 *self) #endif -Z80_API void z80_int(Z80 *self, zboolean state) +Z80_API void z80_int(Z80 *self, zbool state) { if (!(INT_LINE = state)) REQUEST &= ~(zuint8)Z80_REQUEST_INT; else if (IFF1) REQUEST |= Z80_REQUEST_INT; @@ -2215,7 +2433,7 @@ Z80_API void z80_nmi(Z80 *self) self->cycles += insn_table[DATA[0] = FETCH_OPCODE(PC)](self); } - R = R_ALL; /* Restore R7 bit */ + R = R_ALL; return self->cycles; } #endif @@ -2263,7 +2481,7 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) if (IS_XY_PREFIX(DATA[0] = opcode = DATA[2])) self->cycles += insn_table[FETCH_OPCODE(PC)](self); - else if (opcode != 0x76) + else if (opcode != Z80_HALT) { PC--; self->cycles += insn_table[opcode](self) - 4; @@ -2275,10 +2493,10 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) else (void)halt(self); break; - /*--------------------------------------------------------------. - | The CPU is in normal operation state; the emulator ran out of | - | clock cycles by fetching a prefix DDh or FDh. | - '==============================================================*/ + /*-------------------------------------------------------. + | The CPU is in normal operation state; the emulator ran | + | out of clock cycles by fetching a prefix DDh or FDh. | + '=======================================================*/ case Z80_RESUME_XY: RESUME = 0; R++; @@ -2287,10 +2505,10 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) xy->uint16_value = XY; break; - /*----------------------------------------------------------------. - | The CPU is responding to an INT in mode 0; the emulator ran out | - | of clock cycles by fetching a prefix DDh or FDh. | - '================================================================*/ + /*---------------------------------------------------------. + | The CPU is responding to an INT in mode 0; the emulator | + | ran out of clock cycles by fetching a prefix DDh or FDh. | + '=========================================================*/ # ifdef Z80_WITH_FULL_IM0 case Z80_RESUME_IM0_XY: ird = DATA[0]; @@ -2300,6 +2518,15 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) while (self->cycles < self->cycle_limit) /* main execution loop */ { +# ifdef Z80_WITH_RESET_SIGNAL + /* Check external reset signal at the instruction boundary, + matching real Z80 behaviour where /RESET is sampled at the + rising edge of the last T-state. A non-zero value causes + immediate exit before the next instruction fetch. */ + if (self->reset_signal != Z_NULL && (*self->reset_signal & self->reset_signal_mask)) + break; +# endif + if (REQUEST) { /*-------------------------------------------------------------------------. @@ -2329,8 +2556,8 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) | The non-maskable interrupt takes priority over the maskable interrupt | | and cannot be disabled under software control. Its usual function is to | | provide immediate response to important signals. The CPU responds to an | - | NMI by pushing PC onto the stack and jumping to the ISR located at | - | address 0066h. The interrupt enable flip-flop #1 (IFF1) is reset to | + | NMI request by pushing PC onto the stack and jumping to the ISR located | + | at address 0066h. The interrupt enable flip-flop #1 (IFF1) is reset to | | prevent any maskable interrupt from being accepted during the execution | | of this routine, which is usually exited by using a `reti` or `retn` | | instruction to restore the original state of IFF1 [1]. | @@ -2342,17 +2569,17 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) | simulations [3]. | | | | In 2022, Manuel Sainz de Baranda y Goñi discovered that the CPU does not | - | accept a second NMI during the NMI response [4,5]. Therefore, it is not | + | accept a second NMI during the NMI response [4, 5]. Therefore, it is not | | possible to chain two NMI responses in a row without executing at least | - | one instruction between them [3,4,5]. | + | one instruction between them [3]. | | | | References: | | 1. Zilog (1978-05). "Z80 Family Program Interrupt Structure, The", | | pp. 4-5. | | 2. https://baltazarstudios.com/webshare/Z80-undocumented-behavior.htm | | 3. Checked with "Visual Z80 Remix". | - | 4. https://spectrumcomputing.co.uk/forums/viewtopic.php?t=7086 | - | 5. https://stardot.org.uk/forums/viewtopic.php?t=24662 | + | 4. https://spectrumcomputing.co.uk/forums/viewtopic.php?p=91405#p91405 | + | 5. https://stardot.org.uk/forums/viewtopic.php?p=356579#p356579 | '=========================================================================*/ if (REQUEST & Z80_REQUEST_REJECT_NMI) REQUEST = 0; @@ -2373,7 +2600,7 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) PUSH(PC); # endif - PC = MEMPTR = 0x66; + MEMPTR = PC = 0x66; self->cycles += 11; continue; } @@ -2392,11 +2619,11 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) | not accept the maskable interrupt if IFF1 and IFF2 do not have the same | | state prior to the execution of the instruction, which can only be | | caused by an earlier NMI response [1]. This behavior was rediscovered in | - | 2022 by Manuel Sainz de Baranda y Goñi [2,3]. | + | 2022 by Manuel Sainz de Baranda y Goñi [2, 3]. | | | | References: | | 1. Weissflog, Andre (2021-12-17). "New Cycle-Stepped Z80 Emulator, A". | - | * https://floooh.github.io/2021/12/17/cycle-stepped-z80.html | + | * https://floooh.github.io/2021/12/17/cycle-stepped-z80.html | | 2. https://spectrumcomputing.co.uk/forums/viewtopic.php?t=7086 | | 3. https://stardot.org.uk/forums/viewtopic.php?t=24662 | '=========================================================================*/ @@ -2404,9 +2631,10 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) # ifdef Z80_WITH_SPECIAL_RESET (REQUEST & Z80_REQUEST_INT) && # endif - /* if the previous instruction is not `ei` */ + /* If the previous instruction is not `ei` and... */ DATA[0] != 0xFB && - /* if the previous instruction is not `reti/retn` or IFF1 has not changed */ + /* the previous instruction is not `reti/retn`, + or IFF1 has not changed. */ (self->data.uint32_value & Z_UINT32_BIG_ENDIAN(Z_UINT32(0xFFC70100))) != Z_UINT32_BIG_ENDIAN(Z_UINT32(0xED450000)) ) @@ -2419,10 +2647,16 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) REQUEST = IFF1 = IFF2 = 0; if (HALT_LINE) {EXIT_HALT;} - /*-------------------------------------------------------------------. - | Due to a bug, the Zilog Z80 NMOS resets PF when an INT is accepted | - | during the execution of the `ld a,{i|r}` instructions. | - '===================================================================*/ + /*----------------------------------------------------------------------. + | Due to a bug, the Zilog Z80 NMOS resets PF when an INT is accepted | + | during the execution of the `ld a,{i|r}` instructions. | + | | + | References: | + | * Zilog (1989-01). "Z80 Family Data Book", pp. 412-413. | + | * Roshchin, Ivan (1998). "Undocumented Feature of the Z80 Processor". | + | * https://zxpress.ru/article.php?id=7820 | + | * http://code-zx.zxnet-archive.ru/id/123456 | + '======================================================================*/ # ifdef Z80_WITH_ZILOG_NMOS_LD_A_IR_BUG if ( (OPTIONS & Z80_OPTION_LD_A_IR_BUG) && (self->data.uint16_array[0] & Z_UINT16_BIG_ENDIAN(Z_UINT16(0xFFF7))) @@ -2431,18 +2665,17 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) FLAGS = F & ~(zuint8)PF; # endif - /*---------------------------------------------------------------------. - | The INT acknowledge cycle (INTA) indicates that the interrupting I/O | - | device can write to the data bus. 2 wait T-states are automatically | - | added to this M-cycle, allowing sufficient time to identify which | - | device must insert the interrupt response data (IRD). The first and | - | possibly sole byte of the IRD is read from the data bus during this | - | special M1 cycle. | - | | - | The value FFh is assumed when the `Z80::inta` callback is not used. | - | This is the most convenient default IRD, since an `rst 38h` will be | - | executed if the interrupt mode is 0. | - '=====================================================================*/ + /*-----------------------------------------------------------------------. + | The INT acknowledge M-cycle (INTA) indicates that the interrupting I/O | + | device can write to the data bus. The CPU adds 2 wait T-states to this | + | M-cycle, allowing sufficient time to identify which device must insert | + | the interrupt response data (IRD). The first and possibly sole byte of | + | the IRD is read from the data bus during this special M1 cycle. | + | | + | The value FFh is assumed when the `Z80::inta` callback is not used. | + | This is the most convenient default IRD, since an `rst 38h` will be | + | executed if the interrupt mode is 0. | + '=======================================================================*/ R++; ird = (self->inta != Z_NULL) ? self->inta(CONTEXT, PC) : 0xFF; @@ -2450,21 +2683,21 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) PC >>= special_reset; # endif - switch (IM) /* response */ + switch (IM) { /*-------------------------------------------------------------------------. | Interrupt Mode 0: Execute Instruction | T-states: 2*n + instruction | |--------------------------------------------------------------------------| | An instruction supplied via the data bus is executed. Its first byte is | - | read during the INT acknowledge cycle (INTA). If it is an opcode prefix, | - | additional M-cycles of this kind are produced until the final opcode of | - | the instruction is fetched [1]. Each INTA M-cycle takes as many T-states | - | as its normal M1 counterpart (the opcode fetch M-cycle) plus the 2 wait | - | T-states mentioned above [1]. Subsequent bytes of the instruction are | - | fetched by using normal memory read M-cycles [1,2], during which the | - | interrupting I/O device must still supply the data [2]. The PC register, | - | however, remains at its pre-interrupt state, not being incremented as a | - | result of the instruction fetch [1,2]. | + | read during the INTA M-cycle and, if it is an opcode prefix, additional | + | M-cycles of this kind are produced until the final opcode of the | + | instruction is fetched [1]. Each INTA M-cycle takes as many T-states as | + | its normal M1 counterpart (the opcode fetch M-cycle) plus the 2 wait | + | T-states mentioned in the previous comment [1]. Subsequent bytes of the | + | instruction are fetched by using normal memory read M-cycles [1, 2], | + | during which the interrupting I/O device must still supply the data [2]. | + | The PC register, however, remains at its pre-interrupt state, not being | + | incremented as a result of the instruction fetch [1, 2]. | | | | References: | | 1. Checked with "Visual Z80 Remix". | @@ -2484,20 +2717,20 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) hook = self->hook; self->hook = Z_NULL; - /*------------------------------------------------------------------------. - | The `Z80::fetch` callback is temporarily replaced by a trampoline that | - | invokes `Z80::int_fecth`. This trampoline needs to access the callback | - | pointer in addition to the initial, non-incremented value of PC, so the | - | value of `Z80::context` is temporarily replaced by a pointer to an | - | `IM0` object that holds the real context and all this data, which also | - | makes it necessary to replace other callbacks with trampolines so that | - | the real context can be passed to them. | - | | - | The main idea here is that the instruction code will invoke trampolines | - | rather than callbacks, and the one assigned to `Z80::fetch` will ignore | - | the received fetch address, passing instead to `Z80::int_fetch` the | - | initial, non-incremented value of PC. | - '========================================================================*/ + /*-----------------------------------------------------------------------. + | The `Z80::fetch` callback is temporarily replaced with a trampoline | + | that invokes `Z80::int_fetch`. This trampoline needs access to the | + | callback pointer as well as the initial, non-incremented value of PC. | + | To provide this, the value of `Z80::context` is temporarily replaced | + | with a pointer to an `IM0` object that holds the real context and all | + | required data. As a consequence, other callbacks must also be replaced | + | with trampolines so that the real context can be passed to them. | + | | + | The main idea is that the instruction code invokes trampolines rather | + | than callbacks. The trampoline assigned to `Z80::fetch` ignores the | + | received fetch address and passes the initial, non-incremented value | + | of PC to `Z80::int_fetch` instead. | + '=======================================================================*/ im0.z80 = self; im0.context = CONTEXT; im0.fetch = self->fetch; @@ -2515,24 +2748,24 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) im0_execute: - /*------------------------------------------------------------------------. - | `call`, `djnz`, `jr` and `rst` increment PC before pushing it onto the | - | stack or using it as the base address. This makes it necessary to | - | decrement PC before executing any of these instructions so that the | - | final address is correct. `jmp` and `ret` are handled here too because | - | in their case this pre-decrement has no effect and PC must also not be | - | corrected after executing the instruction. These groups of instructions | - | are identified by using a table of decrements. Note that `jmp (XY)` and | - | `reti/retn` are prefixed and will be handled later. | - '========================================================================*/ + /*-----------------------------------------------------------------------. + | `call`, `djnz`, `jr` and `rst` increment PC before pushing it onto the | + | stack or using it as the base address. This makes it necessary to | + | decrement PC before executing any of these instructions so that the | + | final address is correct. `jmp` and `ret` are handled here as well | + | because in this case the pre-decrement has no effect and PC must not | + | be corrected either after executing the instruction. This group of | + | instructions is identified using a table of decrements. Note that | + | `jmp (XY)`, `reti` and `retn` are prefixed and will be handled later. | + '=======================================================================*/ if (im0_pc_decrement_table[ird]) { PC -= im0_pc_decrement_table[ird]; self->cycles += 2 + insn_table[ird](self); } - /* halt */ - else if (ird == 0x76) HALT_LINE = 1; + /* `halt` */ + else if (ird == Z80_HALT) HALT_LINE = 1; /*---------------------------------------------------------------. | Instructions with the CBh prefix are called directly from here | @@ -2545,7 +2778,7 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) self->cycles += 4 + cb_insn_table[DATA[1] = self->inta(im0.context, im0.pc)](self); } - /* Instructions with the EDh prefix */ + /* Instructions with the EDh prefix. */ else if (ird == 0xED) { Insn insn; @@ -2561,7 +2794,7 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) self->ld_i_a = (Z80Notify)im0_ld_i_a; self->ld_r_a = (Z80Notify)im0_ld_r_a; -# ifdef Z80_WITH_RETX_NOTIFICATIONS_IN_IM0 +# ifdef Z80_WITH_IM0_RETX_NOTIFICATIONS self->reti = (Z80Notify)im0_reti; self->retn = (Z80Notify)im0_retn; # else @@ -2570,8 +2803,8 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) # endif PC -= ((ird & 0xC7) == 0x43) - ? 4 /* `ld SS,(WORD)` and `ld (WORD),SS` */ - : 2 /* All others */; + ? 4 /* `ld SS,(WORD)` and `ld (WORD),SS`. */ + : 2 /* All other instructions. */; self->cycles += 4 + insn(self); @@ -2585,12 +2818,12 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) self->cycles += 4 + 8; else { - DATA[2] = 4; + DATA[2] = 4; /* Notify wait T-states. */ self->cycles += 4 + self->illegal(self, ird); } } - /* Instructions with the prefix DDh, FDh, DDCBh or FDCBh */ + /* Instructions with the prefix DDh, FDh, DDCBh or FDCBh. */ else if (IS_XY_PREFIX(ird)) { Insn insn; @@ -2621,11 +2854,12 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) goto im0_execute; } - XY = (xy = &self->ix_iy[((DATA[1] = ird) >> 5) & 1])->uint16_value; + DATA[1] = ird; + XY = (xy = &self->ix_iy[(DATA[0] >> 5) & 1])->uint16_value; self->cycles += 2 + insn(self); xy->uint16_value = XY; - /* Restore PC, except for `jp (XY)` */ + /* Restore PC, except for `jp (XY)`. */ if (ird != 0xE9) PC = im0.pc; } @@ -2657,13 +2891,13 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) # else switch (ird) { - case 0xC3: /* jp WORD */ + case 0xC3: /* `jp WORD` */ Q_0 MEMPTR = PC = int_fetch_16(self); self->cycles += 2 + 10; continue; - case 0xCD: /* call WORD */ + case 0xCD: /* `call WORD` */ Q_0 MEMPTR = int_fetch_16(self); PUSH(PC); @@ -2671,7 +2905,7 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) self->cycles += 2 + 17; continue; - default: /* `rst N` is assumed for all other instructions */ + default: /* `rst N` is assumed for all other instructions. */ Q_0 PUSH(PC); MEMPTR = PC = ird & 56; @@ -2706,9 +2940,9 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) | of the interrupt response vector "must be a zero", since the address | | formed "is used to get two adjacent bytes to form a complete 16-bit | | service routine starting address and the addresses must always start | - | in even locations" [1]. However, Sean Young's experiments confirmed | - | that there is no such limitation [2]; any vector works regardless of | - | whether it is even or odd. | + | in even locations" [1]. However, Sean Young's tests found that there | + | is no such limitation [2]; the CPU fetches the ISR pointer from the | + | specified location regardless of the value of bit 0 of the IRD. | | | | References: | | 1. Zilog (2005-03). "Z80 CPU User Manual" rev. 5, pp. 25-26. | @@ -2734,13 +2968,13 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) | The /HALT line goes low and then high during TLAST if a | | special RESET is detected during the `halt` instruction. | '=========================================================*/ - if (DATA[0] == 0x76 && self->halt != Z_NULL) + if (DATA[0] == Z80_HALT && self->halt != Z_NULL) self->halt(CONTEXT, Z80_HALT_CANCEL); R++; if (self->nop != Z_NULL) (void)self->nop(CONTEXT, PC); DATA[0] = 0; - Q_0; + Q_0 PC = 0; self->cycles += 4; continue; @@ -2749,15 +2983,30 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles) } R++; - self->cycles += insn_table[DATA[0] = FETCH_OPCODE(PC)](self); + +# ifdef Z80_WITH_RESET_SIGNAL + /* Fetch the opcode first (generates M1 bus cycle), then + re-check the reset signal before executing. A real Z80 + checks /RESET at M-cycle boundaries — if /RESET went LOW + during the M1 fetch, the CPU should not execute this + opcode. */ + DATA[0] = FETCH_OPCODE(PC); + + if (self->reset_signal != Z_NULL && (*self->reset_signal & self->reset_signal_mask)) + break; + + self->cycles += insn_table[DATA[0]](self); +# else + self->cycles += insn_table[DATA[0] = FETCH_OPCODE(PC)](self); +# endif } - R = R_ALL; /* Restore R7 bit */ + R = R_ALL; /* Restore R7 bit. */ return self->cycles; } -#ifdef Z80_WITH_WINDOWS_DLL_MAIN +#ifdef Z80_WITH_DLL_MAIN_CRT_STARTUP int Z_MICROSOFT_STD_CALL _DllMainCRTStartup(void *hDllHandle, unsigned long dwReason, void *lpReserved) {return 1;} #endif diff --git a/projects/Z80/sources/Z80.pas b/projects/Z80/sources/Z80.pas index 129bfff..a0feb16 100644 --- a/projects/Z80/sources/Z80.pas +++ b/projects/Z80/sources/Z80.pas @@ -47,7 +47,11 @@ const Z80_MAXIMUM_CYCLES = SizeUInt(SizeUInt(SizeUInt.MaxValue) - 30); Z80_MAXIMUM_CYCLES_PER_STEP = 23; - Z80_HOOK = $64; + Z80_HALT = $76; + Z80_HOOK = $64; + Z80_JP_WORD = $C3; + Z80_NOP = $00; + Z80_RET = $C9; Z80_SF = 128; Z80_ZF = 64; @@ -105,12 +109,12 @@ type xy: TZ80RegisterPair; memptr: TZ80RegisterPair; af: TZ80RegisterPair; - bc: TZ80RegisterPair; - de: TZ80RegisterPair; - hl: TZ80RegisterPair; af_: TZ80RegisterPair; + bc: TZ80RegisterPair; bc_: TZ80RegisterPair; + de: TZ80RegisterPair; de_: TZ80RegisterPair; + hl: TZ80RegisterPair; hl_: TZ80RegisterPair; r: UInt8; i: UInt8; @@ -213,6 +217,12 @@ begin end; +procedure z80_wait(self: PZ80; cycles: SizeUInt); +begin + self^.cycles := self^.cycles + cycles; +end; + + var LibHandle: TLibHandle; diff --git a/projects/Z80/sources/Z80.rc.in b/projects/Z80/sources/Z80.rc.in index c7b5af8..9a00cde 100644 --- a/projects/Z80/sources/Z80.rc.in +++ b/projects/Z80/sources/Z80.rc.in @@ -17,11 +17,11 @@ BEGIN BEGIN BLOCK "040904B0" BEGIN - VALUE "CompanyName", "Manuel Sainz de Baranda y Goñi" + VALUE "CompanyName", "@RC_AUTHOR@" VALUE "FileDescription", "@PROJECT_DESCRIPTION@" VALUE "FileVersion", "@PROJECT_VERSION@" VALUE "InternalName", "@PROJECT_NAME@" - VALUE "LegalCopyright", "Copyright © 1999-2024 Manuel Sainz de Baranda y Goñi" + VALUE "LegalCopyright", "Copyright © @RC_COPYRIGHT_YEAR@ @RC_AUTHOR@" VALUE "OriginalFilename", "@PROJECT_NAME@.dll" VALUE "ProductName", "@PROJECT_NAME@" VALUE "ProductVersion", "@PROJECT_VERSION@" diff --git a/projects/Z80/sources/generate-daa-af-table.c b/projects/Z80/sources/generate-daa-af-table.c new file mode 100644 index 0000000..c6e89d7 --- /dev/null +++ b/projects/Z80/sources/generate-daa-af-table.c @@ -0,0 +1,81 @@ +/* generate-daa-af-table + ______ ______ ______ + /\___ \/\ __ \\ __ \ + ____ \/__/ /\_\ __ \\ \/\ \ ________________________________________________ +| /\_____\\_____\\_____\ | +| Zilog \/_____//_____//_____/ CPU Emulator - `daa` AF Table Generator | +| Copyright (C) 2024-2025 Manuel Sainz de Baranda y Goñi. | +| | +| 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, either version 3 of the License, or (at your option) | +| any later version. | +| | +| 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 . | +| | +'=============================================================================*/ + +#include +#include + + +static zuint8 cpu_fetch_opcode(void *context, zuint16 address) + { + Z_UNUSED(context) Z_UNUSED(address) + return 0x27; /* `daa` */ + } + + +int main(int argc, char **argv) + { + Z80 cpu; + zuint8 hnc, f, x, y; + + Z_UNUSED(argc) Z_UNUSED(argv) + cpu.fetch_opcode = cpu_fetch_opcode; + puts("static zuint16 const daa_af_table[2048] = {"); + + for (hnc = 0; hnc < 8; hnc++) + { + printf( "/* HNC */\n/* %u%u%u\t" + "0\t 1\t 2\t 3\t 4\t 5\t 6\t 7\t" + "8\t 9\t A\t B\t C\t D\t E\t F" + " */\n", + (zuint)( hnc >> 2 ), + (zuint)((hnc >> 1) & 1), + (zuint)( hnc & 1)); + + f = ((hnc << 2) | hnc) & (Z80_HF | Z80_NF | Z80_CF); + + for (y = 0; y < 16; y++) + { + printf("/* %X */", (zuint)y); + + for (x = 0; x < 16; x++) + { + z80_power(&cpu, Z_TRUE); + Z80_F(cpu) = f; + Z80_A(cpu) = y * 16 + x; + z80_execute(&cpu, 1); + + printf( " H(%04X)%s", + (zuint)Z80_AF(cpu), + x == 15 && y == 15 && hnc == 7 + ? "};" : ","); + } + + putchar('\n'); + } + } + + return 0; + } + + +/* generate-daa-af-table.c EOF */ diff --git a/projects/Z80/sources/generate-pf-parity-table.c b/projects/Z80/sources/generate-pf-parity-table.c new file mode 100644 index 0000000..a2dc6fd --- /dev/null +++ b/projects/Z80/sources/generate-pf-parity-table.c @@ -0,0 +1,58 @@ +/* generate-pf-parity-table + ______ ______ ______ + /\___ \/\ __ \\ __ \ + ____ \/__/ /\_\ __ \\ \/\ \ ________________________________________________ +| /\_____\\_____\\_____\ | +| Zilog \/_____//_____//_____/ CPU Emulator - PF Parity Table Generator | +| Copyright (C) 2024-2025 Manuel Sainz de Baranda y Goñi. | +| | +| 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, either version 3 of the License, or (at your option) | +| any later version. | +| | +| 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 . | +| | +'=============================================================================*/ + +#include +#include +#include + + +static Z_ALWAYS_INLINE zuint8 pf_parity(zuint8 value) + {return (zuint8)(((0x9669U >> ((value ^ (value >> 4)) & 0xF)) & 1) << 2);} + + +int main(int argc, char **argv) + { + zuint8 x, y; + + Z_UNUSED(argc) Z_UNUSED(argv) + + puts( "static zuint8 const pf_parity_table[256] = {\n" + "/*\t0 1 2 3 4 5 6 7\t8 9 A B C D E F */"); + + for (y = 0; y < 16; y++) + { + printf("/* %X */", (zuint)y); + + for (x = 0; x < 16; x++) + printf(" %u%s", + (zuint)pf_parity(y * 16 + x), + x == 15 && y == 15 ? "};" : ","); + + putchar('\n'); + } + + return 0; + } + + +/* generate-pf-parity-table.c EOF */ diff --git a/projects/Z80/sources/step-test-Z80.c b/projects/Z80/sources/step-test-Z80.c new file mode 100644 index 0000000..ceefa9c --- /dev/null +++ b/projects/Z80/sources/step-test-Z80.c @@ -0,0 +1,1125 @@ +/* step-test-Z80 + ______ ______ ______ + /\___ \/\ __ \\ __ \ + ____ \/__/ /\_\ __ \\ \/\ \ ________________________________________________ +| /\_____\\_____\\_____\ | +| Zilog \/_____//_____//_____/ CPU Emulator - Step Testing Tool | +| Copyright (C) 2024-2026 Manuel Sainz de Baranda y Goñi. | +| | +| 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, either version 3 of the License, or (at your option) | +| any later version. | +| | +| 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 . | +| | +'=============================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define INPUT_BLOCK_SIZE (Z_USIZE(512) * Z_USIZE(1024)) + + +/* MARK: - Types */ + +typedef struct { + char const *caption; /* Name used in the mismatch reports. */ + char const *key; /* JSON key. */ + zusize offset; /* Offset within the Z80 structure. */ + zuint16 maximum_value; /* Maximum value the member can hold. */ +} Member; + +/*--------------------------------------------------------------------. +| `Cycle` and `Port` store information about a clock cycle and an I/O | +| operation, respectively. These structures are packed to avoid any | +| padding bytes, so that they can be compared using `memcmp`. | +'====================================================================*/ + +typedef Z_PACKED_STRUCTURE_BEGIN { + zuint16 address; /* Value on the address bus. */ + zsint16 value; /* Value on the data bus (-1 = do not check). */ + char pins[4]; /* State of the pins: /RD, WR, /MREQ, /IORQ. */ +} Z_PACKED_STRUCTURE_END Cycle; + +typedef Z_PACKED_STRUCTURE_BEGIN { + zuint16 port; /* I/O port number. */ + zuint8 value; /* Value read from or written to the I/O port. */ + char direction; /* 'r' = read, 'w' = write. */ +} Z_PACKED_STRUCTURE_END Port; + + +/* MARK: - Global Variables */ + +static struct {char const *key; zuint8 options;} const cpu_models[] = { + {"zilog-nmos", Z80_MODEL_ZILOG_NMOS}, + {"zilog-cmos", Z80_MODEL_ZILOG_CMOS}, + {"nec-nmos", Z80_MODEL_NEC_NMOS }}; + +static Member const members[] = { + {"A", "a", Z_MEMBER_OFFSET(Z80, af.uint8_values.at_1 ), Z_UINT8_MAXIMUM }, + {"AF'", "af_", Z_MEMBER_OFFSET(Z80, af_.uint16_value ), Z_UINT16_MAXIMUM}, + {"B", "b", Z_MEMBER_OFFSET(Z80, bc.uint8_values.at_1 ), Z_UINT8_MAXIMUM }, + {"BC'", "bc_", Z_MEMBER_OFFSET(Z80, bc_.uint16_value ), Z_UINT16_MAXIMUM}, + {"C", "c", Z_MEMBER_OFFSET(Z80, bc.uint8_values.at_0 ), Z_UINT8_MAXIMUM }, + {"D", "d", Z_MEMBER_OFFSET(Z80, de.uint8_values.at_1 ), Z_UINT8_MAXIMUM }, + {"DE'", "de_", Z_MEMBER_OFFSET(Z80, de_.uint16_value ), Z_UINT16_MAXIMUM}, + {"E", "e", Z_MEMBER_OFFSET(Z80, de.uint8_values.at_0 ), Z_UINT8_MAXIMUM }, + {"F", "f", Z_MEMBER_OFFSET(Z80, af.uint8_values.at_0 ), Z_UINT8_MAXIMUM }, + {"H", "h", Z_MEMBER_OFFSET(Z80, hl.uint8_values.at_1 ), Z_UINT8_MAXIMUM }, + {"HL'", "hl_", Z_MEMBER_OFFSET(Z80, hl_.uint16_value ), Z_UINT16_MAXIMUM}, + {"I", "i", Z_MEMBER_OFFSET(Z80, i ), Z_UINT8_MAXIMUM }, + {"IFF1", "iff1", Z_MEMBER_OFFSET(Z80, iff1 ), 1 }, + {"IFF2", "iff2", Z_MEMBER_OFFSET(Z80, iff2 ), 1 }, + {"IM", "im", Z_MEMBER_OFFSET(Z80, im ), 2 }, + {"IX", "ix", Z_MEMBER_OFFSET(Z80, ix_iy[0].uint16_value), Z_UINT16_MAXIMUM}, + {"IY", "iy", Z_MEMBER_OFFSET(Z80, ix_iy[1].uint16_value), Z_UINT16_MAXIMUM}, + {"L", "l", Z_MEMBER_OFFSET(Z80, hl.uint8_values.at_0 ), Z_UINT8_MAXIMUM }, + {"PC", "pc", Z_MEMBER_OFFSET(Z80, pc.uint16_value ), Z_UINT16_MAXIMUM}, + {"Q", "q", Z_MEMBER_OFFSET(Z80, q ), Z_UINT8_MAXIMUM }, + {"SP", "sp", Z_MEMBER_OFFSET(Z80, sp.uint16_value ), Z_UINT16_MAXIMUM}, + {"R", "r", Z_MEMBER_OFFSET(Z80, r ), Z_UINT8_MAXIMUM }, + {"WZ", "wz", Z_MEMBER_OFFSET(Z80, memptr.uint16_value ), Z_UINT16_MAXIMUM}, + {"EI", "ei", 0, 1 }, + {"P", "p", 0, 1 }}; + +static Z80 cpu; +static Z80InsnClock insn_clock; +static zuint8 memory[Z_USIZE(65536)]; + +/*----------------------------------------------------------------------------. +| `run` points to the function used to run the emulator: either `z80_execute` | +| or `z80_run`, depending on whether the `--run` option was specified. | +'============================================================================*/ + +#ifdef STEP_TEST_Z80_WITH_EXECUTE + static zusize (* run)(Z80 *self, zusize cycles) = z80_execute; +#endif + +static Cycle* cycles; +static zuint cycles_size; +static zuint cycles_index; +static Port* ports; +static zuint ports_size; +static zuint ports_index; +static cJSON* expected_ports; +static zuint expected_port_count; + +static zbool file_failed, test_failed, array_failed; +static char const *field_separator = ""; + +static zbool cpu_break; + + +/*----------------------------------------------------------------------------. +| `add_cycle` and `add_port` add entries to the lists of recorded cycles and | +| I/O port operations, respectively. If memory reallocation fails, they break | +| the CPU emulation and ignore further entries. | +'============================================================================*/ + +static void add_cycle(zuint16 address, zsint16 value, char const *pins) + { + Cycle *c; + + if (cycles_index == cycles_size) + { + if (cpu_break) return; + cycles_size += Z80_MAXIMUM_CYCLES_PER_STEP; + + if ((c = realloc(cycles, cycles_size * sizeof(Cycle))) == Z_NULL) + { + z80_break(&cpu); + cpu_break = Z_TRUE; + return; + } + + cycles = c; + } + + c = cycles + cycles_index; + c->address = address; + c->value = value; + *(zuint32 *)c->pins = *(zuint32 const *)pins; + cycles_index++; + } + + +static void add_extra_cycles(zuint16 address, zuint8 count) + {while (count--) add_cycle(address, -1, "----");} + + +static void add_port(zuint16 port, zuint8 value, char direction) + { + Port *p; + + if (ports_index == ports_size) + { + if (cpu_break) return; + + if ((p = realloc(ports, ++ports_size * sizeof(Port))) == Z_NULL) + { + z80_break(&cpu); + cpu_break = Z_TRUE; + return; + } + } + + p = ports + ports_index; + p->port = port; + p->value = value; + p->direction = direction; + ports_index++; + } + + +/* MARK: - CPU Callbacks */ + +static zuint8 cpu_fetch_opcode(void *context, zuint16 address) + { + zuint16 refresh_address = z80_refresh_address(&cpu); + zuint8 opcode = memory[address]; + zuint8 extra = z80_insn_clock_extra_m1(&insn_clock, opcode); + + Z_UNUSED(context) + z80_insn_clock_extra_add_m1(&insn_clock, extra); + add_cycle(address, -1, "----"); + add_cycle(address, -1, "r-m-"); + add_cycle(refresh_address, opcode, "----"); + add_cycle(refresh_address, -1, "--m-"); + add_extra_cycles(refresh_address, extra); + return memory[address]; + } + + +static zuint8 cpu_nop(void *context, zuint16 address) + { + zuint16 refresh_address = z80_refresh_address(&cpu); + + Z_UNUSED(context) + add_cycle(address, -1, "----"); + add_cycle(address, -1, "r-m-"); + add_cycle(refresh_address, memory[address], "----"); + add_cycle(refresh_address, -1, "--m-"); + return 0; + } + + +static zuint8 cpu_read(void *context, zuint16 address) + { + zuint8 extra = z80_insn_clock_extra_m(&insn_clock); + + Z_UNUSED(context) + z80_insn_clock_extra_add_m(&insn_clock, extra); + add_cycle(address, -1, "----"); + add_cycle(address, -1, "r-m-"); + add_cycle(address, memory[address], "r-m-"); + add_extra_cycles(address, extra); + return memory[address]; + } + + +static void cpu_write(void *context, zuint16 address, zuint8 value) + { + zuint8 extra = z80_insn_clock_extra_m(&insn_clock); + + Z_UNUSED(context) + z80_insn_clock_extra_add_m(&insn_clock, extra); + add_cycle(address, -1, "----"); + add_cycle(address, value, "--m-"); + add_cycle(address, value, "-wm-"); + add_extra_cycles(address, extra); + memory[address] = value; + } + + +static zuint8 cpu_in(void *context, zuint16 port) + { + zuint8 value = (zuint8)cJSON_GetNumberValue(cJSON_GetArrayItem( + cJSON_GetArrayItem(expected_ports, (int)ports_index), 1)); + + Z_UNUSED(context) + z80_insn_clock_extra_add_in(&insn_clock); + add_cycle(port, -1, "----"); + add_cycle(port, -1, "r--i"); + add_cycle(port, -1, "r--i"); + add_cycle(port, value, "r--i"); + add_port (port, value, 'r'); + return value; + } + + +static void cpu_out(void *context, zuint16 port, zuint8 value) + { + zuint8 extra = z80_insn_clock_extra_out(&insn_clock); + + Z_UNUSED(context) + add_cycle(port, -1, "----"); + add_cycle(port, value, "-w-i"); + add_cycle(port, value, "-w-i"); + add_cycle(port, value, "-w-i"); + add_extra_cycles(port, extra); + add_port (port, value, 'w'); + } + + +/* MARK: - Instruction Clock Callback */ + +static zuint8 insn_clock_read(void *context, zuint16 address) + { + Z_UNUSED(context) + return memory[address]; + } + + +/* MARK: - JSON Validation */ + +static zbool is_number_between(cJSON *number, int minimum, int maximum) + { + double value; + + return cJSON_IsNumber(number) && + (value = cJSON_GetNumberValue(number)) >= minimum && + value <= maximum; + } + + +static zbool validate_test_state(cJSON *state) + { + cJSON *item, *subitem; + Member const *member; + + /* The state object must contain all CPU members plus the `"ram"` array. */ + if ( !cJSON_IsObject(state) || + cJSON_GetArraySize(state) != (int)Z_ARRAY_SIZE(members) + /* "ram" */ 1 || + (item = cJSON_GetObjectItem(state, "ram")) == Z_NULL || + !cJSON_IsArray(item) + ) + return Z_FALSE; + + /* The `"ram"` array must contain arrays of two numbers: 16-bit address and + 8-bit value. */ + cJSON_ArrayForEach(subitem, item) if ( + !cJSON_IsArray(subitem) || + cJSON_GetArraySize(subitem) != 2 || + !is_number_between(cJSON_GetArrayItem(subitem, 0), 0, Z_UINT16_MAXIMUM) || + !is_number_between(cJSON_GetArrayItem(subitem, 1), 0, Z_UINT8_MAXIMUM) + ) + return Z_FALSE; + + /* Each CPU member must be present and hold a valid number according to its type. */ + for (member = members; member != members + Z_ARRAY_SIZE(members) - 2; member++) + if ( (item = cJSON_GetObjectItem(state, member->key)) == Z_NULL || + !is_number_between(item, 0, member->maximum_value) + ) + return Z_FALSE; + + return Z_TRUE; + + /*--------------------------------------------------------------. + | `"ei"` and `"p"` are mutually exclusive, as the previous | + | instruction cannot be `ei` and `ld a,{i|r}` at the same time. | + '============================================================== + return 2.0 != + cJSON_GetNumberValue(cJSON_GetObjectItem(state, "ei")) + + cJSON_GetNumberValue(cJSON_GetObjectItem(state, "p" ));*/ + } + + +static zbool validate_tests(cJSON *tests) + { + cJSON *test; + + if (!cJSON_IsArray(tests)) return Z_FALSE; + cycles_size = ports_size = 0; + + cJSON_ArrayForEach(test, tests) + { + cJSON *item, *array; + int size; + + if ( !cJSON_IsObject(test) || + (item = cJSON_GetObjectItem(test, "name" )) == Z_NULL || + !cJSON_IsString(item) || + (item = cJSON_GetObjectItem(test, "initial")) == Z_NULL || + !validate_test_state(item) || + (item = cJSON_GetObjectItem(test, "final" )) == Z_NULL || + !validate_test_state(item) || + (item = cJSON_GetObjectItem(test, "cycles" )) == Z_NULL || + !cJSON_IsArray(item) || + !(size = cJSON_GetArraySize(item)) + ) + return Z_FALSE; + + if (size > (int)cycles_size) cycles_size = (zuint)size; + + cJSON_ArrayForEach(array, item) + { + cJSON *cycle_item; + char const *pins; + + if ( !cJSON_IsArray(array) || + cJSON_GetArraySize(array) != 3 || + !cJSON_IsNumber(cycle_item = cJSON_GetArrayItem(array, 0)) || + ( !cJSON_IsNumber(cycle_item = cJSON_GetArrayItem(array, 1)) && + !cJSON_IsNull(cycle_item)) || + !cJSON_IsString(cycle_item = cJSON_GetArrayItem(array, 2)) || + strlen(pins = cycle_item->valuestring) != 4 || + (pins[0] != '-' && pins[0] != 'r') || + (pins[1] != '-' && pins[1] != 'w') || + (pins[2] != '-' && pins[2] != 'm') || + (pins[3] != '-' && pins[3] != 'i') + ) + return Z_FALSE; + } + + if ((item = cJSON_GetObjectItem(test, "ports")) != Z_NULL) + { + if (!cJSON_IsArray(item) || !(size = cJSON_GetArraySize(item))) + return Z_FALSE; + + if (size > (int)ports_size) ports_size = (zuint)size; + + cJSON_ArrayForEach(array, item) + { + cJSON *io_item; + + if ( !cJSON_IsArray(array) || + cJSON_GetArraySize(array) != 3 || + !is_number_between(cJSON_GetArrayItem(array, 0), 0, Z_UINT16_MAXIMUM) || + !is_number_between(cJSON_GetArrayItem(array, 1), 0, Z_UINT8_MAXIMUM ) || + !cJSON_IsString(io_item = cJSON_GetArrayItem(array, 2)) || + (strcmp(io_item->valuestring, "r") && strcmp(io_item->valuestring, "w")) + ) + return Z_FALSE; + } + } + } + + return Z_TRUE; + } + + +static void mismatch_found(cJSON *test) + { + if (!file_failed) + { + file_failed = Z_TRUE; + puts("Failed"); + } + + if (!test_failed) + { + test_failed = Z_TRUE; + printf("<%s>", cJSON_GetObjectItem(test, "name")->valuestring); + } + } + + +static zuint16 data_bus_value_to_string(zsint16 value) + { + char string[3]; + + if (value == -1) return (zuint16)('-' | ((zuint16)'-' << 8)); + sprintf(string, "%02X", (zuint)value); + return *(zuint16 *)string; + } + + +static void print_cycle_mismatch(cJSON *test, zuint index, Cycle const *actual, Cycle const *expected) + { + char actual_value[2], expected_value[2]; + + mismatch_found(test); + + if (array_failed) printf(", "); + + else { + array_failed = Z_TRUE; + printf("%s Cycles: [", field_separator); + field_separator = ","; + } + + if (actual != Z_NULL) + *(zuint16 *)actual_value = data_bus_value_to_string(actual ->value); + + if (expected != Z_NULL) + *(zuint16 *)expected_value = data_bus_value_to_string(expected->value); + + printf("%u", index + 1); + + if (actual == Z_NULL) + printf( " ****""/%04X **""/%.2s ****""/%.4s", + expected->address, expected_value, expected->pins); + + else if (expected == Z_NULL) + printf( " %04X/""**** %.2s/""** %.4s/""****", + actual->address, actual_value, actual->pins); + + else { + if (actual->address != expected->address) + printf(" %04X/%04X", actual->address, expected->address); + + if (actual->value != expected->value) + printf(" %.2s/%.2s", actual_value, expected_value); + + if (*(zuint32 const *)actual->pins != *(zuint32 const *)expected->pins) + printf(" %.4s/%.4s", actual->pins, expected->pins); + } + } + + +static void print_port_mismatch(cJSON *test, zuint index, Port const *actual, Port const *expected) + { + mismatch_found(test); + + if (array_failed) printf(", "); + + else { + array_failed = Z_TRUE; + printf("%s Ports: [", field_separator); + field_separator = ","; + } + + printf("%u", index + 1); + + if (actual == Z_NULL) + printf( " ****""/%04X **""/%02X *""/%c", + expected->port, expected->value, expected->direction); + + else if (expected == Z_NULL) + printf( " %04X/""**** %02X/""** %c/""*", + actual->port, actual->value, actual->direction); + + else { + if (actual->port != expected->port) + printf(" %04X/%04X", actual->port, expected->port); + + if (actual->value != expected->value) + printf(" %02X/%02X", actual->value, expected->value); + + if (actual->direction != expected->direction) + printf(" %c/%c", actual->direction, expected->direction); + } + } + + +static void array_check_end(void) + { + if (array_failed) + { + putchar(']'); + array_failed = Z_FALSE; + } + } + + +static Cycle read_cycle_item(cJSON const *item) + { + Cycle cycle; + + *(zuint32 *)cycle.pins = *(zuint32 *)cJSON_GetArrayItem(item, 2)->valuestring; + cycle.address = (zuint16)cJSON_GetNumberValue(cJSON_GetArrayItem(item, 0)); + + cycle.value = cJSON_IsNull(item = cJSON_GetArrayItem(item, 1)) + ? -1 : (zsint16)cJSON_GetNumberValue(item); + + return cycle; + } + + +static Port read_port_item(cJSON const *item) + { + Port port; + + port.port = (zuint16)cJSON_GetNumberValue(cJSON_GetArrayItem(item, 0)); + port.value = (zuint8 )cJSON_GetNumberValue(cJSON_GetArrayItem(item, 1)); + port.direction = *cJSON_GetArrayItem(item, 2)->valuestring; + return port; + } + + +static zbool string_is_option(char const *string, char const *option) + {return (*string == *option && string[1] == '\0') || !strcmp(string, &option[1]);} + + +int main(int argc, char **argv) + { + zbool test_format_and_exit = Z_FALSE; + zbool produce_json_output = Z_FALSE; + zbool test_pins = Z_FALSE; + zbool read_from_stdin = Z_FALSE; + zuint8 verbosity = 2; + int i = 0; + zuint j; + zuint file_count; + zuint read_error_count; + zuint bad_file_count; + zuint passed_file_count; + zuint failed_file_count; + zuint test_count; + zuint passed_test_count; + zuint failed_test_count; + char const *string; + +# define option string +# define invalid string +# define error string + + /* The default CPU model to emulate is Zilog NMOS. */ + cpu.options = Z80_MODEL_ZILOG_NMOS; + + /* Parse command line arguments. */ + while (++i < argc && *argv[i] == '-' && *(option = &argv[i][1]) != '\0') + { + if (string_is_option(option, "V-version")) + { + puts( "step-test-Z80 v" Z80_LIBRARY_VERSION_STRING "\n" + "Copyright (C) 2024-2026 Manuel Sainz de Baranda y Goñi.\n" + "Released under the terms of the GNU General Public License v3."); + + return 0; + } + + else if (string_is_option(option, "h-help")) + { + printf( "Usage: step-test-Z80 [options] ...\n" + "\n" + "Options:\n" + " -V, --version Print version information and exit.\n" + " -h, --help Print this help message and exit.\n" + " -j, --json-output Produce output in JSON format.\n" + " -m, --model Specify the CPU model to emulate.\n" + " -p, --pins Test address bus, data bus and control pins.\n" +# ifdef STEP_TEST_Z80_WITH_EXECUTE + " -r, --run Emulate using `z80_run` instead of `z80_execute`.\n" +# endif + " -t, --test-format Test format of the JSON file(s) and exit.\n" + " -v, --verbosity (0..2) Set the verbosity level [default: 2].\n" + "\n" + "CPU models:\n" + " zilog-nmos Zilog NMOS [default]\n" + " zilog-cmos Zilog CMOS\n" + " nec-nmos NEC NMOS\n" + "\n" + "Email bug reports to \n" + "Open issues at \n"); + + return 0; + } + + else if (string_is_option(option, "j-json-output")) + produce_json_output = Z_TRUE; + + else if (string_is_option(option, "m-model")) + { + if (++i == argc) goto incomplete_option; + + for (j = 0; j < Z_ARRAY_SIZE(cpu_models); j++) + if (!strcmp(argv[i], cpu_models[j].key)) + { + cpu.options = cpu_models[j].options; + goto cpu_model_found; + } + + invalid = "CPU model"; + goto invalid_argument; + cpu_model_found: continue; + } + + else if (string_is_option(option, "p-pins")) + test_pins = Z_TRUE; + +# ifdef STEP_TEST_Z80_WITH_EXECUTE + else if (string_is_option(option, "r-run")) + run = z80_run; +# endif + + else if (string_is_option(option, "t-test-format")) + test_format_and_exit = Z_TRUE; + + else if (string_is_option(option, "v-verbosity")) + { + char *end; + zulong parsed; + + if (++i == argc) goto incomplete_option; + parsed = strtoul(argv[i], &end, 0); + + if (end == argv[i] || *end || parsed > 2) + { + invalid = "verbosity level"; + goto invalid_argument; + } + + verbosity = (zuint8)parsed; + } + + else { + invalid = "option"; + goto invalid_argument; + } + } + + if (!(file_count = (zuint)(argc - i))) + { + fputs("step-test-Z80: No file specified.\n", stderr); + goto bad_syntax; + } + + for (j = (zuint)i; j < (zuint)argc; j++) if (*argv[j] == '\0') + { + i = (int)j; + invalid = "file path"; + goto invalid_argument; + } + + /* Initialize the result counters. */ + read_error_count = + bad_file_count = + passed_file_count = + failed_file_count = + passed_test_count = + failed_test_count = 0; + + /* Initialize the CPU emulator and the instruction clock. */ + cpu.context = Z_NULL; + cpu.fetch_opcode = cpu_fetch_opcode; + cpu.nop = cpu_nop; + cpu.fetch = + cpu.read = cpu_read; + cpu.write = cpu_write; + cpu.in = cpu_in; + cpu.out = cpu_out; + cpu.halt = Z_NULL; + cpu.ld_i_a = + cpu.ld_r_a = + cpu.reti = + cpu.retn = Z_NULL; + cpu.hook = Z_NULL; + cpu.illegal = Z_NULL; + + z80_insn_clock_initialize(&insn_clock, &cpu.af, &cpu.bc, &cpu.hl, Z_NULL, insn_clock_read); + + cycles = Z_NULL; + ports = Z_NULL; + + if (verbosity && !produce_json_output) + setvbuf(stdout, Z_NULL, _IONBF, 0); + + for (; !read_from_stdin && i != argc; i++) + { + cJSON* tests = Z_NULL; + char const* parse_end = Z_NULL; + char* json = Z_NULL; + zusize json_size = 0; + + error = Z_NULL; + + if (argv[i][0] == '-' && argv[i][1] == '\0') + { + zusize buffer_size = 0; + + read_from_stdin = Z_TRUE; + printf("-: "); + + do { + char *buffer = realloc(json, buffer_size += INPUT_BLOCK_SIZE); + + if (buffer == Z_NULL) + { + free(json); + goto cannot_allocate_memory; + } + + json = buffer; + json_size = fread(json + buffer_size - INPUT_BLOCK_SIZE, 1, INPUT_BLOCK_SIZE, stdin); + + if (ferror(stdin)) + { + error = "I/O error"; + break; + } + } + while (!feof(stdin)); + + json_size += buffer_size - INPUT_BLOCK_SIZE; + } + + else { + FILE *file = Z_NULL; + long file_size; + + printf("%s: ", argv[i]); + + if ((file = fopen(argv[i], "r")) == Z_NULL) + error = "Cannot open file"; + + else { + if ( fseek(file, 0, SEEK_END) || + (file_size = ftell(file)) < 0 || + fseek(file, 0, SEEK_SET) + ) + error = "Cannot determine file size"; + + else if ((json_size = (zusize)file_size)) + { + if ((json = malloc(json_size)) == Z_NULL) + { + fclose(file); + goto cannot_allocate_memory; + } + + if (fread(json, json_size, 1, file) != 1) + error = "I/O error"; + } + + fclose(file); + } + } + + if (error != Z_NULL) + { + free(json); + printf("Error: %s\n", error); + read_error_count++; + } + + else if (!json_size) + { + free(json); + invalid_format: + puts("Invalid format"); + bad_file_count++; + } + + else if ((tests = cJSON_ParseWithLengthOpts(json, json_size, &parse_end, Z_FALSE)) == Z_NULL) + { + free(json); + if (parse_end == Z_NULL) goto cannot_allocate_memory; + goto invalid_format; + } + + else { + free(json); + + if (!validate_tests(tests)) + { + cJSON_Delete(tests); + goto invalid_format; + } + + else if (test_format_and_exit) + { + passed_file_count++; + puts("OK"); + } + + else { + cJSON *test; + + if (cycles_size && (cycles = malloc(cycles_size * sizeof(Cycle))) == Z_NULL) + goto cannot_allocate_memory; + + if (ports_size && (ports = malloc(ports_size * sizeof(Port))) == Z_NULL) + goto cannot_allocate_memory; + + file_failed = Z_FALSE; + + cJSON_ArrayForEach(test, tests) + { + cJSON *item, *subitem; + cJSON *initial = cJSON_GetObjectItem(test, "initial"); + cJSON *final = cJSON_GetObjectItem(test, "final" ); + cJSON *expected_cycles = cJSON_GetObjectItem(test, "cycles" ); + zuint expected_cycle_count = (zuint)cJSON_GetArraySize(expected_cycles); + zuint actual, expected; + zuint32 address; + + /* Clean memory, power on CPU and start instruction clock. */ + memset(memory, 0, sizeof(memory)); + z80_power(&cpu, Z_TRUE); + z80_insn_clock_start(&insn_clock, cpu.resume); + + /* Set initial CPU state. */ + for (j = 0; j != Z_ARRAY_SIZE(members) - 2; j++) + { + Member const *member = members + j; + double v = cJSON_GetNumberValue(cJSON_GetObjectItem(initial, member->key)); + + if (member->maximum_value == Z_UINT16_MAXIMUM) + *(zuint16 *)(void *)((char *)&cpu + member->offset) = (zuint16)v; + + else *(zuint8 *)(void *)((char *)&cpu + member->offset) = (zuint8)v; + } + + if (cJSON_GetNumberValue(cJSON_GetObjectItem(initial, "ei")) == 1.0) + cpu.data.uint8_array[0] = 0xFB; /* `ei` */ + + else if (cJSON_GetNumberValue(cJSON_GetObjectItem(initial, "p")) == 1.0) + { + cpu.data.uint8_array[0] = 0xED; /* `ld a,i` */ + cpu.data.uint8_array[1] = 0x57; + } + + /* Set initial memory state. */ + item = cJSON_GetObjectItem(initial, "ram"); + + cJSON_ArrayForEach(subitem, item) memory[ + (zuint16)cJSON_GetNumberValue(cJSON_GetArrayItem(subitem, 0))] = + (zuint8 )cJSON_GetNumberValue(cJSON_GetArrayItem(subitem, 1)); + + cycles_index = ports_index = 0; + + expected_port_count = (expected_ports = cJSON_GetObjectItem(test, "ports")) != Z_NULL + ? (zuint)cJSON_GetArraySize(expected_ports) : 0U; + + /* Run the test. */ + cpu_break = Z_FALSE; + +# ifdef STEP_TEST_Z80_WITH_EXECUTE + run(&cpu, expected_cycle_count); +# else + z80_run(&cpu, expected_cycle_count); +# endif + + if (cpu_break) goto cannot_allocate_memory; + + test_failed = array_failed = Z_FALSE; + field_separator = ""; + + /* Check final CPU state. */ + for (j = 0; j != Z_ARRAY_SIZE(members) - 2; j++) + { + Member const *member = members + j; + + expected = (zuint)cJSON_GetNumberValue(cJSON_GetObjectItem(final, member->key)); + + if (member->maximum_value == Z_UINT16_MAXIMUM) + actual = *(zuint16 *)(void *)((char *)&cpu + member->offset); + + else actual = *(zuint8 *)(void *)((char *)&cpu + member->offset); + + if (actual != expected) + { + mismatch_found(test); + + printf( member->maximum_value == Z_UINT16_MAXIMUM + ? "%s %s: %04X/%04X" + : (member->maximum_value == Z_UINT8_MAXIMUM + ? "%s %s: %02X/%02X" : "%s %s: %u/%u"), + field_separator, member->caption, actual, expected); + + field_separator = ","; + } + } + + if ( (expected = (zuint)cJSON_GetNumberValue(cJSON_GetObjectItem(final, "ei"))) != + (actual = cpu.data.uint8_array[0] == 0xFB) + ) + { + mismatch_found(test); + printf("%s EI: %u/%u", field_separator, actual, expected); + field_separator = ","; + } + + if ( (expected = (zuint)cJSON_GetNumberValue(cJSON_GetObjectItem(final, "p"))) != + (actual = + cpu.data.uint8_array[0] == 0xED && ( + cpu.data.uint8_array[1] == 0x57 || cpu.data.uint8_array[1] == 0x5F)) + ) + { + mismatch_found(test); + printf("%s P: %u/%u", field_separator, cpu.data.uint8_array[0], 0xFBU); + field_separator = ","; + } + + /* Check final memory state. */ + item = cJSON_GetObjectItem(final, "ram"); + + cJSON_ArrayForEach(subitem, item) + { + address = (zuint32)cJSON_GetNumberValue(cJSON_GetArrayItem(subitem, 0)); + actual = memory[address]; + expected = (zuint)cJSON_GetNumberValue(cJSON_GetArrayItem(subitem, 1)); + + if (actual == expected) memory[address] = 0; + else if (!actual) memory[address] = (zuint8)expected; + } + + for (address = 0; address != Z_UINT32(65536); address++) + if (memory[address]) + { + expected = 0; + mismatch_found(test); + + if (array_failed) printf(", "); + + else { + printf("%s RAM: [", field_separator); + array_failed = Z_TRUE; + field_separator = ","; + } + + cJSON_ArrayForEach(subitem, item) + if ((zuint32)cJSON_GetNumberValue(cJSON_GetArrayItem(subitem, 0)) == address) + { + expected = (zuint)cJSON_GetNumberValue(cJSON_GetArrayItem(subitem, 1)); + break; + } + + printf( "%04X %02X/%02X", + address, + memory[address] == expected ? 0U : memory[address], + expected); + } + + array_check_end(); + + /* Check cycles. */ + if (test_pins) + { + for (j = 0; j != expected_cycle_count; j++) + { + Cycle expected_cycle = read_cycle_item(cJSON_GetArrayItem(expected_cycles, (int)j)); + + if (j >= cycles_index) + print_cycle_mismatch(test, j, Z_NULL, &expected_cycle); + + else if (memcmp(cycles + j, &expected_cycle, sizeof(Cycle))) + print_cycle_mismatch(test, j, cycles + j, &expected_cycle); + } + + if (j < cycles_index) + for (; j != cycles_index; j++) + print_cycle_mismatch(test, j, cycles + j, Z_NULL); + + array_check_end(); + } + + else if (cycles_index != expected_cycle_count) + { + mismatch_found(test); + printf( "%s Cycles: %u/%u", field_separator, cycles_index, expected_cycle_count); + field_separator = ","; + } + + /* Check ports. */ + for (j = 0; j != expected_port_count; j++) + { + Port expected_port = read_port_item(cJSON_GetArrayItem(expected_ports, (int)j)); + + if (j >= ports_index) + print_port_mismatch(test, j, Z_NULL, &expected_port); + + else if (memcmp(ports + j, &expected_port, sizeof(Port))) + print_port_mismatch(test, j, ports + j, &expected_port); + } + + if (j < ports_index) + for (; j != ports_index; j++) + print_port_mismatch(test, j, ports + j, Z_NULL); + + array_check_end(); + + if (test_failed) + { + failed_test_count++; + putchar('\n'); + } + + else passed_test_count++; + } + + if (file_failed) failed_file_count++; + + else { + passed_file_count++; + puts("Passed"); + } + } + + cJSON_Delete(tests ); tests = Z_NULL; + free (ports ); ports = Z_NULL; + free (cycles); cycles = Z_NULL; + } + + continue; + + cannot_allocate_memory: + free(ports ); + free(cycles); + if (tests != Z_NULL) cJSON_Delete(tests); + puts("Error"); + fputs("step-test-Z80: Cannot allocate memory.\n", stderr); + return -1; + } + + /* Print the results. */ + printf( "\nResults:%c%u file%s in total", + test_format_and_exit ? ' ' : '\n', + file_count, + file_count > 1 ? "s" : ""); + + if (file_count == 1) printf( + ", %s", + passed_file_count + ? "passed" + : (failed_file_count + ? "failed" + : (bad_file_count ? "invalid" : "unreadable"))); + + else if (file_count == passed_file_count) printf(", all passed" ); + else if (file_count == failed_file_count) printf(", all failed" ); + else if (file_count == bad_file_count ) printf(", all invalid" ); + else if (file_count == read_error_count ) printf(", all unreadable"); + + else { + if (passed_file_count) printf(", %u passed", passed_file_count); + if (failed_file_count) printf(", %u failed", failed_file_count); + if (bad_file_count ) printf(", %u invalid", bad_file_count ); + if (read_error_count ) printf(", %u unreadable", read_error_count ); + } + + if (!test_format_and_exit && (test_count = passed_test_count + failed_test_count)) + { + printf( ".\n%u%s test%s in total", + test_count, + bad_file_count || read_error_count ? " valid" : "", + test_count > 1 ? "s" : ""); + + if (!failed_test_count) printf(",%s passed", passed_test_count > 1 ? " all" : ""); + else if (!passed_test_count) printf(",%s failed", failed_test_count > 1 ? " all" : ""); + else printf(", %u passed, %u failed", passed_test_count, failed_test_count); + } + + puts("."); + return read_error_count + bad_file_count + failed_file_count == 0 ? 0 : -1; + + incomplete_option: + fprintf(stderr, "step-test-Z80: Incomplete option: %s\n", argv[i - 1]); + goto bad_syntax; + + invalid_argument: + if (*argv[i] != '\0') fprintf(stderr, "step-test-Z80: Invalid %s: %s\n", invalid, argv[i]); + else fprintf(stderr, "step-test-Z80: Bad syntax: Empty %s.\n", invalid); + + bad_syntax: + fputs("step-test-Z80: Type 'step-test-Z80 -h' for help.\n", stderr); + return -1; + } + + +/* step-test-Z80.c EOF */ diff --git a/projects/Z80/sources/test-Z80.c b/projects/Z80/sources/test-Z80.c index 2b10294..ab6c2d2 100644 --- a/projects/Z80/sources/test-Z80.c +++ b/projects/Z80/sources/test-Z80.c @@ -4,7 +4,7 @@ ____ \/__/ /\_\ __ \\ \/\ \ ________________________________________________ | /\_____\\_____\\_____\ | | Zilog \/_____//_____//_____/ CPU Emulator - Testing Tool | -| Copyright (C) 2021-2024 Manuel Sainz de Baranda y Goñi. | +| Copyright (C) 2021-2026 Manuel Sainz de Baranda y Goñi. | | | | 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 | @@ -36,44 +36,26 @@ #include -/* MARK: - Macros */ - -#ifdef TEST_Z80_WITH_EXECUTE -# define RUN z80_execute -#else -# define RUN z80_run -#endif - -#define OPCODE_NOP 0x00 -#define OPCODE_RET 0xC9 -#define OPCODE_HALT 0x76 -#define OPCODE_CALL_WORD 0xCD -#define OPCODE_JP_WORD 0xC3 - -#define TEST_FORMAT_CPM 0 /* CP/M program in COM format. */ -#define TEST_FORMAT_HARSTON 1 /* Z80 Instruction Set Exerciser for Spectrum. */ -#define TEST_FORMAT_RAK 2 /* Patrik Rak's Zilog Z80 CPU Test Suite. */ -#define TEST_FORMAT_WOODMASS 3 /* Mark Woodmass' Z80 Test Suite. */ - - /* MARK: - Types */ typedef struct { /* Name of the archive if the file is compressed; `Z_NULL` otherwise. */ - char const* archive_name; + char const *archive_name; /* Name of the file, or path to the file inside the archive if the file - is compressed. */ - char const* file_path; + * is compressed. */ + char const *file_path; /* Total number of clock cycles executed when the test passes. */ zusize cycles[1 + (Z_USIZE_WIDTH < 64)]; /* FNV-1 hash of the entire text output when the test passes - (i.e., of all bytes sent by the program to the print routine). */ + * (i.e., of all bytes sent by the program to the print routine). */ zuint32 hash; - /* Memory address to jump to in order to start executing the program. */ + /* Memory address to jump to in order to start executing the program. + * The lower byte is zeroed to obtain the address where to load the + * executable code. */ zuint16 start_address; /* Value of the PC register once the program completes. */ @@ -98,6 +80,11 @@ typedef struct { zuint8 columns; } Test; +#define TEST_FORMAT_CPM 0 /* CP/M program in COM format. */ +#define TEST_FORMAT_HARSTON 1 /* Z80 Instruction Set Exerciser for Spectrum. */ +#define TEST_FORMAT_RAK 2 /* Patrik Rak's Zilog Z80 CPU Test Suite. */ +#define TEST_FORMAT_WOODMASS 3 /* Mark Woodmass' Z80 Test Suite. */ + /* MARK: - Global Variables */ @@ -118,18 +105,18 @@ static Test const tests[22] = { {"Z80 Instruction Set Exerciser for Spectrum 2 v0.1 (2012-11-27)(Rak, Patrik)[!].zip", "zexall2-0.1/zexall2.tap", CYCLES(C, 18A43876) /* 51,953,023,094 */, Z_UINT32(0x05C746F7), Z_UINT16(0x8000), Z_UINT16(0x8040), 9316, 9228, 87, TEST_FORMAT_HARSTON, 76, 31}, {Z_NULL, "Z80 Test Suite (2008)(Woodmass, Mark)[!].tap", CYCLES(0, 9C3040EF) /* 2,620,408,047 */, Z_UINT32(0xF787CA8E), Z_UINT16(0x8057), Z_UINT16(0x80E6), 5573, 5452, 120, TEST_FORMAT_WOODMASS, 50, 32}, {Z_NULL, "Z80 Test Suite (2008)(Woodmass, Mark)[!].tap", CYCLES(0, 0308BF63) /* 50,904,931 */, Z_UINT32(0xF5AE5140), Z_UINT16(0x8049), Z_UINT16(0x80E6), 5573, 5452, 120, TEST_FORMAT_WOODMASS, 61, 32}, - {"Zilog Z80 CPU Test Suite v1.0 (2012-12-08)(Rak, Patrik)[!].zip", "z80test-1.0/z80full.tap", CYCLES(0, 4303ABF1) /* 1,124,314,097 */, Z_UINT32(0xB8707D12), Z_UINT16(0x8000), Z_UINT16(0x7003), 13758, 13666, 91, TEST_FORMAT_RAK, 156, 32}, - {"Zilog Z80 CPU Test Suite v1.0 (2012-12-08)(Rak, Patrik)[!].zip", "z80test-1.0/z80doc.tap", CYCLES(0, 436E8265) /* 1,131,315,813 */, Z_UINT32(0x9E9DD1F5), Z_UINT16(0x8000), Z_UINT16(0x7003), 13758, 13666, 91, TEST_FORMAT_RAK, 156, 32}, - {"Zilog Z80 CPU Test Suite v1.0 (2012-12-08)(Rak, Patrik)[!].zip", "z80test-1.0/z80flags.tap", CYCLES(0, 20ED11DC) /* 552,407,516 */, Z_UINT32(0x27CB27A2), Z_UINT16(0x8000), Z_UINT16(0x7003), 13758, 13666, 91, TEST_FORMAT_RAK, 156, 32}, - {"Zilog Z80 CPU Test Suite v1.0 (2012-12-08)(Rak, Patrik)[!].zip", "z80test-1.0/z80docflags.tap", CYCLES(0, 2110B9B1) /* 554,744,241 */, Z_UINT32(0x3966C46C), Z_UINT16(0x8000), Z_UINT16(0x7003), 13758, 13666, 91, TEST_FORMAT_RAK, 156, 32}, - {"Zilog Z80 CPU Test Suite v1.0 (2012-12-08)(Rak, Patrik)[!].zip", "z80test-1.0/z80ccf.tap", CYCLES(0, 23AB74CA) /* 598,439,114 */, Z_UINT32(0xB34ED107), Z_UINT16(0x8000), Z_UINT16(0x7003), 14219, 14127, 91, TEST_FORMAT_RAK, 156, 32}, - {"Zilog Z80 CPU Test Suite v1.0 (2012-12-08)(Rak, Patrik)[!].zip", "z80test-1.0/z80memptr.tap", CYCLES(0, 215CF3BD) /* 559,739,837 */, Z_UINT32(0x840ACD96), Z_UINT16(0x8000), Z_UINT16(0x7003), 13758, 13666, 91, TEST_FORMAT_RAK, 156, 32}, - {"Zilog Z80 CPU Test Suite v1.2a (2023-12-02)(Rak, Patrik)[!].zip", "z80test-1.2a/z80full.tap", CYCLES(0, 4382DC6A) /* 1,132,649,578 */, Z_UINT32(0x4C578BC6), Z_UINT16(0x8000), Z_UINT16(0x7003), 14390, 14298, 91, TEST_FORMAT_RAK, 164, 32}, - {"Zilog Z80 CPU Test Suite v1.2a (2023-12-02)(Rak, Patrik)[!].zip", "z80test-1.2a/z80doc.tap", CYCLES(0, 43EE72CE) /* 1,139,700,430 */, Z_UINT32(0x02114A09), Z_UINT16(0x8000), Z_UINT16(0x7003), 14390, 14298, 91, TEST_FORMAT_RAK, 164, 32}, - {"Zilog Z80 CPU Test Suite v1.2a (2023-12-02)(Rak, Patrik)[!].zip", "z80test-1.2a/z80flags.tap", CYCLES(0, 212F17D5) /* 556,734,421 */, Z_UINT32(0x91826856), Z_UINT16(0x8000), Z_UINT16(0x7003), 14390, 14298, 91, TEST_FORMAT_RAK, 164, 32}, - {"Zilog Z80 CPU Test Suite v1.2a (2023-12-02)(Rak, Patrik)[!].zip", "z80test-1.2a/z80docflags.tap", CYCLES(0, 2152FFDA) /* 559,087,578 */, Z_UINT32(0x408190F0), Z_UINT16(0x8000), Z_UINT16(0x7003), 14390, 14298, 91, TEST_FORMAT_RAK, 164, 32}, - {"Zilog Z80 CPU Test Suite v1.2a (2023-12-02)(Rak, Patrik)[!].zip", "z80test-1.2a/z80ccf.tap", CYCLES(0, 23F34E43) /* 603,147,843 */, Z_UINT32(0x27FF6693), Z_UINT16(0x8000), Z_UINT16(0x7003), 14875, 14783, 91, TEST_FORMAT_RAK, 164, 32}, - {"Zilog Z80 CPU Test Suite v1.2a (2023-12-02)(Rak, Patrik)[!].zip", "z80test-1.2a/z80memptr.tap", CYCLES(0, 219FC276) /* 564,118,134 */, Z_UINT32(0xDB7B18AA), Z_UINT16(0x8000), Z_UINT16(0x7003), 14390, 14298, 91, TEST_FORMAT_RAK, 164, 32}}; + {"Zilog Z80 CPU Test Suite v1.0 (2012-12-08)(Rak, Patrik)[!].zip", "z80test-1.0/z80full.tap", CYCLES(0, 4303ABE0) /* 1,124,314,097 */, Z_UINT32(0xB8707D12), Z_UINT16(0x8000), Z_UINT16( 0), 13758, 13666, 91, TEST_FORMAT_RAK, 156, 32}, + {"Zilog Z80 CPU Test Suite v1.0 (2012-12-08)(Rak, Patrik)[!].zip", "z80test-1.0/z80doc.tap", CYCLES(0, 436E8254) /* 1,131,315,813 */, Z_UINT32(0x9E9DD1F5), Z_UINT16(0x8000), Z_UINT16( 0), 13758, 13666, 91, TEST_FORMAT_RAK, 156, 32}, + {"Zilog Z80 CPU Test Suite v1.0 (2012-12-08)(Rak, Patrik)[!].zip", "z80test-1.0/z80flags.tap", CYCLES(0, 20ED11CB) /* 552,407,516 */, Z_UINT32(0x27CB27A2), Z_UINT16(0x8000), Z_UINT16( 0), 13758, 13666, 91, TEST_FORMAT_RAK, 156, 32}, + {"Zilog Z80 CPU Test Suite v1.0 (2012-12-08)(Rak, Patrik)[!].zip", "z80test-1.0/z80docflags.tap", CYCLES(0, 2110B9A0) /* 554,744,241 */, Z_UINT32(0x3966C46C), Z_UINT16(0x8000), Z_UINT16( 0), 13758, 13666, 91, TEST_FORMAT_RAK, 156, 32}, + {"Zilog Z80 CPU Test Suite v1.0 (2012-12-08)(Rak, Patrik)[!].zip", "z80test-1.0/z80ccf.tap", CYCLES(0, 23AB74B9) /* 598,439,114 */, Z_UINT32(0xB34ED107), Z_UINT16(0x8000), Z_UINT16( 0), 14219, 14127, 91, TEST_FORMAT_RAK, 156, 32}, + {"Zilog Z80 CPU Test Suite v1.0 (2012-12-08)(Rak, Patrik)[!].zip", "z80test-1.0/z80memptr.tap", CYCLES(0, 215CF3AC) /* 559,739,837 */, Z_UINT32(0x840ACD96), Z_UINT16(0x8000), Z_UINT16( 0), 13758, 13666, 91, TEST_FORMAT_RAK, 156, 32}, + {"Zilog Z80 CPU Test Suite v1.2a (2023-12-02)(Rak, Patrik)[!].zip", "z80test-1.2a/z80full.tap", CYCLES(0, 4382DC59) /* 1,132,649,578 */, Z_UINT32(0x4C578BC6), Z_UINT16(0x8000), Z_UINT16( 0), 14390, 14298, 91, TEST_FORMAT_RAK, 164, 32}, + {"Zilog Z80 CPU Test Suite v1.2a (2023-12-02)(Rak, Patrik)[!].zip", "z80test-1.2a/z80doc.tap", CYCLES(0, 43EE72BD) /* 1,139,700,430 */, Z_UINT32(0x02114A09), Z_UINT16(0x8000), Z_UINT16( 0), 14390, 14298, 91, TEST_FORMAT_RAK, 164, 32}, + {"Zilog Z80 CPU Test Suite v1.2a (2023-12-02)(Rak, Patrik)[!].zip", "z80test-1.2a/z80flags.tap", CYCLES(0, 212F17C4) /* 556,734,421 */, Z_UINT32(0x91826856), Z_UINT16(0x8000), Z_UINT16( 0), 14390, 14298, 91, TEST_FORMAT_RAK, 164, 32}, + {"Zilog Z80 CPU Test Suite v1.2a (2023-12-02)(Rak, Patrik)[!].zip", "z80test-1.2a/z80docflags.tap", CYCLES(0, 2152FFC9) /* 559,087,578 */, Z_UINT32(0x408190F0), Z_UINT16(0x8000), Z_UINT16( 0), 14390, 14298, 91, TEST_FORMAT_RAK, 164, 32}, + {"Zilog Z80 CPU Test Suite v1.2a (2023-12-02)(Rak, Patrik)[!].zip", "z80test-1.2a/z80ccf.tap", CYCLES(0, 23F34E32) /* 603,147,843 */, Z_UINT32(0x27FF6693), Z_UINT16(0x8000), Z_UINT16( 0), 14875, 14783, 91, TEST_FORMAT_RAK, 164, 32}, + {"Zilog Z80 CPU Test Suite v1.2a (2023-12-02)(Rak, Patrik)[!].zip", "z80test-1.2a/z80memptr.tap", CYCLES(0, 219FC265) /* 564,118,134 */, Z_UINT32(0xDB7B18AA), Z_UINT16(0x8000), Z_UINT16( 0), 14390, 14298, 91, TEST_FORMAT_RAK, 164, 32}}; #undef CYCLES @@ -141,32 +128,36 @@ static struct {char const *key; zuint8 options;} const cpu_models[4] = { static char const new_line[2] = "\n"; +/*----------------------------------------------------------------------------. +| `in_values` holds the bytes returned when reading from I/O ports: | +| [0]: Byte read from even I/O ports (specified with the `--in-even` option). | +| [1]: Byte read from odd I/O ports (specified with the `--in-odd` option). | +| The default values correspond to those of a Sinclair ZX Spectrum 48K with | +| no devices connected. | +'============================================================================*/ + +static zuint8 in_values[2] = {191, 255}; + /*---------------------------------------------------------------------------. -| The search paths specified by using the `-p` option are collected into the | +| The search paths specified with the `--path` option are collected into the | | `search_paths` array of size `search_path_count`. `path_buffer` is used to | -| compose a complete file path consisting of "/". | +| compose complete file paths in the format "/". | '===========================================================================*/ static char* path_buffer = Z_NULL; static char** search_paths = Z_NULL; static zuint search_path_count = 0; -/*-----------------------------------------------------------------------------. -| `verbosity` contains the verbosity level specified by using the `-v` option; | -| `show_test_output` indicates whether to print the text output of the tests. | -'=============================================================================*/ +/*--------------------------------------------------------------------------. +| `verbosity` contains the verbosity level specified with the `--verbosity` | +| option; `show_test_output` indicates whether the text output of the tests | +| should be printed; `test_spacing` points to the string to print between | +| each test: either "\n" or "". | +'==========================================================================*/ -static zuint8 verbosity = 4; -static zboolean show_test_output; - -/*-----------------------------------------------------------------------------. -| [0]: The byte read from even I/O ports (specified by using the `-0` option). | -| [1]: The byte read from odd I/O ports (specified by using the `-1` option). | -| The default values are those of a Sinclair ZX Spectrum 48K with no devices | -| connected. | -'=============================================================================*/ - -static zuint8 in_values[2] = {191, 255}; +static zuint8 verbosity = 4; +static zbool show_test_output; +static char const* test_spacing; /*---------------------------------------------------. | Instance of the Z80 emulator and 64 KiB of memory. | @@ -175,25 +166,37 @@ static zuint8 in_values[2] = {191, 255}; static Z80 cpu; static zuint8 memory[Z_USIZE(65536)]; +/*----------------------------------------------------------------------------. +| `run` points to the function used to run the emulator: either `z80_execute` | +| or `z80_run`, depending on whether the `--run` option was specified. | +'============================================================================*/ + +#ifdef TEST_Z80_WITH_EXECUTE + static zusize (* run)(Z80 *self, zusize cycles) = z80_execute; +# define RUN run +#else +# define RUN z80_run +#endif + /*-----------------------------------------------------------------------------. | `completed` indicates whether the test has reached its exit address; `lines` | -| is incremented every time the test prints a new line; `cursor_x` holds the X | -| position of the cursor in the current line; `columns` contains the rightmost | -| position reached by the cursor throughout the test; and `hash` keeps a FNV-1 | +| is incremented each time the test prints a new line; `cursor_x` holds the X | +| position of the cursor in the current line; `columns` tracks the rightmost | +| position reached by the cursor during the test; and `hash` stores the FNV-1 | | hash of all bytes sent by the test to the print routine. | '=============================================================================*/ -static zboolean completed; -static zusize lines, cursor_x, columns; -static zuint32 hash; +static zbool completed; +static zusize lines, cursor_x, columns; +static zuint32 hash; /*-----------------------------------------------------------------------------. | `zx_spectrum_print_hook_address` contains the address of the hook that | | intercepts the routine called by the test to print characters. When a | | character (17h) is printed, the `zx_spectrum_tab` counter is set to 2 to | -| indicate that it is necessary to process the incoming and | -| bytes before continuing to print characters. `zx_spectrum_bad_character` is | -| set to `Z_TRUE` if the test prints any unsupported control characters. | +| indicate that the incoming and bytes must be processed | +| before continuing to print characters. `zx_spectrum_bad_character` is set to | +| `Z_TRUE` if the test prints any unsupported control characters. | | | | For more information about the TAB control sequence of the ZX Spectrum, see: | | * Sinclair Research (1983). "Sinclair ZX Spectrum BASIC Programming" 2nd | @@ -201,12 +204,23 @@ static zuint32 hash; | * Ardley, Neil (1984). "ZX Spectrum + User Guide" (Dorling Kindersley; | | Sinclair Research. ISBN 0863180809), pp. 67-68. | | | -| These three variables are only used for ZX Spectrum tests. | +| These three variables are used exclusively for ZX Spectrum tests. | '=============================================================================*/ -static zuint16 zx_spectrum_print_hook_address; -static zuint zx_spectrum_tab; -static zboolean zx_spectrum_bad_character; +static zuint16 zx_spectrum_print_hook_address; +static zuint zx_spectrum_tab; +static zbool zx_spectrum_bad_character; + + +/* MARK: - CPU Callbacks: Auxiliary Functions */ + +static void lf(void) + { + if (show_test_output) putchar('\n'); + if (cursor_x > columns) columns = cursor_x; + cursor_x = 0; + lines++; + } /* MARK: - CPU Callbacks: Common */ @@ -237,17 +251,6 @@ static void cpu_halt(void *context, zuint8 state) } -/* MARK: - CPU Callbacks: Auxiliary Functions */ - -static void cr(void) - { - if (show_test_output) putchar('\n'); - if (cursor_x > columns) columns = cursor_x; - cursor_x = 0; - lines++; - } - - /* MARK: - CPU Callbacks: CP/M */ static void cpm_cpu_write(void *context, zuint16 address, zuint8 value) @@ -262,16 +265,16 @@ static zuint8 cpm_cpu_hook(void *context, zuint16 address) zuint8 character; Z_UNUSED(context) - if (address != 5) return OPCODE_NOP; + if (address != 5) return Z80_NOP; /* BDOS function 2 (C_WRITE) - Console output */ if (Z80_C(cpu) == 2) { - hash = Z_FNV1_32_UPDATE(hash, (character = Z80_E(cpu))); + hash = Z_FNV1_32_UPDATE(hash, character = Z80_E(cpu)); switch (character) { - case 0x0A: /* LF */ cr(); + case 0x0A: /* LF */ lf(); case 0x0D: /* CR */ break; default: @@ -288,12 +291,12 @@ static zuint8 cpm_cpu_hook(void *context, zuint16 address) while (c--) { - hash = Z_FNV1_32_UPDATE(hash, (character = memory[i++])); + hash = Z_FNV1_32_UPDATE(hash, character = memory[i++]); switch (character) { - case 0x24: /* $ */ return OPCODE_RET; - case 0x0A: /* LF */ cr(); + case 0x24: /* $ */ return Z80_RET; + case 0x0A: /* LF */ lf(); case 0x0D: /* CR */ break; default: @@ -305,7 +308,7 @@ static zuint8 cpm_cpu_hook(void *context, zuint16 address) if (show_test_output) puts(" [TRUNCATED]"); } - return OPCODE_RET; + return Z80_RET; } @@ -323,13 +326,13 @@ static zuint8 zx_spectrum_cpu_hook(void *context, zuint16 address) zuint8 character; Z_UNUSED(context) - if (address != zx_spectrum_print_hook_address) return OPCODE_NOP; - hash = Z_FNV1_32_UPDATE(hash, (character = Z80_A(cpu))); + if (address != zx_spectrum_print_hook_address) return Z80_NOP; + hash = Z_FNV1_32_UPDATE(hash, character = Z80_A(cpu)); if (!zx_spectrum_tab) switch (character) { - case 0x0D: /* CR */ - cr(); + case 0x0D: /* ENTER */ + lf(); break; case 0x17: /* TAB */ @@ -355,12 +358,12 @@ static zuint8 zx_spectrum_cpu_hook(void *context, zuint16 address) { zuint c = character & (32 - 1), x = cursor_x & (32 - 1); - if (c < x) cr(); + if (c < x) lf(); else cursor_x += (c -= x); if (show_test_output) while (c--) putchar(' '); } - return OPCODE_RET; + return Z80_RET; } @@ -369,9 +372,8 @@ static zuint8 zx_spectrum_cpu_fetch_opcode(void *context, zuint16 address) { Z_UNUSED(context) - return address == 0x0D6B /* THE 'CLS' COMMAND ROUTINE */ || - address == 0x1601 /* THE 'CHAN_OPEN' SUBROUTINE */ - ? OPCODE_RET : memory[address]; + return address == 0x1601 /* 1601: THE 'CHAN_OPEN' SUBROUTINE */ + ? Z80_RET : memory[address]; } @@ -390,23 +392,23 @@ static char const *compose_path(char const *base_path, char const *file_path) } -static zboolean load_file( - char const* search_path, +static zbool load_file( + char const* base_path, char const* file_path, - zuint32 file_size, + zuint16 file_size, zuint16 offset, zuint16 size, void* buffer ) { - zboolean success = Z_FALSE; - FILE *file = fopen(compose_path(search_path, file_path), "rb"); + zbool success = Z_FALSE; + FILE *file = fopen(compose_path(base_path, file_path), "rb"); if (file != Z_NULL) { - if ( !fseek(file, 0, SEEK_END) && - ftell(file) == file_size && - !fseek(file, offset, SEEK_SET) && + if ( !fseek(file, 0, SEEK_END) && + (zulong)ftell(file) == file_size && + !fseek(file, offset, SEEK_SET) && fread(buffer, size, 1, file) == 1 ) success = Z_TRUE; @@ -418,10 +420,10 @@ static zboolean load_file( } -static zboolean load_test(char const *search_path, Test const *test, void *buffer) +static zbool load_test(char const *search_path, Test const *test, void *buffer) { # ifdef TEST_Z80_WITH_ARCHIVE_EXTRACTION - zboolean success = load_file( + zbool success = load_file( search_path, test->file_path, test->file_size, test->code_offset, test->code_size, buffer); @@ -436,35 +438,41 @@ static zboolean load_test(char const *search_path, Test const *test, void *buffe if (gz != Z_NULL) { - union {zuint8 data[Z_TAR_BLOCK_SIZE]; Z_TARPOSIXHeader fields;} header; + union {zuint8 data[Z_TAR_BLOCK_SIZE]; Z_TARPOSIXHeader header;} block; while (!gzeof(gz)) { char *end; - zulong file_size, block_tail_size; + zulong file_size; - if (gzread(gz, header.data, Z_TAR_BLOCK_SIZE) != Z_TAR_BLOCK_SIZE) break; - header.fields.size[Z_ARRAY_SIZE(header.fields.size) - 1] = 0; - file_size = strtoul((char const *)header.fields.size, &end, 8); - if ((zuint8 *)end == header.fields.size || *end) break; + if (gzread(gz, block.data, Z_TAR_BLOCK_SIZE) != Z_TAR_BLOCK_SIZE) break; + block.header.size[Z_ARRAY_SIZE(block.header.size) - 1] = 0; + file_size = strtoul((char const *)block.header.size, &end, 8); + if ((zuint8 *)end == block.header.size || *end) break; - if (!strcmp(test->file_path, (char const *)header.fields.name)) + if (!strcmp(test->file_path, (char const *)block.header.name)) { success = - file_size == test->file_size && - gzseek(gz, test->code_offset, SEEK_CUR) != -1 && - gzread(gz, buffer, test->code_size) == test->code_size; + file_size == test->file_size && + gzseek(gz, (z_off_t)test->code_offset, SEEK_CUR) != -1 && + (zuint)gzread(gz, buffer, test->code_size) == test->code_size; break; } - if (-1 == gzseek(gz, (block_tail_size = (file_size % Z_TAR_BLOCK_SIZE)) - ? file_size + (Z_TAR_BLOCK_SIZE - block_tail_size) - : file_size, SEEK_CUR) + if (file_size % Z_TAR_BLOCK_SIZE) + file_size += Z_TAR_BLOCK_SIZE - (file_size % Z_TAR_BLOCK_SIZE); + + for (; file_size > (zulong)(Z_SINT_MAXIMUM / 2); + file_size -= (zulong)(Z_SINT_MAXIMUM / 2) ) - break; + if (gzseek(gz, (z_off_t)(Z_SINT_MAXIMUM / 2), SEEK_CUR) == -1) + goto close_gz; + + if (gzseek(gz, (z_off_t)file_size, SEEK_CUR) == -1) break; } + close_gz: gzclose(gz); } } @@ -485,7 +493,7 @@ static zboolean load_test(char const *search_path, Test const *test, void *buffe ) { if ( zip_fread(file, buffer, test->code_offset) == test->code_offset && - zip_fread(file, buffer, test->code_size) == test->code_size + zip_fread(file, buffer, test->code_size ) == test->code_size ) success = Z_TRUE; @@ -509,14 +517,14 @@ static zboolean load_test(char const *search_path, Test const *test, void *buffe static zuint8 run_test(int test_index) { - char const *failure = Z_NULL; + char const *failure; Test const *test = &tests[test_index]; zuint16 start_address = test->start_address; - zusize cycles = 0; - zuint i = 0; + zusize cycles; + zuint i; # if Z_USIZE_WIDTH < 64 - zuint32 j = 0; + zuint32 j; # endif if (verbosity) @@ -533,20 +541,17 @@ static zuint8 run_test(int test_index) memset(memory, 0, Z_USIZE(65536)); - for (; i < search_path_count && - !load_test(search_paths[i], test, memory + (start_address & Z_UINT16(0xFF00))); - i++ + for ( i = search_path_count; + i && !load_test(search_paths[i - 1], test, &memory[start_address & Z_UINT16(0xFF00)]); + i-- ); - if ( i == search_path_count && - !load_test(Z_NULL, test, memory + (start_address & Z_UINT16(0xFF00))) - ) + if (!i && !load_test(Z_NULL, test, &memory[start_address & Z_UINT16(0xFF00)])) { + failure = "program"; error_loading_file: - if (verbosity) puts(show_test_output - ? "error, test skipped\n" - : "error, test skipped"); - + if (verbosity > 2) printf("Error\n%s", test_spacing); + else if (verbosity) printf("Error: Cannot load %s\n%s", failure, test_spacing); return Z_FALSE; } @@ -558,39 +563,34 @@ static zuint8 run_test(int test_index) cpu.fetch_opcode = cpu_read; cpu.write = cpm_cpu_write; cpu.hook = cpm_cpu_hook; - memory[0] = OPCODE_HALT; + memory[0] = Z80_HALT; memory[5] = Z80_HOOK; /* PRINT */ } else { - cpu.write = zx_spectrum_cpu_write; - cpu.hook = zx_spectrum_cpu_hook; - cpu.im = 1; - cpu.i = 0x3F; - if (test->format == TEST_FORMAT_WOODMASS) { if (verbosity >= 3) printf("* Loading firmware... "); - for ( i = 0; - i < search_path_count && - !load_file(search_paths[i], "ZX Spectrum.rom", 16384, 0, 16384, memory); - i++ + for ( i = search_path_count; + i && !load_file(search_paths[i - 1], "ZX Spectrum.rom", 16384, 0, 16384, memory); + i-- ); - if ( i == search_path_count && - !load_file(Z_NULL, "ZX Spectrum.rom", 16384, 0, 16384, memory) - ) + if (!i && !load_file(Z_NULL, "ZX Spectrum.rom", 16384, 0, 16384, memory)) + { + failure = "firmware"; goto error_loading_file; + } if (verbosity >= 3) puts("OK"); + + cpu.fetch_opcode = zx_spectrum_cpu_fetch_opcode; Z80_SP(cpu) = 0x7FE8; Z80_AF(cpu) = 0x3222; - cpu.fetch_opcode = zx_spectrum_cpu_fetch_opcode; - /* 0010: THE 'PRINT A CHARACTER' RESTART */ - memory[0x0010] = OPCODE_JP_WORD; /* jp PRINT */ + memory[0x0010] = Z80_JP_WORD; /* jp PRINT */ memory[0x0011] = 0xF2; memory[0x0012] = 0x70; @@ -600,29 +600,24 @@ static zuint8 run_test(int test_index) else { cpu.fetch_opcode = cpu_read; + if (test->format == TEST_FORMAT_RAK) Z80_SP(cpu) -= 2; /* 0010: THE 'PRINT A CHARACTER' RESTART */ memory[zx_spectrum_print_hook_address = 0x0010] = Z80_HOOK; - /* 0D6B: THE 'CLS' COMMAND ROUTINE */ - memory[0x0D6B] = OPCODE_RET; - /* 1601: THE 'CHAN_OPEN' SUBROUTINE */ - memory[0x1601] = OPCODE_RET; - - if (test->format == TEST_FORMAT_RAK) - { - /* 7000: START */ - memory[0x7000] = OPCODE_CALL_WORD; - memory[0x7001] = (zuint8)start_address; - memory[0x7002] = (zuint8)(start_address >> 8); - /*memory[0x7003] = HALT;*/ - start_address = 0x7000; - } + memory[0x1601] = Z80_RET; } + + cpu.write = zx_spectrum_cpu_write; + cpu.hook = zx_spectrum_cpu_hook; + cpu.i = 0x3F; + + /* 0D6B: THE 'CLS' COMMAND ROUTINE */ + memory[0x0D6B] = Z80_RET; } - memory[test->exit_address] = OPCODE_HALT; + memory[test->exit_address] = Z80_HALT; Z80_PC(cpu) = start_address; hash = Z_FNV1_32_INITIALIZER; lines = @@ -635,6 +630,8 @@ static zuint8 run_test(int test_index) if (verbosity >= 3) printf("* Running program%s", show_test_output ? ":\n\n" : "... "); # if Z_USIZE_WIDTH < 64 + j = 0; + for (i = 0; i < test->cycles[1];) { cycles = RUN(&cpu, Z_UINT32_MAXIMUM / 2); @@ -660,10 +657,10 @@ static zuint8 run_test(int test_index) /*--------------------------------------------------------------------. | The test is considered passed if it has reached its exit address at | | the correct clock cycle, has not printed any unsupported characters | - | and has printed the expected output within the correct margins. | + | and has produced the expected output within the correct margins. | '====================================================================*/ - if (!completed) failure = "clock cycle limit exceeded; program aborted"; + if (!completed) failure = "Aborted due to exceeding the clock cycle limit"; else if ( zx_spectrum_bad_character || @@ -671,7 +668,7 @@ static zuint8 run_test(int test_index) lines != test->lines || columns != test->columns ) - failure = "incorrect behavior detected"; + failure = "Incorrect behavior detected"; else if ( # if Z_USIZE_WIDTH < 64 @@ -679,7 +676,9 @@ static zuint8 run_test(int test_index) # endif cycles != test->cycles[0] ) - failure = "incorrect number of clock cycles"; + failure = "Incorrect number of clock cycles"; + + else failure = Z_NULL; if (verbosity) { @@ -690,14 +689,14 @@ static zuint8 run_test(int test_index) if (failure == Z_NULL) puts(&new_line[has_final_new_line]); else printf( - "%s>>> Test failed: %s.\n\n", + "%s> Test failed: %s.\n\n", &new_line[!lines || (completed && has_final_new_line)], failure); } else { - if (failure == Z_NULL) puts ("passed"); - else printf("failed: %s\n", failure); + if (failure == Z_NULL) printf("Passed\n%s", test_spacing); + else printf("Failed: %s\n%s", failure, test_spacing); } } @@ -705,11 +704,11 @@ static zuint8 run_test(int test_index) } -static zboolean string_is_option(char const* string, char const* short_option, char const* long_option) - {return !strcmp(string, short_option) || !strcmp(string, long_option);} +static zbool string_is_option(char const *string, char const *option) + {return (*string == *option && string[1] == '\0') || !strcmp(string, &option[1]);} -static zboolean string_to_uint8(char const* string, zuint8 maximum, zuint8 *value) +static zbool string_to_uint8(char const *string, zuint8 maximum, zuint8 *value) { char *end; zulong parsed = strtoul(string, &end, 0); @@ -722,52 +721,52 @@ static zboolean string_to_uint8(char const* string, zuint8 maximum, zuint8 *valu int main(int argc, char **argv) { - zboolean all = Z_FALSE; - zuint32 tests_run = 0; + zbool all = Z_FALSE; zusize maximum_search_path_size = 0; + zuint32 tests_run; int j, i = 0; + char const *string; - /*--------------------------------------------. - | String specifying what has been detected as | - | invalid when parsing the command line. | - '============================================*/ - char const *invalid; +# define option string +# define invalid string - /*------------------------------. - | [0] = Number of tests failed. | - | [1] = Number of tests passed. | - '==============================*/ + /* [0] = Number of tests failed. [1] = Number of tests passed. */ zuint results[2] = {0, 0}; - /*--------------------------------------------. - | The emulator will behave as a Zilog NMOS if | - | the user does not specify a CPU model. | - '============================================*/ + /* The default CPU model to emulate is Zilog NMOS. */ cpu.options = Z80_MODEL_ZILOG_NMOS; + /* Parse command line arguments. */ while (++i < argc && *argv[i] == '-') { - if (string_is_option(argv[i], "-V", "--version")) + option = &argv[i][1]; + + if (string_is_option(option, "V-version")) { puts( "test-Z80 v" Z80_LIBRARY_VERSION_STRING "\n" - "Copyright (C) 2021-2024 Manuel Sainz de Baranda y Goñi.\n" + "Copyright (C) 2021-2026 Manuel Sainz de Baranda y Goñi.\n" "Released under the terms of the GNU General Public License v3."); goto exit_without_error; } - else if (string_is_option(argv[i], "-h", "--help")) + else if (string_is_option(option, "h-help")) { - puts( "Usage: test-Z80 [options] (--all|...)\n" + puts( "Usage:\n" + " test-Z80 [options] --all [...]\n" + " test-Z80 [options] ...\n" "\n" "Options:\n" " -V, --version Print version information and exit.\n" - " -0, --even-in (0..255) Set the byte read from even I/O ports [default: 191].\n" - " -1, --odd-in (0..255) Set the byte read from odd I/O ports [default: 255].\n" + " -0, --in-even (0..255) Set the byte read from even I/O ports [default: 191].\n" + " -1, --in-odd (0..255) Set the byte read from odd I/O ports [default: 255].\n" " -a, --all Run all tests.\n" " -h, --help Print this help message and exit.\n" " -m, --model Specify the CPU model to emulate.\n" " -p, --path Add a path where to look for the required files.\n" +# ifdef TEST_Z80_WITH_EXECUTE + " -r, --run Emulate using `z80_run` instead of `z80_execute`.\n" +# endif " -v, --verbosity (0..4) Set the verbosity level [default: 4].\n" "\n" "CPU models:\n" @@ -805,28 +804,28 @@ int main(int argc, char **argv) " 20 Tests all flags after executing `ccf` after each instruction.\n" " 21 Tests all flags after executing `bit N,(hl)` after each instruction.\n" "\n" - "Email bug reports and questions to \n" + "Email bug reports to \n" "Open issues at "); goto exit_without_error; } - else if (string_is_option(argv[i], "-0", "--even-in")) + else if (string_is_option(option, "0-in-even")) { if (++i == argc) goto incomplete_option; if (!string_to_uint8(argv[i], 255, &in_values[0])) goto invalid_io_value; } - else if (string_is_option(argv[i], "-1", "--odd-in")) + else if (string_is_option(option, "1-in-odd")) { if (++i == argc) goto incomplete_option; if (!string_to_uint8(argv[i], 255, &in_values[1])) goto invalid_io_value; } - else if (string_is_option(argv[i], "-a", "--all")) + else if (string_is_option(option, "a-all")) all = Z_TRUE; - else if (string_is_option(argv[i], "-m", "--model")) + else if (string_is_option(option, "m-model")) { if (++i == argc) goto incomplete_option; @@ -842,10 +841,10 @@ int main(int argc, char **argv) cpu_model_found: continue; } - else if (string_is_option(argv[i], "-p", "--path")) + else if (string_is_option(option, "p-path")) { - zusize s; char **p; + zusize s; if (++i == argc) goto incomplete_option; @@ -864,7 +863,12 @@ int main(int argc, char **argv) search_paths[search_path_count++] = argv[i]; } - else if (string_is_option(argv[i], "-v", "--verbosity")) +# ifdef TEST_Z80_WITH_EXECUTE + else if (string_is_option(option, "r-run")) + run = z80_run; +# endif + + else if (string_is_option(option, "v-verbosity")) { if (++i == argc) goto incomplete_option; @@ -881,25 +885,25 @@ int main(int argc, char **argv) } } - /*------------------------------------------------. - | The user must specify at least one test number, | - | or the `-a` option in its absence. | - '================================================*/ + /*---------------------------------------------------. + | The user must specify at least one test number or, | + | alternatively, pass the `--all` option. | + '===================================================*/ if (i == argc && !all) { fputs("test-Z80: No test specified.\n", stderr); goto bad_syntax; } - /*------------------------------------------. - | All test numbers specified must be valid. | - '==========================================*/ + /*-----------------------------------------------------. + | All test numbers specified by the user must be valid | + | and must be decimal. Leading zeros are allowed. | + '=====================================================*/ for (j = i; i < argc; i++) { - char const *string = argv[i]; char *end; - if (strtoul(string, &end, 10) >= Z_ARRAY_SIZE(tests) || end == string || *end) + if (strtoul(argv[i], &end, 10) >= Z_ARRAY_SIZE(tests) || end == argv[i] || *end) { invalid = "test number"; goto invalid_argument; @@ -911,27 +915,44 @@ int main(int argc, char **argv) ) { cannot_allocate_memory: - fputs("test-Z80: Cannot allocate memory.", stderr); + fputs("test-Z80: Cannot allocate memory.\n", stderr); goto exit_with_error; } - /*---------------------------------------------------------------. - | Disable output buffering if verbosity is enabled, so that the | - | messages are visible immediately rather than after each ENTER. | - '===============================================================*/ + /*----------------------------------------------------------------. + | Disable buffering on stdout when the verbosity level is greater | + | than 0 to ensure progress messages are displayed immediately. | + '================================================================*/ if (verbosity) setvbuf(stdout, Z_NULL, _IONBF, 0); + + /*--------------------------------------------------------------. + | The output of the test programs is only printed at verbosity | + | level 4. For levels 3 and 4, an additional line feed is added | + | between tests to ensure proper formatting. | + '==============================================================*/ show_test_output = verbosity == 4; + test_spacing = &new_line[verbosity < 3]; - /* Configure the Z80 CPU emulator. */ - - /*---------------------------------------------------------------. - | No CPU context is needed, since we are using global variables. | - '===============================================================*/ - cpu.context = Z_NULL; - - /*---------------------------------------------------. - | No test program requires these optional callbacks. | - '===================================================*/ + /*---------------------------------------------------------------------. + | Initialize the Z80 emulator: | + | * `context` is not needed, as global variables are used. | + | * `fetch` and `read` use the same function because it is unnecessary | + | to distinguish between different types of M-cycles when reading | + | memory, as the test programs do not require precision down to the | + | T-state level. | + | * `nmia`, `inta`, and `int_fetch` will never be called because the | + | test programs do not require interrupts. | + | * `nop`, `ld_i_a`, `ld_r_a`, `reti`, `retn`, and `illegal` are also | + | not needed. | + | * `fetch_opcode`, `write`, and `hook` will be set by `run_test`. | + '=====================================================================*/ + cpu.context = Z_NULL; + cpu.fetch = + cpu.read = cpu_read; + cpu.in = cpu_in; + cpu.out = cpu_out; + cpu.halt = cpu_halt; + cpu.nop = cpu.nmia = cpu.inta = cpu.int_fetch = Z_NULL; @@ -941,44 +962,22 @@ int main(int argc, char **argv) cpu.retn = Z_NULL; cpu.illegal = Z_NULL; - /*------------------------------------------------------------------. - | It is not necessary to distinguish between opcode fetch, internal | - | NOP and memory read, as the test programs require neither precise | - | timing nor memory contention. | - '==================================================================*/ - cpu.fetch = - cpu.read = - cpu.nop = cpu_read; - - cpu.in = cpu_in; - cpu.out = cpu_out; - - /*-------------------------------------------------------------------. - | Entering the HALT state means that the test program has completed. | - '===================================================================*/ - cpu.halt = cpu_halt; - /*------------------------------------------------------------. - | Run the tests whose numbers have been explicitly specified. | + | Run the tests whose numbers have been specified. Then, if | + | the user has passed the `--all` option, run all the others. | '============================================================*/ - while (j < argc) + for (tests_run = 0; j < argc;) { tests_run |= Z_UINT32(1) << (i = atoi(argv[j++])); results[run_test(i)]++; } - /*-----------------------------------------------------. - | If the `-a` option has been specified, run all tests | - | without repeating those that have already been run. | - '=====================================================*/ if (all) for (i = 0; i < (int)Z_ARRAY_SIZE(tests); i++) if (!(tests_run & (Z_UINT32(1) << i))) results[run_test(i)]++; - /*---------------------------. - | Print the results summary. | - '===========================*/ + /* Print the results. */ printf( "%sResults%s: %u test%s passed, %u failed.\n", - &new_line[!verbosity || show_test_output], + &new_line[!verbosity || *test_spacing], show_test_output ? " summary" : "", results[1], results[1] == 1 ? "" : "s", @@ -990,14 +989,15 @@ int main(int argc, char **argv) return results[0] ? -1 : 0; incomplete_option: - fprintf(stderr, "test-Z80: Incomplete option: '%s'\n", argv[i - 1]); + fprintf(stderr, "test-Z80: Incomplete option: %s\n", argv[i - 1]); goto bad_syntax; invalid_io_value: invalid = "I/O value"; invalid_argument: - fprintf(stderr, "test-Z80: Invalid %s: '%s'\n", invalid, argv[i]); + if (*argv[i] != '\0') fprintf(stderr, "test-Z80: Invalid %s: %s\n", invalid, argv[i]); + else fprintf(stderr, "test-Z80: Bad syntax: Empty %s.\n", invalid); bad_syntax: fputs("test-Z80: Type 'test-Z80 -h' for help.\n", stderr); diff --git a/projects/Z80/support/Z80Config.cmake.in b/projects/Z80/support/Z80Config.cmake.in index ec67ebd..3ff7b17 100644 --- a/projects/Z80/support/Z80Config.cmake.in +++ b/projects/Z80/support/Z80Config.cmake.in @@ -1,13 +1,9 @@ -cmake_minimum_required( - # 3.3: IN_LIST - VERSION 3.3...${CMAKE_VERSION}) - -set(@PROJECT_NAME@_known_components Static Shared) +cmake_minimum_required(VERSION 3.0...${CMAKE_VERSION}) set(@PROJECT_NAME@_component_Static NO) set(@PROJECT_NAME@_component_Shared NO) foreach(@PROJECT_NAME@_component IN LISTS ${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS) - if(@PROJECT_NAME@_component IN_LIST @PROJECT_NAME@_known_components) + if(@PROJECT_NAME@_component MATCHES "^(Static|Shared)$") set(@PROJECT_NAME@_component_${@PROJECT_NAME@_component} YES) else() set( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE diff --git a/projects/Zeta/API/Z/classes/Empty.hpp b/projects/Zeta/API/Z/classes/Empty.hpp index 8da1007..f831a4b 100644 --- a/projects/Zeta/API/Z/classes/Empty.hpp +++ b/projects/Zeta/API/Z/classes/Empty.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_Empty_HPP diff --git a/projects/Zeta/API/Z/classes/Functor.hpp b/projects/Zeta/API/Z/classes/Functor.hpp index bf0df1b..dcc9fe1 100644 --- a/projects/Zeta/API/Z/classes/Functor.hpp +++ b/projects/Zeta/API/Z/classes/Functor.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_Functor_HPP @@ -19,13 +19,10 @@ Released under the terms of the GNU Lesser General Public License v3. */ # define Z_HAS_Functor 1 - namespace Zeta { - template class Functor; template class Functor { - private: typedef r (* Call)(const Functor *, typename Type

::to_forwardable...); typedef void (* Destroy)(Functor *); @@ -46,9 +43,9 @@ Released under the terms of the GNU Lesser General Public License v3. */ # endif } target; - struct Callers { + static Z_INLINE Call function() Z_NOTHROW { return [](const Functor *functor, typename Type

::to_forwardable... arguments) -> r @@ -79,11 +76,13 @@ Released under the terms of the GNU Lesser General Public License v3. */ }; } # endif + + }; - public: + Z_CT(CPP11) Functor() Z_NOTHROW : call(Z_NULL), destroy(Z_NULL) {} @@ -134,7 +133,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ # if Z_HAS(TypeIsConvertible) - template ::is_class && TypeIsConvertible::value @@ -142,12 +140,10 @@ Released under the terms of the GNU Lesser General Public License v3. */ Z_INLINE Functor(const o &object) Z_NOTHROW : call(Callers::function()), destroy(Z_NULL) {target.function = (r(*)(p...))object;} // TODO: cast - # endif # if Z_HAS(ObjectSelector) - Z_INLINE Functor(id object, SEL selector) Z_NOTHROW : call(Callers::object_selector()), destroy(Z_NULL) { @@ -162,7 +158,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ target.object_selector.selector = object_selector.selector; target.object_selector.object = object_selector.object; } - # endif @@ -170,16 +165,16 @@ Released under the terms of the GNU Lesser General Public License v3. */ {if (destroy) destroy(this);} - Z_CT(CPP11) operator Boolean() const Z_NOTHROW + Z_CT(CPP11) operator Bool() const Z_NOTHROW {return call != Z_NULL;} Z_INLINE r operator ()(typename Type

::to_forwardable... arguments) const {return call(this, arguments...);} + + }; } - - #endif #endif // Z_classes_Functor_HPP diff --git a/projects/Zeta/API/Z/classes/InitializerList.hpp b/projects/Zeta/API/Z/classes/InitializerList.hpp index 42d7366..3238c0e 100644 --- a/projects/Zeta/API/Z/classes/InitializerList.hpp +++ b/projects/Zeta/API/Z/classes/InitializerList.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_InitializerList_HPP @@ -18,7 +18,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ # define Z_HAS_InitializerList 1 - namespace Zeta {template class InitializerList { public: typedef t value_type; diff --git a/projects/Zeta/API/Z/classes/Iterator.hpp b/projects/Zeta/API/Z/classes/Iterator.hpp index 8aed31c..637acb3 100644 --- a/projects/Zeta/API/Z/classes/Iterator.hpp +++ b/projects/Zeta/API/Z/classes/Iterator.hpp @@ -3,13 +3,12 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_Iterator_HPP #define Z_classes_Iterator_HPP - namespace Zeta{template struct Iterator { t& data_source; typename t::size_type index; @@ -19,7 +18,7 @@ namespace Zeta{template struct Iterator { : data_source(data_source_), index(index_) {} - friend Z_CT(CPP11) Boolean operator !=(const Iterator &lhs, const Iterator &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator !=(const Iterator &lhs, const Iterator &rhs) Z_NOTHROW {return lhs.index != rhs.index;} @@ -32,7 +31,8 @@ namespace Zeta{template struct Iterator { index++; return *this; } + + };} - #endif // Z_classes_Iterator_HPP diff --git a/projects/Zeta/API/Z/classes/MemberFunction.hpp b/projects/Zeta/API/Z/classes/MemberFunction.hpp index 191569e..8b1484c 100644 --- a/projects/Zeta/API/Z/classes/MemberFunction.hpp +++ b/projects/Zeta/API/Z/classes/MemberFunction.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_MemberFunction_HPP @@ -20,7 +20,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ # include # include - namespace Zeta { template struct MemberFunction; @@ -46,7 +45,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ : function(reinterpret_cast(function)) {} - Z_CT(CPP11) operator Boolean() const Z_NOTHROW + Z_CT(CPP11) operator Bool() const Z_NOTHROW {return function != Z_NULL;} @@ -78,6 +77,8 @@ Released under the terms of the GNU Lesser General Public License v3. */ template Z_INLINE r operator ()(const o &object, typename Type

::to_forwardable... arguments) const {return (const_cast(reinterpret_cast(&object))->*function)(arguments...);} + + }; } #endif diff --git a/projects/Zeta/API/Z/classes/NaT.hpp b/projects/Zeta/API/Z/classes/NaT.hpp index 0a269bd..f99a6fd 100644 --- a/projects/Zeta/API/Z/classes/NaT.hpp +++ b/projects/Zeta/API/Z/classes/NaT.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_NaT_HPP @@ -11,7 +11,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ #include - namespace Zeta {struct NaT Z_FINAL { # if Z_DIALECT_HAS(CPP11, DELETED_FUNCTION) NaT() = delete; @@ -26,5 +25,4 @@ namespace Zeta {struct NaT Z_FINAL { # endif };} - #endif // Z_classes_NaT_HPP diff --git a/projects/Zeta/API/Z/classes/ObjectMemberFunction.hpp b/projects/Zeta/API/Z/classes/ObjectMemberFunction.hpp index 8c92186..de59468 100644 --- a/projects/Zeta/API/Z/classes/ObjectMemberFunction.hpp +++ b/projects/Zeta/API/Z/classes/ObjectMemberFunction.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_ObjectMemberFunction_HPP @@ -15,7 +15,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ #if Z_HAS(MemberFunction) # define Z_HAS_ObjectMemberFunction 1 - namespace Zeta { template struct ObjectMemberFunction; @@ -141,6 +140,8 @@ Released under the terms of the GNU Lesser General Public License v3. */ this->object = const_cast(reinterpret_cast(&object)); return *this; } + + }; } #endif diff --git a/projects/Zeta/API/Z/classes/ObjectSelector.hpp b/projects/Zeta/API/Z/classes/ObjectSelector.hpp index 19e4c33..caebafa 100644 --- a/projects/Zeta/API/Z/classes/ObjectSelector.hpp +++ b/projects/Zeta/API/Z/classes/ObjectSelector.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_ObjectSelector_HPP @@ -15,7 +15,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ #if Z_HAS(Selector) # define Z_HAS_ObjectSelector 1 - namespace Zeta { template struct ObjectSelector; @@ -87,6 +86,8 @@ Released under the terms of the GNU Lesser General Public License v3. */ this->object = object; return *this; } + + }; } #endif diff --git a/projects/Zeta/API/Z/classes/OpaqueMemberFunctionPointer.hpp b/projects/Zeta/API/Z/classes/OpaqueMemberFunctionPointer.hpp index 50b33f7..7c3d462 100644 --- a/projects/Zeta/API/Z/classes/OpaqueMemberFunctionPointer.hpp +++ b/projects/Zeta/API/Z/classes/OpaqueMemberFunctionPointer.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_OpaqueMemberFunctionPointer_HPP @@ -11,7 +11,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ #include - namespace Zeta {struct OpaqueMemberFunctionPointer { void (NaT::* value)(); @@ -24,7 +23,8 @@ namespace Zeta {struct OpaqueMemberFunctionPointer { template Z_INLINE operator m() const Z_NOTHROW {return reinterpret_cast(value);} + + };} - #endif // Z_classes_OpaqueMemberFunctionPointer_HPP diff --git a/projects/Zeta/API/Z/classes/Pair.hpp b/projects/Zeta/API/Z/classes/Pair.hpp index 3f190d1..23b8ffd 100644 --- a/projects/Zeta/API/Z/classes/Pair.hpp +++ b/projects/Zeta/API/Z/classes/Pair.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_Pair_HPP @@ -12,7 +12,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ #include #include - namespace Zeta {template struct Pair { typedef t1 First; typedef t2 Second; @@ -20,19 +19,21 @@ namespace Zeta {template struct Pair { t1 first; t2 second; + Z_INLINE Pair() Z_DEFAULTED({}) + Z_CT(CPP11) Pair( typename Type::to_forwardable first, typename Type::to_forwardable second ) : first(first), second(second) {} - Z_CT(CPP11) Boolean operator ==(const Pair &pair) const + Z_CT(CPP11) Bool operator ==(const Pair &pair) const {return first == pair.first && second == pair.second;} - Z_CT(CPP11) Boolean operator !=(const Pair &pair) const + Z_CT(CPP11) Bool operator !=(const Pair &pair) const {return first != pair.first || second != pair.second;} @@ -42,7 +43,8 @@ namespace Zeta {template struct Pair { reinterpret_cast::to_opaque *>(this), reinterpret_cast::to_opaque *>(&pair)); }*/ + + };} - #endif // Z_classes_Pair_HPP diff --git a/projects/Zeta/API/Z/classes/Range.hpp b/projects/Zeta/API/Z/classes/Range.hpp index cd320a4..d363601 100644 --- a/projects/Zeta/API/Z/classes/Range.hpp +++ b/projects/Zeta/API/Z/classes/Range.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_Range_HPP @@ -15,7 +15,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ # import #endif - namespace Zeta {template struct Range { t index, size; @@ -32,15 +31,15 @@ namespace Zeta {template struct Range { : index(index_), size(size_) {} - Z_CT(CPP11) operator Boolean() const Z_NOTHROW + Z_CT(CPP11) operator Bool() const Z_NOTHROW {return !!size;} - friend Z_CT(CPP11) Boolean operator ==(const Range &lhs, const Range &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator ==(const Range &lhs, const Range &rhs) Z_NOTHROW {return lhs.index == rhs.index && lhs.size == rhs.size;} - friend Z_CT(CPP11) Boolean operator !=(const Range &lhs, const Range &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator !=(const Range &lhs, const Range &rhs) Z_NOTHROW {return lhs.index != rhs.index || lhs.size != rhs.size;} @@ -89,11 +88,11 @@ namespace Zeta {template struct Range { Z_CT(CPP11) t operator [](t index_) const Z_NOTHROW {return index + index_;} - Z_CT(CPP11) Boolean contains(const Range &other) const Z_NOTHROW + Z_CT(CPP11) Bool contains(const Range &other) const Z_NOTHROW {return other.index >= index && other.end() <= end();} - Z_CT(CPP11) Boolean contains(t index_) const Z_NOTHROW + Z_CT(CPP11) Bool contains(t index_) const Z_NOTHROW {return index_ >= index && index_ < end();} @@ -101,25 +100,22 @@ namespace Zeta {template struct Range { {return index + size;} - Z_CT(CPP11) Boolean intersects(const Range &other) const Z_NOTHROW + Z_CT(CPP11) Bool intersects(const Range &other) const Z_NOTHROW {return index < other.end() && other.index < end();} - Z_CT(CPP11) Boolean is_zero() const Z_NOTHROW + Z_CT(CPP11) Bool is_zero() const Z_NOTHROW {return !index && !size;} # if defined(Z_WITH_FOUNDATION) && Z_LANGUAGE_INCLUDES(OBJECTIVE_CPP) - Z_CT(CPP11) Range(const NSRange &range) Z_NOTHROW : index(t(range.location)), size(t(range.length)) {} # if Z_DIALECT_HAS(CPP11, COPY_LIST_INITIALIZATION) - Z_CT(CPP11) operator NSRange() const Z_NOTHROW {return {NSUInteger(index), NSUInteger(size)};} - # else Z_CT(CPP14) operator NSRange() const Z_NOTHROW { @@ -127,8 +123,9 @@ namespace Zeta {template struct Range { return result; } # endif - # endif + + };} diff --git a/projects/Zeta/API/Z/classes/Rectangle.hpp b/projects/Zeta/API/Z/classes/Rectangle.hpp index d1baae8..e7c56c0 100644 --- a/projects/Zeta/API/Z/classes/Rectangle.hpp +++ b/projects/Zeta/API/Z/classes/Rectangle.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_Rectangle_HPP @@ -27,7 +27,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ # include #endif - namespace Zeta {template struct Rectangle { XY point, size; @@ -93,15 +92,15 @@ namespace Zeta {template struct Rectangle { } - Z_CT(CPP11) operator Boolean() const Z_NOTHROW + Z_CT(CPP11) operator Bool() const Z_NOTHROW {return point || size;} - friend Z_CT(CPP11) Boolean operator ==(const Rectangle &lhs, const Rectangle &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator ==(const Rectangle &lhs, const Rectangle &rhs) Z_NOTHROW {return lhs.point == rhs.point && lhs.size == rhs.size;} - friend Z_CT(CPP11) Boolean operator !=(const Rectangle &lhs, const Rectangle &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator !=(const Rectangle &lhs, const Rectangle &rhs) Z_NOTHROW {return lhs.point != rhs.point || lhs.size != rhs.size;} @@ -348,7 +347,7 @@ namespace Zeta {template struct Rectangle { - Z_CT(CPP11) Boolean contains(const Rectangle &other) const Z_NOTHROW + Z_CT(CPP11) Bool contains(const Rectangle &other) const Z_NOTHROW { return !other.size.has_zero() && other.point >= point && @@ -356,7 +355,7 @@ namespace Zeta {template struct Rectangle { } - Z_CT(CPP11) Boolean contains(const XY &point_) const Z_NOTHROW + Z_CT(CPP11) Bool contains(const XY &point_) const Z_NOTHROW {return point_ >= point && point_ < point + size;} @@ -502,7 +501,7 @@ namespace Zeta {template struct Rectangle { {return Rectangle(point.x, point.y - delta, size.x, size.y + delta);} - Z_CT(CPP11) Boolean intersects(const Rectangle &other) const Z_NOTHROW + Z_CT(CPP11) Bool intersects(const Rectangle &other) const Z_NOTHROW { return !size.has_zero() && !other.size.has_zero() && @@ -511,7 +510,7 @@ namespace Zeta {template struct Rectangle { } - Z_CT(CPP11) Boolean is_zero() const Z_NOTHROW + Z_CT(CPP11) Bool is_zero() const Z_NOTHROW {return point.is_zero() && size.is_zero();} @@ -638,21 +637,17 @@ namespace Zeta {template struct Rectangle { {return point + point_ * size;} - # ifdef Z_WITH_COCOS2D_X - Z_INLINE Rectangle(const cocos2d::Rect &rectangle) : point(rectangle.origin), size(rectangle.size) {} Z_INLINE operator cocos2d::Rect() const {return cocos2d::Rect(float(point.x), float(point.y), float(size.x), float(size.y));} - # endif # if defined(Z_WITH_CORE_FOUNDATION) || defined(Z_WITH_FOUNDATION) - # define Z_z_APPLE_CONSTRUCTORS(Prefix) \ \ Z_CT(CPP11) Rectangle(const Prefix##Rect &rectangle) Z_NOTHROW \ @@ -708,12 +703,10 @@ namespace Zeta {template struct Rectangle { # undef Z_z_APPLE_CONSTRUCTORS # undef Z_z_APPLE_OPERATORS - # endif # ifdef Z_WITH_QT - Z_CT(CPP11) Rectangle(const QRect &rectangle) Z_NOTHROW : point(rectangle.topLeft()), size(rectangle.size()) {} @@ -728,9 +721,9 @@ namespace Zeta {template struct Rectangle { Z_CT(CPP11) operator QRect() const Z_NOTHROW {return QRect(int(point.x), int(point.y), int(size.x), int(size.y));} - # endif + + };} - #endif // Z_classes_Rectangle_HPP diff --git a/projects/Zeta/API/Z/classes/Reference.hpp b/projects/Zeta/API/Z/classes/Reference.hpp index 87c1217..aa89bd6 100644 --- a/projects/Zeta/API/Z/classes/Reference.hpp +++ b/projects/Zeta/API/Z/classes/Reference.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_Reference_HPP @@ -11,7 +11,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ #include - namespace Zeta {template struct Reference { typedef t type; @@ -33,7 +32,8 @@ namespace Zeta {template struct Reference { Z_CT(CPP11) t &get() const Z_NOTHROW {return *value;} + + };} - #endif // Z_classes_Span_HPP diff --git a/projects/Zeta/API/Z/classes/Selector.hpp b/projects/Zeta/API/Z/classes/Selector.hpp index 39d93a0..5fc01db 100644 --- a/projects/Zeta/API/Z/classes/Selector.hpp +++ b/projects/Zeta/API/Z/classes/Selector.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_Selector_HPP @@ -24,11 +24,9 @@ Released under the terms of the GNU Lesser General Public License v3. */ # define Z_HAS_Selector 1 - namespace Zeta { template struct Selector; - template struct Selector { typedef r (* Send )(id, SEL, p...); @@ -70,9 +68,10 @@ Released under the terms of the GNU Lesser General Public License v3. */ return (SendSuper(ObjectiveC::send_super())) (const_cast(&object_super), selector, arguments...); } - }; + }; + # if Z_DIALECT_HAS(CPP11, RVALUE_REFERENCE) template struct Selector { @@ -118,11 +117,11 @@ Released under the terms of the GNU Lesser General Public License v3. */ return (SendSuper(ObjectiveC::send_super())) (const_cast(&object_super), selector, forwardable(arguments)...); } + + }; # endif } - - #endif #endif // Z_classes_Selector_HPP diff --git a/projects/Zeta/API/Z/classes/Shared.hpp b/projects/Zeta/API/Z/classes/Shared.hpp index 96fa8ab..43f8784 100644 --- a/projects/Zeta/API/Z/classes/Shared.hpp +++ b/projects/Zeta/API/Z/classes/Shared.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_Shared_HPP @@ -14,9 +14,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ #include #include - namespace Zeta {template struct Shared { - struct Owned { t* data; USize owner_count; @@ -29,6 +27,7 @@ namespace Zeta {template struct Shared { Z_INLINE ~Owned() {delete data;} + }; Owned *owned; @@ -50,8 +49,8 @@ namespace Zeta {template struct Shared { {if (owned && !--owned->owner_count) delete owned;} - Z_INLINE operator Boolean() const Z_NOTHROW - {return Boolean(owned);} + Z_INLINE operator Bool() const Z_NOTHROW + {return Bool(owned);} Z_INLINE Shared &operator =(const Shared &rhs) @@ -79,11 +78,11 @@ namespace Zeta {template struct Shared { } - friend Z_INLINE Boolean operator ==(const Shared &lhs, const Shared &rhs) Z_NOTHROW + friend Z_INLINE Bool operator ==(const Shared &lhs, const Shared &rhs) Z_NOTHROW {return lhs.owned == rhs.owned;} - friend Z_INLINE Boolean operator !=(const Shared &lhs, const Shared &rhs) Z_NOTHROW + friend Z_INLINE Bool operator !=(const Shared &lhs, const Shared &rhs) Z_NOTHROW {return lhs.owned != rhs.owned;} @@ -120,7 +119,6 @@ namespace Zeta {template struct Shared { # ifdef Z_NULLPTR - Z_CT(CPP11) Shared(NullPtr) Z_NOTHROW : owned(nullptr) {} @@ -133,26 +131,24 @@ namespace Zeta {template struct Shared { } - friend Z_INLINE Boolean operator ==(const Shared &lhs, NullPtr) Z_NOTHROW + friend Z_INLINE Bool operator ==(const Shared &lhs, NullPtr) Z_NOTHROW {return !lhs.owned;} - friend Z_INLINE Boolean operator ==(NullPtr, const Shared &rhs) Z_NOTHROW + friend Z_INLINE Bool operator ==(NullPtr, const Shared &rhs) Z_NOTHROW {return !rhs.owned;} - friend Z_INLINE Boolean operator !=(const Shared &lhs, NullPtr) Z_NOTHROW + friend Z_INLINE Bool operator !=(const Shared &lhs, NullPtr) Z_NOTHROW {return !!lhs.owned;} - friend Z_INLINE Boolean operator !=(NullPtr, const Shared &rhs) Z_NOTHROW + friend Z_INLINE Bool operator !=(NullPtr, const Shared &rhs) Z_NOTHROW {return !!rhs.owned;} - # endif # if Z_DIALECT_HAS(CPP11, RVALUE_REFERENCE) - Z_INLINE Shared(Shared &&other) Z_NOTHROW : owned(other.owned) {other.owned = Z_NULL;} @@ -169,9 +165,9 @@ namespace Zeta {template struct Shared { return *this; } - # endif + + };} - #endif // Z_classes_Shared_HPP diff --git a/projects/Zeta/API/Z/classes/SizedString.hpp b/projects/Zeta/API/Z/classes/SizedString.hpp index ab58095..829f493 100644 --- a/projects/Zeta/API/Z/classes/SizedString.hpp +++ b/projects/Zeta/API/Z/classes/SizedString.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_SizedString_HPP @@ -12,12 +12,9 @@ Released under the terms of the GNU Lesser General Public License v3. */ #include #include - namespace Zeta{namespace ZetaDetail { - template > struct SizedString; - template struct SizedString > { t data[s]; @@ -29,12 +26,14 @@ namespace Zeta{namespace ZetaDetail { Z_CT(CPP11) SizedString(const StringView &string_view) Z_NOTHROW : data{string_view.data[i]..., 0} {} + + }; }} - namespace Zeta{template struct SizedString : ZetaDetail::SizedString { + Z_CT(CPP11) SizedString(const t (&string)[s]) Z_NOTHROW : ZetaDetail::SizedString(string) {} @@ -49,7 +48,8 @@ namespace Zeta{template struct SizedString : ZetaDetail::Size Z_CT(CPP11) const t &operator [](USize index) const Z_NOTHROW {return this->data[index];} + + };} - #endif // Z_classes_SizedString_HPP diff --git a/projects/Zeta/API/Z/classes/Span.hpp b/projects/Zeta/API/Z/classes/Span.hpp index d25300f..cc6b872 100644 --- a/projects/Zeta/API/Z/classes/Span.hpp +++ b/projects/Zeta/API/Z/classes/Span.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_Span_HPP @@ -13,7 +13,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ #include #include - namespace Zeta {template struct Span { typedef const t* const_pointer; typedef const t& const_reference; @@ -72,7 +71,8 @@ namespace Zeta {template struct Span { Z_CT(CPP11) Iterator end() const Z_NOTHROW {return Iterator(*this, size);}*/ + + };} - #endif // Z_classes_Span_HPP diff --git a/projects/Zeta/API/Z/classes/Strid.hpp b/projects/Zeta/API/Z/classes/Strid.hpp index b081762..2287480 100644 --- a/projects/Zeta/API/Z/classes/Strid.hpp +++ b/projects/Zeta/API/Z/classes/Strid.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_Strid_HPP @@ -11,7 +11,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ #include - namespace Zeta {struct Strid { UInt64 hash; @@ -32,29 +31,30 @@ namespace Zeta {struct Strid { {return hash;} - friend Z_CT(CPP11) Boolean operator ==(const Strid &lhs, const Strid &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator ==(const Strid &lhs, const Strid &rhs) Z_NOTHROW {return lhs.hash == rhs.hash;} - friend Z_CT(CPP11) Boolean operator ==(const Strid &lhs, UInt64 rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator ==(const Strid &lhs, UInt64 rhs) Z_NOTHROW {return lhs.hash == rhs;} - friend Z_CT(CPP11) Boolean operator ==(UInt64 lhs, const Strid &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator ==(UInt64 lhs, const Strid &rhs) Z_NOTHROW {return lhs == rhs.hash;} - friend Z_CT(CPP11) Boolean operator !=(const Strid &lhs, const Strid &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator !=(const Strid &lhs, const Strid &rhs) Z_NOTHROW {return lhs.hash != rhs.hash;} - friend Z_CT(CPP11) Boolean operator !=(const Strid &lhs, UInt64 rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator !=(const Strid &lhs, UInt64 rhs) Z_NOTHROW {return lhs.hash != rhs;} - friend Z_CT(CPP11) Boolean operator !=(UInt64 lhs, const Strid &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator !=(UInt64 lhs, const Strid &rhs) Z_NOTHROW {return lhs != rhs.hash;} + + };} - #endif // Z_classes_Strid_HPP diff --git a/projects/Zeta/API/Z/classes/StringView.hpp b/projects/Zeta/API/Z/classes/StringView.hpp index 44ef887..de5121f 100644 --- a/projects/Zeta/API/Z/classes/StringView.hpp +++ b/projects/Zeta/API/Z/classes/StringView.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_StringView_HPP @@ -61,52 +61,51 @@ namespace Zeta {template struct StringView { # ifdef Z_WITH_STDCPP - - friend Z_INLINE Boolean operator ==(const StringView &lhs, const StringView &rhs) Z_NOTHROW + friend Z_INLINE Bool operator ==(const StringView &lhs, const StringView &rhs) Z_NOTHROW {return lhs.size == rhs.size && !std::memcmp(lhs.data, rhs.data, lhs.size * sizeof(t));} - friend Z_INLINE Boolean operator !=(const StringView &lhs, const StringView &rhs) Z_NOTHROW + friend Z_INLINE Bool operator !=(const StringView &lhs, const StringView &rhs) Z_NOTHROW {return lhs.size != rhs.size || std::memcmp(lhs.data, rhs.data, lhs.size * sizeof(t));} template - friend Z_INLINE Boolean operator ==(const StringView &lhs, const t (&rhs)[s]) Z_NOTHROW + friend Z_INLINE Bool operator ==(const StringView &lhs, const t (&rhs)[s]) Z_NOTHROW {return lhs.size == (s - 1) && !std::memcmp(lhs.data, rhs, (s - 1) * sizeof(t));} template - friend Z_INLINE Boolean operator !=(const StringView &lhs, const t (&rhs)[s]) Z_NOTHROW + friend Z_INLINE Bool operator !=(const StringView &lhs, const t (&rhs)[s]) Z_NOTHROW {return lhs.size != (s - 1) || std::memcmp(lhs.data, rhs, (s - 1) * sizeof(t));} - friend Z_INLINE Boolean operator ==(const StringView &lhs, const t *rhs) Z_NOTHROW + friend Z_INLINE Bool operator ==(const StringView &lhs, const t *rhs) Z_NOTHROW {return lhs.size * sizeof(t) == std::strlen(rhs) && !std::memcmp(lhs.data, rhs, lhs.size * sizeof(t));} - friend Z_INLINE Boolean operator !=(const StringView &lhs, const t *rhs) Z_NOTHROW + friend Z_INLINE Bool operator !=(const StringView &lhs, const t *rhs) Z_NOTHROW {return lhs.size * sizeof(t) != std::strlen(rhs) || std::memcmp(lhs.data, rhs, lhs.size * sizeof(t));} template - friend Z_INLINE Boolean operator ==(const t (&lhs)[s], const StringView &rhs) Z_NOTHROW + friend Z_INLINE Bool operator ==(const t (&lhs)[s], const StringView &rhs) Z_NOTHROW {return rhs.size == (s - 1) && !std::memcmp(rhs.data, lhs, (s - 1) * sizeof(t));} template - friend Z_INLINE Boolean operator !=(const t (&lhs)[s], const StringView &rhs) Z_NOTHROW + friend Z_INLINE Bool operator !=(const t (&lhs)[s], const StringView &rhs) Z_NOTHROW {return rhs.size != (s - 1) || std::memcmp(rhs.data, lhs, (s - 1) * sizeof(t));} - friend Z_INLINE Boolean operator ==(const t *lhs, const StringView &rhs) Z_NOTHROW + friend Z_INLINE Bool operator ==(const t *lhs, const StringView &rhs) Z_NOTHROW {return rhs.size * sizeof(t) == std::strlen(lhs) && !std::memcmp(rhs.data, lhs, rhs.size * sizeof(t));} - friend Z_INLINE Boolean operator !=(const t *lhs, const StringView &rhs) Z_NOTHROW + friend Z_INLINE Bool operator !=(const t *lhs, const StringView &rhs) Z_NOTHROW {return rhs.size * sizeof(t) != std::strlen(lhs) || std::memcmp(rhs.data, lhs, rhs.size * sizeof(t));} - # endif + + };} - #endif // Z_classes_StringView_HPP diff --git a/projects/Zeta/API/Z/classes/TripleBuffer.hpp b/projects/Zeta/API/Z/classes/TripleBuffer.hpp index 43b9cef..767d224 100644 --- a/projects/Zeta/API/Z/classes/TripleBuffer.hpp +++ b/projects/Zeta/API/Z/classes/TripleBuffer.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_TripleBuffer_HPP @@ -15,9 +15,9 @@ Released under the terms of the GNU Lesser General Public License v3. */ #include #include - namespace Zeta {struct TripleBuffer : ZTripleBuffer { + Z_INLINE TripleBuffer() Z_NOTHROW Z_DEFAULTED({}) @@ -101,7 +101,8 @@ namespace Zeta {struct TripleBuffer : ZTripleBuffer { Z_CT(CPP11) UChar production_index() const Z_NOTHROW {return (f & 48) >> 4;} + + };} - #endif // Z_classes_TripleBuffer_HPP diff --git a/projects/Zeta/API/Z/classes/Tuple.hpp b/projects/Zeta/API/Z/classes/Tuple.hpp index 4151aac..d9944e9 100644 --- a/projects/Zeta/API/Z/classes/Tuple.hpp +++ b/projects/Zeta/API/Z/classes/Tuple.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_Tuple_HPP @@ -16,38 +16,37 @@ Released under the terms of the GNU Lesser General Public License v3. */ # define Z_HAS_Tuple 1 - namespace Zeta {namespace ZetaDetail {namespace Tuple { - template struct Element; - template struct Super { typedef Element, 1>::type> type; }; - template struct Element > { typedef t0 type; type value; + Z_INLINE Element() Z_DEFAULTED({}) Z_CT(CPP11) Element(typename Zeta::Type::to_forwardable value) : value(value) {} - }; + }; + template struct Element > : Super::type { typedef tn type; type value; + Z_INLINE Element() Z_DEFAULTED({}) @@ -56,17 +55,17 @@ Released under the terms of the GNU Lesser General Public License v3. */ typename Zeta::Type::to_forwardable... previous, typename Zeta::Type::to_forwardable value ) : Super::type(previous...), value(value) {} + + }; }}} - namespace Zeta {template class Tuple : public ZetaDetail::Tuple::Super::type { private: typedef typename ZetaDetail::Tuple::Super::type Super; public: template class At { - private: enum {tail_size = TypeCount::value - (i + 1)}; @@ -78,10 +77,10 @@ Released under the terms of the GNU Lesser General Public License v3. */ typedef typename Element::type type; }; - # if !Z_DIALECT_HAS(CPP11, INHERITING_CONSTRUCTORS) using Super::Super; + # else Z_INLINE Tuple() Z_DEFAULTED({}) @@ -108,9 +107,10 @@ Released under the terms of the GNU Lesser General Public License v3. */ At::Element::value = value; return *this; } - };} + };} + # if defined(Z_WITH_STD) && \ Z_DIALECT_HAS(CPP17, STRUCTURED_BINDING) && \ defined(__has_include) && \ @@ -118,6 +118,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ # include + # define Z_z_IMPLEMENTATION(qualifiers) \ \ template \ @@ -130,6 +131,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ typedef typename Zeta::Type::template At::type>::add_const type; \ }; + Z_z_IMPLEMENTATION(Z_EMPTY ) Z_z_IMPLEMENTATION(const ) Z_z_IMPLEMENTATION(const volatile) @@ -137,7 +139,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ # undef Z_z_IMPLEMENTATION # endif - #endif #endif // Z_classes_Tuple_HPP diff --git a/projects/Zeta/API/Z/classes/XY.hpp b/projects/Zeta/API/Z/classes/XY.hpp index ecb8edb..86d304e 100644 --- a/projects/Zeta/API/Z/classes/XY.hpp +++ b/projects/Zeta/API/Z/classes/XY.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_XY_HPP @@ -31,12 +31,13 @@ Released under the terms of the GNU Lesser General Public License v3. */ namespace Zeta {template struct XYZ;} - namespace Zeta {template struct XY { t x, y; + Z_INLINE XY() Z_NOTHROW Z_DEFAULTED({}) + Z_CT(CPP11) XY(t x_, t y_) Z_NOTHROW : x(x_), y(y_) {} @@ -58,31 +59,31 @@ namespace Zeta {template struct XY { # endif - Z_CT(CPP11) operator Boolean() const Z_NOTHROW + Z_CT(CPP11) operator Bool() const Z_NOTHROW {return x != t(0) || y != t(0);} - friend Z_CT(CPP11) Boolean operator ==(const XY &lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator ==(const XY &lhs, const XY &rhs) Z_NOTHROW {return lhs.x == rhs.x && lhs.y == rhs.y;} - friend Z_CT(CPP11) Boolean operator !=(const XY &lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator !=(const XY &lhs, const XY &rhs) Z_NOTHROW {return lhs.x != rhs.x || lhs.y != rhs.y;} - friend Z_CT(CPP11) Boolean operator >=(const XY &lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >=(const XY &lhs, const XY &rhs) Z_NOTHROW {return lhs.x >= rhs.x && lhs.y >= rhs.y;} - friend Z_CT(CPP11) Boolean operator <=(const XY &lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <=(const XY &lhs, const XY &rhs) Z_NOTHROW {return lhs.x <= rhs.x && lhs.y <= rhs.y;} - friend Z_CT(CPP11) Boolean operator >(const XY &lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >(const XY &lhs, const XY &rhs) Z_NOTHROW {return lhs.x > rhs.x && lhs.y > rhs.y;} - friend Z_CT(CPP11) Boolean operator <(const XY &lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <(const XY &lhs, const XY &rhs) Z_NOTHROW {return lhs.x < rhs.x && lhs.y < rhs.y;} @@ -102,27 +103,27 @@ namespace Zeta {template struct XY { {return XY(lhs.x / rhs.x, lhs.y / rhs.y);} - friend Z_CT(CPP11) Boolean operator ==(const XY &lhs, t rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator ==(const XY &lhs, t rhs) Z_NOTHROW {return lhs.x == rhs && lhs.y == rhs;} - friend Z_CT(CPP11) Boolean operator !=(const XY &lhs, t rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator !=(const XY &lhs, t rhs) Z_NOTHROW {return lhs.x != rhs || lhs.y != rhs;} - friend Z_CT(CPP11) Boolean operator >=(const XY &lhs, t rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >=(const XY &lhs, t rhs) Z_NOTHROW {return lhs.x >= rhs && lhs.y >= rhs;} - friend Z_CT(CPP11) Boolean operator <=(const XY &lhs, t rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <=(const XY &lhs, t rhs) Z_NOTHROW {return lhs.x <= rhs && lhs.y <= rhs;} - friend Z_CT(CPP11) Boolean operator >(const XY &lhs, t rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >(const XY &lhs, t rhs) Z_NOTHROW {return lhs.x > rhs && lhs.y > rhs;} - friend Z_CT(CPP11) Boolean operator <(const XY &lhs, t rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <(const XY &lhs, t rhs) Z_NOTHROW {return lhs.x < rhs && lhs.y < rhs;} @@ -142,27 +143,27 @@ namespace Zeta {template struct XY { {return XY(lhs.x / rhs, lhs.y / rhs);} - friend Z_CT(CPP11) Boolean operator ==(t lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator ==(t lhs, const XY &rhs) Z_NOTHROW {return lhs == rhs.x && lhs == rhs.y;} - friend Z_CT(CPP11) Boolean operator !=(t lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator !=(t lhs, const XY &rhs) Z_NOTHROW {return lhs != rhs.x || lhs != rhs.y;} - friend Z_CT(CPP11) Boolean operator >=(t lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >=(t lhs, const XY &rhs) Z_NOTHROW {return lhs >= rhs.x && lhs >= rhs.y;} - friend Z_CT(CPP11) Boolean operator <=(t lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <=(t lhs, const XY &rhs) Z_NOTHROW {return lhs <= rhs.x && lhs <= rhs.y;} - friend Z_CT(CPP11) Boolean operator >(t lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >(t lhs, const XY &rhs) Z_NOTHROW {return lhs > rhs.x && lhs > rhs.y;} - friend Z_CT(CPP11) Boolean operator <(t lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <(t lhs, const XY &rhs) Z_NOTHROW {return lhs < rhs.x && lhs < rhs.y;} @@ -232,7 +233,7 @@ namespace Zeta {template struct XY { } - Z_CT(CPP11) Boolean has_zero() const Z_NOTHROW + Z_CT(CPP11) Bool has_zero() const Z_NOTHROW {return x == t(0) || y == t(0);} @@ -256,7 +257,7 @@ namespace Zeta {template struct XY { {return x + y;} - Z_CT(CPP11) Boolean is_zero() const Z_NOTHROW + Z_CT(CPP11) Bool is_zero() const Z_NOTHROW {return x == t(0) && y == t(0);} @@ -278,16 +279,15 @@ namespace Zeta {template struct XY { // MARK: - Signed - Z_CT(CPP11) XY absolute() const Z_NOTHROW {return XY(Zeta::absolute(x), Zeta::absolute(y));} - Z_CT(CPP11) Boolean has_negative() const Z_NOTHROW + Z_CT(CPP11) Bool has_negative() const Z_NOTHROW {return x < t(0) || y < t(0);} - Z_CT(CPP11) Boolean is_negative() const Z_NOTHROW + Z_CT(CPP11) Bool is_negative() const Z_NOTHROW {return x < t(0) && y < t(0);} @@ -297,31 +297,29 @@ namespace Zeta {template struct XY { // MARK: - Integer - -// Z_CT(CPP11) Boolean is_perpendicular(const XY &other) const Z_NOTHROW +// Z_CT(CPP11) Bool is_perpendicular(const XY &other) const Z_NOTHROW // {return !Zeta::absolute(dot_product(other));} // MARK: - Real - Z_CT(CPP11) XY clamp_01() const Z_NOTHROW {return XY(Zeta::clamp_01(x), Zeta::clamp_01(y));} - Z_CT(CPP11) Boolean has_almost_zero() const Z_NOTHROW + Z_CT(CPP11) Bool has_almost_zero() const Z_NOTHROW {return Zeta::is_almost_zero(x) || Zeta::is_almost_zero(y);} - Z_CT(CPP11) Boolean has_finite() const Z_NOTHROW + Z_CT(CPP11) Bool has_finite() const Z_NOTHROW {return Zeta::is_finite(x) || Zeta::is_finite(y);} - Z_CT(CPP11) Boolean has_infinity() const Z_NOTHROW + Z_CT(CPP11) Bool has_infinity() const Z_NOTHROW {return Zeta::is_infinity(x) || Zeta::is_infinity(y);} - Z_CT(CPP11) Boolean has_nan() const Z_NOTHROW + Z_CT(CPP11) Bool has_nan() const Z_NOTHROW {return Zeta::is_nan(x) || Zeta::is_nan(y);} @@ -333,30 +331,30 @@ namespace Zeta {template struct XY { } - Z_CT(CPP11) Boolean is_almost_equal(const XY &other) const Z_NOTHROW + Z_CT(CPP11) Bool is_almost_equal(const XY &other) const Z_NOTHROW { return Zeta::are_almost_equal(x, other.x) && Zeta::are_almost_equal(y, other.y); } - Z_CT(CPP11) Boolean is_almost_zero() const Z_NOTHROW + Z_CT(CPP11) Bool is_almost_zero() const Z_NOTHROW {return Zeta::is_almost_zero(x) && Zeta::is_almost_zero(y);} - Z_CT(CPP11) Boolean is_finite() const Z_NOTHROW + Z_CT(CPP11) Bool is_finite() const Z_NOTHROW {return Zeta::is_finite(x) && Zeta::is_finite(y);} - Z_CT(CPP11) Boolean is_infinity() const Z_NOTHROW + Z_CT(CPP11) Bool is_infinity() const Z_NOTHROW {return Zeta::is_infinity(x) && Zeta::is_infinity(y);} - Z_CT(CPP11) Boolean is_nan() const Z_NOTHROW + Z_CT(CPP11) Bool is_nan() const Z_NOTHROW {return Zeta::is_nan(x) && Zeta::is_nan(y);} - Z_CT(CPP11) Boolean is_perpendicular(const XY &other) const Z_NOTHROW + Z_CT(CPP11) Bool is_perpendicular(const XY &other) const Z_NOTHROW {return Zeta::absolute(dot_product(other)) <= Type::epsilon();} @@ -373,7 +371,6 @@ namespace Zeta {template struct XY { # if defined(Z_WITH_CORE_FOUNDATION) || defined(Z_WITH_FOUNDATION) - # define Z_z_APPLE_CONSTRUCTORS(Prefix) \ \ Z_CT(CPP11) XY(const Prefix##Point &point) Z_NOTHROW \ @@ -385,7 +382,6 @@ namespace Zeta {template struct XY { # if Z_DIALECT_HAS(CPP11, COPY_LIST_INITIALIZATION) - # define Z_z_APPLE_OPERATORS(Prefix) \ \ Z_CT(CPP11) operator Prefix##Point() const Z_NOTHROW \ @@ -399,6 +395,7 @@ namespace Zeta {template struct XY { Z_CT(CPP11) operator Prefix##Rect() const Z_NOTHROW \ {return {{0.0, 0.0}, {CGFloat(x), CGFloat(y)}};} + # else # define Z_z_APPLE_OPERATORS(Prefix) \ \ @@ -441,12 +438,10 @@ namespace Zeta {template struct XY { # undef Z_z_APPLE_CONSTRUCTORS # undef Z_z_APPLE_OPERATORS - # endif # ifdef Z_WITH_COCOS2D_X - Z_CT(CPP11) XY(const cocos2d::Vec2 &point) Z_NOTHROW : x(point.x), y(point.y) {} @@ -465,12 +460,10 @@ namespace Zeta {template struct XY { Z_INLINE operator cocos2d::Rect() const Z_NOTHROW {return cocos2d::Rect(0.0f, 0.0f, float(x), float(y));} - # endif # ifdef Z_WITH_QT - Z_CT(CPP11) XY(const QPoint &point) Z_NOTHROW : x(t(point.x())), y(t(point.y())) {} @@ -489,11 +482,11 @@ namespace Zeta {template struct XY { Z_CT(CPP11) operator QRect() const Z_NOTHROW {return QRect(0, 0, int(x), int(y));} - # endif -};} +};} + #ifndef Z_classes_XYZ_HPP # include #endif diff --git a/projects/Zeta/API/Z/classes/XYZ.hpp b/projects/Zeta/API/Z/classes/XYZ.hpp index ddc0680..e76963c 100644 --- a/projects/Zeta/API/Z/classes/XYZ.hpp +++ b/projects/Zeta/API/Z/classes/XYZ.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_XYZ_HPP @@ -13,13 +13,13 @@ Released under the terms of the GNU Lesser General Public License v3. */ # include #endif - namespace Zeta {template struct XYZ { t x, y, z; Z_INLINE XYZ() Z_NOTHROW Z_DEFAULTED({}) + Z_CT(CPP11) XYZ(t x_, t y_, t z_) Z_NOTHROW : x(x_), y(y_), z(z_) {} @@ -53,31 +53,31 @@ namespace Zeta {template struct XYZ { # endif - Z_CT(CPP11) operator Boolean() const Z_NOTHROW + Z_CT(CPP11) operator Bool() const Z_NOTHROW {return x != t(0) || y != t(0) || z != t(0);} - friend Z_CT(CPP11) Boolean operator ==(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator ==(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW {return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z;} - friend Z_CT(CPP11) Boolean operator !=(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator !=(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW {return lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != rhs.z;} - friend Z_CT(CPP11) Boolean operator >=(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >=(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW {return lhs.x >= rhs.x && lhs.y >= rhs.y && lhs.z >= rhs.z;} - friend Z_CT(CPP11) Boolean operator <=(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <=(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW {return lhs.x <= rhs.x && lhs.y <= rhs.y && lhs.z <= rhs.z;} - friend Z_CT(CPP11) Boolean operator >(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW {return lhs.x > rhs.x && lhs.y > rhs.y && lhs.z > rhs.z;} - friend Z_CT(CPP11) Boolean operator <(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW {return lhs.x < rhs.x && lhs.y < rhs.y && lhs.z < rhs.z;} @@ -97,27 +97,27 @@ namespace Zeta {template struct XYZ { {return XYZ(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z);} - friend Z_CT(CPP11) Boolean operator ==(const XYZ &lhs, t rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator ==(const XYZ &lhs, t rhs) Z_NOTHROW {return lhs.x == rhs && lhs.y == rhs && lhs.z == rhs;} - friend Z_CT(CPP11) Boolean operator !=(const XYZ &lhs, t rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator !=(const XYZ &lhs, t rhs) Z_NOTHROW {return lhs.x != rhs || lhs.y != rhs || lhs.z != rhs;} - friend Z_CT(CPP11) Boolean operator >=(const XYZ &lhs, t rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >=(const XYZ &lhs, t rhs) Z_NOTHROW {return lhs.x >= rhs && lhs.y >= rhs && lhs.z >= rhs;} - friend Z_CT(CPP11) Boolean operator <=(const XYZ &lhs, t rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <=(const XYZ &lhs, t rhs) Z_NOTHROW {return lhs.x <= rhs && lhs.y <= rhs && lhs.z <= rhs;} - friend Z_CT(CPP11) Boolean operator >(const XYZ &lhs, t rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >(const XYZ &lhs, t rhs) Z_NOTHROW {return lhs.x > rhs && lhs.y > rhs && lhs.z > rhs;} - friend Z_CT(CPP11) Boolean operator <(const XYZ &lhs, t rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <(const XYZ &lhs, t rhs) Z_NOTHROW {return lhs.x < rhs && lhs.y < rhs && lhs.z < rhs;} @@ -137,27 +137,27 @@ namespace Zeta {template struct XYZ { {return XYZ(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs);} - friend Z_CT(CPP11) Boolean operator ==(t lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator ==(t lhs, const XYZ &rhs) Z_NOTHROW {return lhs == rhs.x && lhs == rhs.y && lhs == rhs.z;} - friend Z_CT(CPP11) Boolean operator !=(t lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator !=(t lhs, const XYZ &rhs) Z_NOTHROW {return lhs != rhs.x || lhs != rhs.y || lhs != rhs.y;} - friend Z_CT(CPP11) Boolean operator >=(t lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >=(t lhs, const XYZ &rhs) Z_NOTHROW {return lhs >= rhs.x && lhs >= rhs.y && lhs >= rhs.z;} - friend Z_CT(CPP11) Boolean operator <=(t lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <=(t lhs, const XYZ &rhs) Z_NOTHROW {return lhs <= rhs.x && lhs <= rhs.y && lhs <= rhs.z;} - friend Z_CT(CPP11) Boolean operator >(t lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >(t lhs, const XYZ &rhs) Z_NOTHROW {return lhs > rhs.x && lhs > rhs.y && lhs > rhs.z;} - friend Z_CT(CPP11) Boolean operator <(t lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <(t lhs, const XYZ &rhs) Z_NOTHROW {return lhs < rhs.x && lhs < rhs.y && lhs < rhs.z;} @@ -169,27 +169,27 @@ namespace Zeta {template struct XYZ { {return XYZ(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);} - friend Z_CT(CPP11) Boolean operator ==(const XYZ &lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator ==(const XYZ &lhs, const XY &rhs) Z_NOTHROW {return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == t(0);} - friend Z_CT(CPP11) Boolean operator !=(const XYZ &lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator !=(const XYZ &lhs, const XY &rhs) Z_NOTHROW {return lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != t(0);} - friend Z_CT(CPP11) Boolean operator >=(const XYZ &lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >=(const XYZ &lhs, const XY &rhs) Z_NOTHROW {return lhs.x >= rhs.x && lhs.y >= rhs.y && lhs.z >= t(0);} - friend Z_CT(CPP11) Boolean operator <=(const XYZ &lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <=(const XYZ &lhs, const XY &rhs) Z_NOTHROW {return lhs.x <= rhs.x && lhs.y <= rhs.y && lhs.z <= t(0);} - friend Z_CT(CPP11) Boolean operator >(const XYZ &lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >(const XYZ &lhs, const XY &rhs) Z_NOTHROW {return lhs.x > rhs.x && lhs.y > rhs.y && lhs.z > t(0);} - friend Z_CT(CPP11) Boolean operator <(const XYZ &lhs, const XY &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <(const XYZ &lhs, const XY &rhs) Z_NOTHROW {return lhs.x < rhs.x && lhs.y < rhs.y && lhs.z < t(0);} @@ -205,27 +205,27 @@ namespace Zeta {template struct XYZ { {return XYZ(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z, t(0));} - friend Z_CT(CPP11) Boolean operator ==(const XY &lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator ==(const XY &lhs, const XYZ &rhs) Z_NOTHROW {return lhs.x == rhs.x && lhs.y == rhs.y && rhs.z == t(0);} - friend Z_CT(CPP11) Boolean operator !=(const XY &lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator !=(const XY &lhs, const XYZ &rhs) Z_NOTHROW {return lhs.x != rhs.x || lhs.y != rhs.y || rhs.z != t(0);} - friend Z_CT(CPP11) Boolean operator >=(const XY &lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >=(const XY &lhs, const XYZ &rhs) Z_NOTHROW {return lhs.x >= rhs.x && lhs.y >= rhs.y && t(0) >= rhs.z;} - friend Z_CT(CPP11) Boolean operator <=(const XY &lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <=(const XY &lhs, const XYZ &rhs) Z_NOTHROW {return lhs.x <= rhs.x && lhs.y <= rhs.y && t(0) <= rhs.z;} - friend Z_CT(CPP11) Boolean operator >(const XY &lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator >(const XY &lhs, const XYZ &rhs) Z_NOTHROW {return lhs.x > rhs.x && lhs.y > rhs.y && t(0) > rhs.z;} - friend Z_CT(CPP11) Boolean operator <(const XY &lhs, const XYZ &rhs) Z_NOTHROW + friend Z_CT(CPP11) Bool operator <(const XY &lhs, const XYZ &rhs) Z_NOTHROW {return lhs.x < rhs.x && lhs.y < rhs.y && t(0) < rhs.z;} @@ -306,7 +306,7 @@ namespace Zeta {template struct XYZ { {return XYZ(t(0));} /* TODO */ - Z_CT(CPP11) Boolean has_zero() const Z_NOTHROW + Z_CT(CPP11) Bool has_zero() const Z_NOTHROW {return x == t(0) || y == t(0) || z == t(0);} @@ -330,7 +330,7 @@ namespace Zeta {template struct XYZ { {return x + y + z;} - Z_CT(CPP11) Boolean is_zero() const Z_NOTHROW + Z_CT(CPP11) Bool is_zero() const Z_NOTHROW {return x == t(0) && y == t(0) && z == t(0);} @@ -378,7 +378,6 @@ namespace Zeta {template struct XYZ { // MARK: - Signed - Z_CT(CPP11) XYZ absolute() const Z_NOTHROW { return XYZ( @@ -388,11 +387,11 @@ namespace Zeta {template struct XYZ { } - Z_CT(CPP11) Boolean has_negative() const Z_NOTHROW + Z_CT(CPP11) Bool has_negative() const Z_NOTHROW {return x < t(0) || y < t(0) || z < t(0);} - Z_CT(CPP11) Boolean is_negative() const Z_NOTHROW + Z_CT(CPP11) Bool is_negative() const Z_NOTHROW {return x < t(0) && y < t(0) && z < t(0);} @@ -402,14 +401,12 @@ namespace Zeta {template struct XYZ { // MARK: - Integer - - //Z_CT(CPP11) Boolean is_perpendicular(const XYZ &other) const + //Z_CT(CPP11) Bool is_perpendicular(const XYZ &other) const // {return !Zeta::absolute(dot_product(other));} // MARK: - Real - Z_CT(CPP11) XYZ clamp_01() const Z_NOTHROW { return XYZ( @@ -419,7 +416,7 @@ namespace Zeta {template struct XYZ { } - Z_CT(CPP11) Boolean has_almost_zero() const Z_NOTHROW + Z_CT(CPP11) Bool has_almost_zero() const Z_NOTHROW { return Zeta::is_almost_zero(x) || Zeta::is_almost_zero(y) || @@ -427,7 +424,7 @@ namespace Zeta {template struct XYZ { } - Z_CT(CPP11) Boolean has_finite() const Z_NOTHROW + Z_CT(CPP11) Bool has_finite() const Z_NOTHROW { return Zeta::is_finite(x) || Zeta::is_finite(y) || @@ -435,7 +432,7 @@ namespace Zeta {template struct XYZ { } - Z_CT(CPP11) Boolean has_infinity() const Z_NOTHROW + Z_CT(CPP11) Bool has_infinity() const Z_NOTHROW { return Zeta::is_infinity(x) || Zeta::is_infinity(y) || @@ -443,7 +440,7 @@ namespace Zeta {template struct XYZ { } - Z_CT(CPP11) Boolean has_nan() const Z_NOTHROW + Z_CT(CPP11) Bool has_nan() const Z_NOTHROW { return Zeta::is_nan(x) || Zeta::is_nan(y) || @@ -460,7 +457,7 @@ namespace Zeta {template struct XYZ { } - Z_CT(CPP11) Boolean is_almost_equal(const XYZ &other) const Z_NOTHROW + Z_CT(CPP11) Bool is_almost_equal(const XYZ &other) const Z_NOTHROW { return Zeta::are_almost_equal(x, other.x) && Zeta::are_almost_equal(y, other.y) && @@ -468,7 +465,7 @@ namespace Zeta {template struct XYZ { } - Z_CT(CPP11) Boolean is_almost_zero() const Z_NOTHROW + Z_CT(CPP11) Bool is_almost_zero() const Z_NOTHROW { return Zeta::is_almost_zero(x) && Zeta::is_almost_zero(y) && @@ -476,7 +473,7 @@ namespace Zeta {template struct XYZ { } - Z_CT(CPP11) Boolean is_finite() const Z_NOTHROW + Z_CT(CPP11) Bool is_finite() const Z_NOTHROW { return Zeta::is_finite(x) && Zeta::is_finite(y) && @@ -484,7 +481,7 @@ namespace Zeta {template struct XYZ { } - Z_CT(CPP11) Boolean is_infinity() const Z_NOTHROW + Z_CT(CPP11) Bool is_infinity() const Z_NOTHROW { return Zeta::is_infinity(x) && Zeta::is_infinity(y) && @@ -492,7 +489,7 @@ namespace Zeta {template struct XYZ { } - Z_CT(CPP11) Boolean is_nan() const Z_NOTHROW + Z_CT(CPP11) Bool is_nan() const Z_NOTHROW { return Zeta::is_nan(x) && Zeta::is_nan(y) && @@ -500,7 +497,7 @@ namespace Zeta {template struct XYZ { } - Z_CT(CPP11) Boolean is_perpendicular(const XYZ &other) const Z_NOTHROW + Z_CT(CPP11) Bool is_perpendicular(const XYZ &other) const Z_NOTHROW {return Zeta::absolute(dot_product(other)) <= Type::epsilon();} @@ -515,8 +512,8 @@ namespace Zeta {template struct XYZ { Z_CT(CPP11) XYZ reciprocal() const Z_NOTHROW {return XYZ(t(1) / x, t(1) / y, t(1) / z);} - }; -} +};} + #endif // Z_classes_XYZ_HPP diff --git a/projects/Zeta/API/Z/constants/boolean.h b/projects/Zeta/API/Z/constants/boolean.h index 61a0b56..50e4a1a 100644 --- a/projects/Zeta/API/Z/constants/boolean.h +++ b/projects/Zeta/API/Z/constants/boolean.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_constants_boolean_H diff --git a/projects/Zeta/API/Z/constants/build.hpp b/projects/Zeta/API/Z/constants/build.hpp index d2b7624..83596d9 100644 --- a/projects/Zeta/API/Z/constants/build.hpp +++ b/projects/Zeta/API/Z/constants/build.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_constants_build_HPP diff --git a/projects/Zeta/API/Z/constants/numbers.h b/projects/Zeta/API/Z/constants/numbers.h index 3944a28..9b5e624 100644 --- a/projects/Zeta/API/Z/constants/numbers.h +++ b/projects/Zeta/API/Z/constants/numbers.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_constants_numbers_H @@ -962,7 +962,10 @@ Released under the terms of the GNU Lesser General Public License v3. */ /* MARK: - Integer numbers */ -#define Z_CARMACK_NUMBER 0x5F3759DF -#define Z_LOMONT_NUMBER 0x5F375A86 +#define Z_CARMACK_NUMBER 0x5F3759DF +#define Z_LOMONT_NUMBER 0x5F375A86 + +/* Kaprekar's constant */ +#define Z_KAPREKAR_CONSTANT 6174 #endif /* Z_constants_numbers_H */ diff --git a/projects/Zeta/API/Z/constants/pointer.h b/projects/Zeta/API/Z/constants/pointer.h index 5fa9665..e759a89 100644 --- a/projects/Zeta/API/Z/constants/pointer.h +++ b/projects/Zeta/API/Z/constants/pointer.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_constants_pointer_H @@ -13,15 +13,12 @@ Released under the terms of the GNU Lesser General Public License v3. */ # undef Z_NULL #endif -#ifdef __cplusplus -# include - -# if Z_DIALECT_HAS_LITERAL(CPP11, NULLPTR) -# define Z_NULL nullptr -# else -# define Z_NULL 0 -# endif +#include +#if Z_DIALECT_HAS_LITERAL(CPP11, NULLPTR) || Z_DIALECT_HAS_LITERAL(C23, NULLPTR) +# define Z_NULL nullptr +#elif defined(__cplusplus) +# define Z_NULL 0 #else # define Z_NULL ((void *)0) #endif diff --git a/projects/Zeta/API/Z/formats/archive/TAR.h b/projects/Zeta/API/Z/formats/archive/TAR.h index 25b9ced..7803eb0 100644 --- a/projects/Zeta/API/Z/formats/archive/TAR.h +++ b/projects/Zeta/API/Z/formats/archive/TAR.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_archive_TAR_H diff --git a/projects/Zeta/API/Z/formats/character_set/ASCII.h b/projects/Zeta/API/Z/formats/character_set/ASCII.h index f59ce45..cb1c3a5 100644 --- a/projects/Zeta/API/Z/formats/character_set/ASCII.h +++ b/projects/Zeta/API/Z/formats/character_set/ASCII.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_ASCII_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP437.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP437.h index 2db03f3..0adcdc7 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP437.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP437.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP437_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP737.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP737.h index 1b680f3..ae7d754 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP737.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP737.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP737_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP775.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP775.h index 242d4c6..547ab09 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP775.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP775.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP775_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP850.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP850.h index 17dea5e..6aaffd8 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP850.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP850.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP850_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP852.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP852.h index a04c8df..99a14e0 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP852.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP852.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP852_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP855.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP855.h index 5847056..44afbd7 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP855.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP855.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP855_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP857.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP857.h index 6e69b6c..a9228b3 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP857.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP857.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP857_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP858.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP858.h index 884d884..47a67a4 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP858.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP858.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP858_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP860.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP860.h index 821e6fe..9f026c4 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP860.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP860.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP860_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP861.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP861.h index 45eb2cd..767046c 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP861.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP861.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP861_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP862.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP862.h index a1af323..1fefcf6 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP862.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP862.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP862_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP863.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP863.h index 05ab574..48bbde1 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP863.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP863.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP863_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP864.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP864.h index 1db89f0..cad120c 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP864.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP864.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP864_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP865.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP865.h index 2a15829..a6a8cd1 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP865.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP865.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP865_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP866.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP866.h index b1c74e7..2136255 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP866.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP866.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP866_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP869.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP869.h index 0fc23ef..916eb5d 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP869.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP869.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP869_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP872.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP872.h index 5deff14..07d70f1 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP872.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP872.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP872_H diff --git a/projects/Zeta/API/Z/formats/character_set/DOS_CP874.h b/projects/Zeta/API/Z/formats/character_set/DOS_CP874.h index 4cf43ab..e8f08fa 100644 --- a/projects/Zeta/API/Z/formats/character_set/DOS_CP874.h +++ b/projects/Zeta/API/Z/formats/character_set/DOS_CP874.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_character_set_DOS_CP874_H diff --git a/projects/Zeta/API/Z/formats/data_model/I16LP32.h b/projects/Zeta/API/Z/formats/data_model/I16LP32.h index 7e89533..18cf0b5 100644 --- a/projects/Zeta/API/Z/formats/data_model/I16LP32.h +++ b/projects/Zeta/API/Z/formats/data_model/I16LP32.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_data_model_I16LP32_H diff --git a/projects/Zeta/API/Z/formats/data_model/ILP32.h b/projects/Zeta/API/Z/formats/data_model/ILP32.h index 51c750a..063c2ac 100644 --- a/projects/Zeta/API/Z/formats/data_model/ILP32.h +++ b/projects/Zeta/API/Z/formats/data_model/ILP32.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_data_model_ILP32_H diff --git a/projects/Zeta/API/Z/formats/data_model/ILP64.h b/projects/Zeta/API/Z/formats/data_model/ILP64.h index 187527c..9ea1723 100644 --- a/projects/Zeta/API/Z/formats/data_model/ILP64.h +++ b/projects/Zeta/API/Z/formats/data_model/ILP64.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_data_model_ILP64_H diff --git a/projects/Zeta/API/Z/formats/data_model/IP16L32.h b/projects/Zeta/API/Z/formats/data_model/IP16L32.h index afb627d..c6e6a01 100644 --- a/projects/Zeta/API/Z/formats/data_model/IP16L32.h +++ b/projects/Zeta/API/Z/formats/data_model/IP16L32.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_data_model_IP16L32_H diff --git a/projects/Zeta/API/Z/formats/data_model/LLP64.h b/projects/Zeta/API/Z/formats/data_model/LLP64.h index 3a50645..ec062e7 100644 --- a/projects/Zeta/API/Z/formats/data_model/LLP64.h +++ b/projects/Zeta/API/Z/formats/data_model/LLP64.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_data_model_LLP64_H diff --git a/projects/Zeta/API/Z/formats/data_model/LP32.h b/projects/Zeta/API/Z/formats/data_model/LP32.h index d407232..37f7b9e 100644 --- a/projects/Zeta/API/Z/formats/data_model/LP32.h +++ b/projects/Zeta/API/Z/formats/data_model/LP32.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_data_model_LP32_H diff --git a/projects/Zeta/API/Z/formats/data_model/LP64.h b/projects/Zeta/API/Z/formats/data_model/LP64.h index 9c28739..6bd7d9f 100644 --- a/projects/Zeta/API/Z/formats/data_model/LP64.h +++ b/projects/Zeta/API/Z/formats/data_model/LP64.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_data_model_LP64_H diff --git a/projects/Zeta/API/Z/formats/data_model/SILP64.h b/projects/Zeta/API/Z/formats/data_model/SILP64.h index 9e5814c..c58456b 100644 --- a/projects/Zeta/API/Z/formats/data_model/SILP64.h +++ b/projects/Zeta/API/Z/formats/data_model/SILP64.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_data_model_SILP64_H diff --git a/projects/Zeta/API/Z/formats/floating-point/Brain_Floating-Point.h b/projects/Zeta/API/Z/formats/floating-point/Brain_Floating-Point.h index dba2393..8544a7f 100644 --- a/projects/Zeta/API/Z/formats/floating-point/Brain_Floating-Point.h +++ b/projects/Zeta/API/Z/formats/floating-point/Brain_Floating-Point.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_floating_point_Brain_Floating_Point_H diff --git a/projects/Zeta/API/Z/formats/floating-point/IBM.h b/projects/Zeta/API/Z/formats/floating-point/IBM.h index dd940b0..b96141e 100644 --- a/projects/Zeta/API/Z/formats/floating-point/IBM.h +++ b/projects/Zeta/API/Z/formats/floating-point/IBM.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_floating_point_IBM_H diff --git a/projects/Zeta/API/Z/formats/floating-point/IEEE_754.h b/projects/Zeta/API/Z/formats/floating-point/IEEE_754.h index cdf82b5..e8379da 100644 --- a/projects/Zeta/API/Z/formats/floating-point/IEEE_754.h +++ b/projects/Zeta/API/Z/formats/floating-point/IEEE_754.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_floating_point_IEEE_754_H diff --git a/projects/Zeta/API/Z/formats/floating-point/x87.h b/projects/Zeta/API/Z/formats/floating-point/x87.h index af7e573..bb5e200 100644 --- a/projects/Zeta/API/Z/formats/floating-point/x87.h +++ b/projects/Zeta/API/Z/formats/floating-point/x87.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_floating_point_x87_H diff --git a/projects/Zeta/API/Z/formats/keymap/Mac_OS.h b/projects/Zeta/API/Z/formats/keymap/Mac_OS.h index 20a4794..10fdb7a 100644 --- a/projects/Zeta/API/Z/formats/keymap/Mac_OS.h +++ b/projects/Zeta/API/Z/formats/keymap/Mac_OS.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_keymap_Mac_OS_H diff --git a/projects/Zeta/API/Z/formats/keymap/USB.h b/projects/Zeta/API/Z/formats/keymap/USB.h index 3d40a0f..4b54846 100644 --- a/projects/Zeta/API/Z/formats/keymap/USB.h +++ b/projects/Zeta/API/Z/formats/keymap/USB.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_keymap_USB_H diff --git a/projects/Zeta/API/Z/formats/keymap/Z.h b/projects/Zeta/API/Z/formats/keymap/Z.h index d8fdb8e..d16bd42 100644 --- a/projects/Zeta/API/Z/formats/keymap/Z.h +++ b/projects/Zeta/API/Z/formats/keymap/Z.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_formats_keymap_Z_H diff --git a/projects/Zeta/API/Z/formats/recording/machine/computer/ZX_Spectrum/RZX.h b/projects/Zeta/API/Z/formats/recording/machine/computer/ZX_Spectrum/RZX.h new file mode 100644 index 0000000..1384015 --- /dev/null +++ b/projects/Zeta/API/Z/formats/recording/machine/computer/ZX_Spectrum/RZX.h @@ -0,0 +1,105 @@ +/* Zeta API - Z/formats/recording/machine/computer/ZX_Spectrum/RZX.h + ______ ______________ ___ +|__ / | ___|___ ___|/ \ + / /__| __| | | / - \ + /______|_____| |__| /__/ \__\ +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. +Released under the terms of the GNU Lesser General Public License v3. */ + +#ifndef Z_formats_recording_machine_computer_ZX_Spectrum_RZX_H +#define Z_formats_recording_machine_computer_ZX_Spectrum_RZX_H + +#include + +typedef Z_PACKED_STRUCTURE_BEGIN { + ZInt32 signature; /* 'RZX!' */ + zuint8 version_major; + zuint8 version_minor; + zuint32 flags; +} Z_PACKED_STRUCTURE_END Z_RZXHeader; + +#define Z_RZX_BLOCK_ID_CREATOR_INFO 0x10 +#define Z_RZX_BLOCK_ID_SECURITY_INFO 0x20 +#define Z_RZX_BLOCK_ID_SECURITY_SIGNATURE 0x21 +#define Z_RZX_BLOCK_ID_SNAPSHOT 0x30 +#define Z_RZX_BLOCK_ID_INPUT_RECORDING 0x80 + +typedef Z_PACKED_STRUCTURE_BEGIN { + zuint8 id; + zuint32 size; +} Z_PACKED_STRUCTURE_END Z_RZXBlockHeader; + +/* MARK: - ID 10h - Creator Information */ + +typedef Z_PACKED_STRUCTURE_BEGIN { + Z_RZXBlockHeader header; + zuint8 identifier; + zuint16 version_major; + zuint16 version_minor; + Z_FAM(zuint8 custom_data[];) +} Z_PACKED_STRUCTURE_END Z_RZXCreatorInfo; + +/* MARK: - ID 20h - Security Information */ + +typedef Z_PACKED_STRUCTURE_BEGIN { + Z_RZXBlockHeader header; + zuint32 key_id; + zuint32 week_code; +} Z_PACKED_STRUCTURE_END Z_RZXSecurityInfo; + +/* MARK: - ID 21h - Security Signature */ + +typedef Z_PACKED_STRUCTURE_BEGIN { + Z_RZXBlockHeader header; + Z_FAM(zuint8 r_s[];) +} Z_PACKED_STRUCTURE_END Z_RZXSecuritySignature; + +/* MARK: - ID 21h - Snapshot */ + +typedef Z_PACKED_STRUCTURE_BEGIN { + Z_RZXBlockHeader header; + zuint32 flags; + ZInt32 file_extension; + zuint32 size_uncompressed; + Z_FAM(zuint8 data[];) +} Z_PACKED_STRUCTURE_END Z_RZXSnapshot; + +#define Z_RZX_SNAPSHOT_FLAG_EXTERNAL 1 +#define Z_RZX_SNAPSHOT_FLAG_COMPRESSED 2 + +typedef Z_PACKED_STRUCTURE_BEGIN { + zuint32 checksum; + Z_FAM(zuint8 filename[];) +} Z_PACKED_STRUCTURE_END Z_RZXSnapshotDescriptor; + +/* MARK: - ID 80h - Input Recording */ + +typedef Z_PACKED_STRUCTURE_BEGIN { + Z_RZXBlockHeader header; + zuint32 frame_count; + zuint8 reserved; + zuint32 t_states; + zuint32 flags; +} Z_PACKED_STRUCTURE_END Z_RZXInputRecording; + +#define Z_RZX_INPUT_RECORDING_FLAG_CYPHERED 1 +#define Z_RZX_INPUT_RECORDING_FLAG_COMPRESSED 2 + +typedef Z_PACKED_STRUCTURE_BEGIN { + zuint16 opcode_fetch_count; + zuint16 in_count; + Z_FAM(zuint8 values[];) +} Z_PACKED_STRUCTURE_END Z_RZXInputRecordingFrame; + +/* MARK: - Block union */ + +typedef union { + Z_RZXBlockHeader header; + Z_RZXCreatorInfo creator_info; + Z_RZXSecurityInfo security_info; + Z_RZXSecuritySignature security_signature; + Z_RZXSnapshot snapshot; + Z_RZXInputRecording input_recording; +} Z_RZXBlock; + +#endif /* Z_formats_recording_machine_computer_ZX_Spectrum_RZX_H */ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/+D.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/+D.h index 1dea599..c54ace8 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/+D.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/+D.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. _________________________________________________________ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ACH.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ACH.h index 00b9d1c..e9104c4 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ACH.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ACH.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. _______________________________________________________ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/FRZ.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/FRZ.h index 4adeb8e..6dbb4b3 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/FRZ.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/FRZ.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. _________________________________________________________________ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/PRG.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/PRG.h index a7c1304..2a299f9 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/PRG.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/PRG.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. _______________________________________________________ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SEM.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SEM.h index b3b9397..24d36db 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SEM.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SEM.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. _______________________________________________________ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SIT.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SIT.h index 4ae19f2..5574914 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SIT.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SIT.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. ____________________________________________________________________ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SNA.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SNA.h index 12ecd19..20df28b 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SNA.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SNA.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. ________________________________________________________________________ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SNP.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SNP.h index 609b801..8181de4 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SNP.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SNP.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. ___________________________________________________________________ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SNX.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SNX.h index 5b5c92c..5e9376f 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SNX.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SNX.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. ______________________________________________________________________ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SP.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SP.h index f5c5c88..9b427cb 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SP.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/SP.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. ______________________________________________________________________________ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/Z80.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/Z80.h index 578dc4a..c1103eb 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/Z80.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/Z80.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. _______________________________________________________ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZLS.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZLS.h index d8c6138..af1e9e5 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZLS.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZLS.h @@ -4,7 +4,7 @@ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ Information contributed by Troels Norgaard. -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. ___________________________________________________________________ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZX-State.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZX-State.h index fe6829d..e00e5f0 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZX-State.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZX-State.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. _______________________________________________________________ @@ -105,16 +105,18 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'+', '3', 0, 0} - ZX Spectrum +3 */ typedef Z_PACKED_STRUCTURE_BEGIN { - zuint8 drive_count; - zuint8 motor_is_on; + Z_ZXStateBlockHeader header; + zuint8 drive_count; + zuint8 motor_is_on; } Z_PACKED_STRUCTURE_END Z_ZXStateZXSpectrumPlus3; /* MARK: - ID {'A', 'M', 'X', 'M'} - Mouse */ typedef Z_PACKED_STRUCTURE_BEGIN { - zuint8 type; - zuint8 ctrl_a_registers[3]; - zuint8 ctrl_b_registers[3]; + Z_ZXStateBlockHeader header; + zuint8 type; + zuint8 ctrl_a_registers[3]; + zuint8 ctrl_b_registers[3]; } Z_PACKED_STRUCTURE_END Z_ZXStateMouse; #define Z_ZX_STATE_MOUSE_TYPE_NONE 0 @@ -124,9 +126,10 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'A', 'T', 'R', 'P'} - ZXATASP RAM (added in v1.3) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint16 flags; - zuint8 page_index; - zuint8 data[1]; + zuint8 page_index; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateZXATASPRAM; #define Z_ZX_STATE_ZXATASP_RAM_FLAG_COMPRESSED 1 @@ -134,9 +137,10 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'A', 'Y', 0, 0} - AY chip */ typedef Z_PACKED_STRUCTURE_BEGIN { - zuint8 flags; - zuint8 current_register; - zuint8 registers[16]; + Z_ZXStateBlockHeader header; + zuint8 flags; + zuint8 current_register; + zuint8 registers[16]; } Z_PACKED_STRUCTURE_END Z_ZXStateAY; #define Z_ZX_STATE_AY_FLAG_FULLER_BOX 1 @@ -145,6 +149,7 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'B', '1', '2', '8'} - Beta 128 Disk Interface (added in v1.2) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint32 flags; zuint8 drive_count; zuint8 system_register; @@ -152,7 +157,7 @@ typedef Z_PACKED_STRUCTURE_BEGIN { zuint8 sector_register; zuint8 data_register; zuint8 satus_register; - zuint8 rom_data[1]; + Z_FAM(zuint8 rom_data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateBeta128DiskInterface; #define Z_ZX_STATE_BETA_128_DISK_INTERFACE_FLAG_CONNECTED 1 @@ -165,11 +170,12 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'B', 'D', 'S', 'K'} - Beta Disk (added in v1.2) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint32 flags; zuint8 drive_index; zuint8 cylinder; zuint8 format; - zuint8 data[1]; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateBeta128DiskInterfaceDisk; #define Z_ZX_STATE_BETA_128_DISK_INTERFACE_DISK_FLAG_EMBEDDED 1 @@ -184,9 +190,10 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'C', 'F', 'R', 'P'} - ZXCF RAM (added in v1.3) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint16 flags; zuint8 page_index; - zuint8 data[1]; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateZXCFRAM; #define Z_ZX_STATE_ZXCF_RAM_FLAG_COMPRESSED 1 @@ -194,6 +201,7 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'C', 'O', 'V', 'X'} - Covox (added in v1.2) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint8 volume; zuint8 reserved[3]; } Z_PACKED_STRUCTURE_END Z_ZXStateCovox; @@ -201,18 +209,20 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'C', 'R', 'T', 'R'} - Beta Disk (added in v1.1) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; char name[32]; - zuint16 major_version; - zuint16 minor_version; - zuint8 data[1]; + zuint16 version_major; + zuint16 version_minor; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateCreator; /* MARK: - ID {'D', 'O', 'C', 'K'} - Dock (added in v1.3) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint16 flags; zuint8 page_index; - zuint8 data[1]; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateDock; #define Z_ZX_STATE_DOCK_FLAG_COMPRESSED 1 @@ -222,16 +232,18 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'D', 'R', 'U', 'M'} - SpecDrum */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint8 volume; } Z_PACKED_STRUCTURE_END Z_ZXStateSpecDrum; /* MARK: - ID {'D', 'S', 'K', 0} - Disk */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint16 flags; zuint8 drive_index; - zuint32 uncompressed_size; - zuint8 data[1]; + zuint32 size_uncompressed; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateDisk; #define Z_ZX_STATE_DISK_FLAG_COMPRESSED 1 @@ -241,6 +253,7 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'G', 'S', 0, 0'} - General Sound (added in v1.2) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint8 model; zuint8 uppper_page_index; zuint8 volume_level[4]; @@ -256,7 +269,7 @@ typedef Z_PACKED_STRUCTURE_BEGIN { zuint32 cycles_start; zuint8 hold_int_cycles; zuint8 memptrl; - zuint8 rom[1]; + Z_FAM(zuint8 rom[];) } Z_PACKED_STRUCTURE_END Z_ZXStateGeneralSound; #define Z_ZX_STATE_GENERAL_SOUND_FLAG_EI_LAST 1 @@ -270,9 +283,10 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'G', 'S', 'R', 'P'} - General Sound RAM Page (added in v1.2) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint16 flags; zuint8 index; - zuint8 data[1]; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateGeneralSoundRAMPage; #define Z_ZXS_TATE_GENERAL_SOUND_RAM_PAGE_FLAG_COMPRESSED 1 @@ -280,12 +294,13 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'I', 'F', '1', 0} - ZX Interface 1 */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint16 flags; zuint8 microdrive_count; zuint8 reserved_1[3]; zuint32 reserved_2[8]; zuint16 rom_size; - zuint8 rom[1]; + Z_FAM(zuint8 rom[];) } Z_PACKED_STRUCTURE_END Z_ZXStateZXInterface1; #define Z_ZX_STATE_ZX_INTERFACE_1_FLAG_ENABLED 1 @@ -295,13 +310,15 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'I', 'F', '2', 'R'} - ZX Interface 2 ROM */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint32 rom_size; - zuint8 rom[1]; + Z_FAM(zuint8 rom[];) } Z_PACKED_STRUCTURE_END Z_ZXStateZXInterface2ROM; /* MARK: - ID {'J', 'O', 'Y', 0} - Joystick (added in v1.1) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint32 flags; zuint8 type_player_1; zuint8 type_player_2; @@ -322,6 +339,7 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'K', 'E', 'Y', 'B'} - Keyboard */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint32 flags; zuint8 joystick; /* added in v1.1 */ } Z_PACKED_STRUCTURE_END Z_ZXStateKeyboard; @@ -343,9 +361,10 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'L', 'C', 'R','P'} - LEC Memory Extension RAM Page (added in v1.5) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint16 flags; zuint8 index; - zuint8 data[1]; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateLECMemoryExtensionRAMPage; #define Z_ZX_STATE_LEC_MEMORY_EXTENSION_RAM_PAGE_FLAG_COMPRESSED 1 @@ -353,6 +372,7 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'L', 'E', 'C', 0} - LEC Memory Extension (added in v1.5) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint16 flags; zuint8 page_index; zuint8 ram_page_count; @@ -363,13 +383,14 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'M', 'D', 'R', 'V'} - ZX Microdrive Tape */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint16 flags; zuint8 drive_index; zuint8 drive_is_running; zuint16 drive_position; zuint16 preamble; - zuint32 uncompressed_size; - zuint8 data[1]; + zuint32 size_uncompressed; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateZXMicrodriveTape; #define Z_ZX_STATE_ZX_MICRODRIVE_TAPE_FLAG_COMPRESSED 1 @@ -378,9 +399,10 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'M', 'F', 'C', 'E'} - Multiface */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint8 model_48k; zuint8 flags; - zuint8 data[1]; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateMultiface; #define Z_ZX_STATE_MULTIFACE_FLAG_PAGEDIN 0x01 @@ -396,11 +418,12 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'O', 'D', 'S', 'K'} - Opus Discovery 1 Disk (added in v1.4) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint32 flags; zuint8 drive_index; zuint8 cylinder; zuint8 type; - zuint8 data[1]; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateOpusDiscovery1Disk; #define Z_ZX_STATE_OPUS_DISCOVERY_1_DISK_TYPE_OPD 0 @@ -408,13 +431,14 @@ typedef Z_PACKED_STRUCTURE_BEGIN { #define Z_ZX_STATE_OPUS_DISCOVERY_1_DISK_TYPE_FLOPPY_0 2 #define Z_ZX_STATE_OPUS_DISCOVERY_1_DISK_TYPE_FLOPPY_1 3 -#define Z_ZX_STATE_BETA_128_DISK_INTERFACE_DISK_FLAG_EMBEDDED 1 -#define Z_ZX_STATE_BETA_128_DISK_INTERFACE_DISK_FLAG_COMPRESSED 2 -#define Z_ZX_STATE_BETA_128_DISK_INTERFACE_DISK_FLAG_WRITEPROTECT 4 +#define Z_ZX_STATE_OPUS_DISCOVERY_1_DISK_FLAG_EMBEDDED 1 +#define Z_ZX_STATE_OPUS_DISCOVERY_1_DISK_FLAG_COMPRESSED 2 +#define Z_ZX_STATE_OPUS_DISCOVERY_1_DISK_FLAG_WRITEPROTECT 4 /* MARK: - ID {'O', 'P', 'U', 'S'} - Opus Discovery 1 (added in v1.4) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint32 flags; zuint32 ram_size; zuint32 rom_size; @@ -429,7 +453,7 @@ typedef Z_PACKED_STRUCTURE_BEGIN { zuint8 sector_register; zuint8 data_register; zuint8 status_register; - zuint8 ram[1]; + Z_FAM(zuint8 ram[];) } Z_PACKED_STRUCTURE_END Z_ZXStateOpusDiscovery1; #define Z_ZX_STATE_OPUS_DISCOVERY_1_FLAG_PAGED 1 @@ -440,11 +464,12 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'P', 'D', 'S', 'K'} - +D Disk (added in v1.3) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint32 flags; zuint8 drive_index; zuint8 cylinder; zuint8 type; - zuint8 data[1]; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStatePlusDDisk; #define Z_ZX_STATE_PLUSD_DISK_TYPE_MGT 0 @@ -459,6 +484,7 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'P', 'L', 'S', 'D'} - +D (added in v1.3) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint32 flags; zuint32 ram_size; zuint32 rom_size; @@ -469,7 +495,7 @@ typedef Z_PACKED_STRUCTURE_BEGIN { zuint8 sector_register; zuint8 data_register; zuint8 status_register; - zuint8 ram[1]; + Z_FAM(zuint8 ram[];) } Z_PACKED_STRUCTURE_END Z_ZXStatePlusD; #define Z_ZX_STATE_PLUSD_FLAG_PAGED 1 @@ -483,9 +509,10 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'R', 'A', 'M', 'P'} - RAM Page */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint16 flags; zuint8 index; - zuint8 data[1]; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateRAMPage; #define Z_ZX_STATE_RAM_PAGE_FLAG_COMPRESSED 1 @@ -493,16 +520,18 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'R', 'O', 'M', 0} - ROM */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint16 flags; - zuint32 uncompressed_size; - zuint8 data[1]; -} Z_PACKED_STRUCTURE_END ZXSTROM; + zuint32 size_uncompressed; + Z_FAM(zuint8 data[];) +} Z_PACKED_STRUCTURE_END Z_ZXStateROM; #define Z_ZX_STATE_ROM_FLAG_COMPRESSED 1 /* MARK: - ID {'S', 'C', 'L', 'D'} - Timex (added in v1.2) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint8 port_f4; zuint8 port_ff; } Z_PACKED_STRUCTURE_END Z_ZXStateTimex; @@ -512,15 +541,17 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* https://worldofspectrum.org/zxplus3e/interface.html#simple */ /*typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; } Z_PACKED_STRUCTURE_END Z_ZXStateSimple8BitInterface;*/ /* MARK: - ID {'S','N','E','F'} - Spectranet Flash Page (added in v1.5) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint8 flags; zuint32 unused; zuint32 data_size; - zuint8 data[1]; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateSpectranetFlashPage; #define Z_ZX_STATE_SPECTRANET_FLASH_PAGE_FLAG_COMPRESSED 1 @@ -528,10 +559,11 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'S','N','E','R'} - Spectranet RAM Page (added in v1.5) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint8 flags; zuint32 unused; zuint32 data_size; - zuint8 data[1]; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateSpectranetRAMPage; #define Z_ZX_STATE_SPECTRANET_RAM_PAGE_FLAG_COMPRESSED 1 @@ -539,6 +571,7 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'S', 'N', 'E', 'T'} - Spectranet (added in v1.5) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint32 flags; zuint8 page_a; zuint8 page_b; @@ -558,6 +591,7 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'S', 'P', 'C', 'R'} - ZX Spectrum */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint8 border_color; zuint8 port_7ffd; zuint8 port_1ffd_eff7; /* EFF7h added in v1.3 */ @@ -568,12 +602,13 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'T', 'A', 'P', 'E'} - Tape */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint16 block_index; zuint16 flags; - zuint32 uncompressed_size; - zuint32 compressed_size; + zuint32 size_uncompressed; + zuint32 size_compressed; char file_extension[16]; - zuint8 data[1]; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXStateTape; #define Z_ZX_STATE_TAPE_FLAG_EMBEDDED 1 @@ -582,12 +617,14 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'U', 'S', 'P', 'E'} - Currah μSpeech */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint8 rom_is_paged_in; } Z_PACKED_STRUCTURE_END Z_ZXStateCurrahMicroSpeech; /* MARK: - ID {'Z', '8', '0', 'R'} - Z80 */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; ZInt16 af, bc, de, hl, af_, bc_, de_, hl_, ix, iy, sp, pc; zuint8 i, r; zuint8 iff1, iff2; @@ -605,6 +642,7 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'Z', 'X', 'A', 'T'} - ZXATASP (added in v1.3) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint16 flags; zuint8 port_a; zuint8 port_b; @@ -620,6 +658,7 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'Z', 'X', 'C', 'F'} - ZXCF (added in v1.3) */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint16 flags; zuint8 memory_control_register; zuint8 ram_page_count; @@ -630,54 +669,54 @@ typedef Z_PACKED_STRUCTURE_BEGIN { /* MARK: - ID {'Z', 'X', 'P', 'R'} - ZX Printer */ typedef Z_PACKED_STRUCTURE_BEGIN { + Z_ZXStateBlockHeader header; zuint16 flags; } Z_PACKED_STRUCTURE_END Z_ZXStateZXPrinter; #define Z_ZX_STATE_ZX_PRINTER_FLAG_ENABLED 1 -typedef Z_PACKED_STRUCTURE_BEGIN { - Z_ZXStateBlockHeader header; - - union { Z_ZXStateAY ay; - Z_ZXStateBeta128DiskInterface beta_128_disk_interface; - Z_ZXStateBeta128DiskInterfaceDisk beta_128_disk_interface_disk; - Z_ZXStateCovox covox; - Z_ZXStateCreator creator; - Z_ZXStateCurrahMicroSpeech currah_microspeech; - Z_ZXStateDisk disk; - Z_ZXStateDock dock; - Z_ZXStateGeneralSound general_sound; - Z_ZXStateGeneralSoundRAMPage general_sound_ram_page; - Z_ZXStateJoystick joystick; - Z_ZXStateKeyboard keyboard; - Z_ZXStateLECMemoryExtension lec_memory_extension; - Z_ZXStateLECMemoryExtensionRAMPage lec_memory_extension_page; - Z_ZXStateMouse mouse; - Z_ZXStateMultiface multiface; - Z_ZXStateOpusDiscovery1 opus_discovery_1; - Z_ZXStateOpusDiscovery1Disk opus_discovery_1_disk; - Z_ZXStatePlusD plusd; - Z_ZXStatePlusDDisk plusd_disk; - Z_ZXStateRAMPage ram_page; - /*Z_ZXStateSimple8BitInterface simple_8bit_interface;*/ - Z_ZXStateSpecDrum specdrum; - Z_ZXStateSpectranet spectranet; - Z_ZXStateSpectranetFlashPage spectranet_flash_page; - Z_ZXStateSpectranetRAMPage spectranet_ram_page; - Z_ZXStateTape zx_tape; - Z_ZXStateTimex timex; - Z_ZXStateZ80 z80; - Z_ZXStateZXATASP zxatasp; - Z_ZXStateZXATASPRAM zxatasp_ram; - Z_ZXStateZXCF zxcf; - Z_ZXStateZXCFRAM zxcf_ram; - Z_ZXStateZXInterface1 zx_interface_1; - Z_ZXStateZXInterface2ROM zx_interface_2_rom; - Z_ZXStateZXMicrodriveTape zx_microdrive_tape; - Z_ZXStateZXPrinter zx_printer; - Z_ZXStateZXSpectrum zx_spectrum; - Z_ZXStateZXSpectrumPlus3 zx_spectrum_plus3; - } body; -} Z_PACKED_STRUCTURE_END Z_ZXStateBlock; +typedef Z_PACKED_UNION_BEGIN { + Z_ZXStateBlockHeader header; + Z_ZXStateAY ay; + Z_ZXStateBeta128DiskInterface beta_128_disk_interface; + Z_ZXStateBeta128DiskInterfaceDisk beta_128_disk_interface_disk; + Z_ZXStateCovox covox; + Z_ZXStateCreator creator; + Z_ZXStateCurrahMicroSpeech currah_microspeech; + Z_ZXStateDisk disk; + Z_ZXStateDock dock; + Z_ZXStateGeneralSound general_sound; + Z_ZXStateGeneralSoundRAMPage general_sound_ram_page; + Z_ZXStateJoystick joystick; + Z_ZXStateKeyboard keyboard; + Z_ZXStateLECMemoryExtension lec_memory_extension; + Z_ZXStateLECMemoryExtensionRAMPage lec_memory_extension_page; + Z_ZXStateMouse mouse; + Z_ZXStateMultiface multiface; + Z_ZXStateOpusDiscovery1 opus_discovery_1; + Z_ZXStateOpusDiscovery1Disk opus_discovery_1_disk; + Z_ZXStatePlusD plusd; + Z_ZXStatePlusDDisk plusd_disk; + Z_ZXStateRAMPage ram_page; + Z_ZXStateROM rom; + /*Z_ZXStateSimple8BitInterface simple_8bit_interface;*/ + Z_ZXStateSpecDrum specdrum; + Z_ZXStateSpectranet spectranet; + Z_ZXStateSpectranetFlashPage spectranet_flash_page; + Z_ZXStateSpectranetRAMPage spectranet_ram_page; + Z_ZXStateTape zx_tape; + Z_ZXStateTimex timex; + Z_ZXStateZ80 z80; + Z_ZXStateZXATASP zxatasp; + Z_ZXStateZXATASPRAM zxatasp_ram; + Z_ZXStateZXCF zxcf; + Z_ZXStateZXCFRAM zxcf_ram; + Z_ZXStateZXInterface1 zx_interface_1; + Z_ZXStateZXInterface2ROM zx_interface_2_rom; + Z_ZXStateZXMicrodriveTape zx_microdrive_tape; + Z_ZXStateZXPrinter zx_printer; + Z_ZXStateZXSpectrum zx_spectrum; + Z_ZXStateZXSpectrumPlus3 zx_spectrum_plus3; +} Z_PACKED_UNION_END Z_ZXStateBlock; #endif /* Z_formats_snapshot_machine_computer_ZX_Spectrum_ZX_State_H */ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZX.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZX.h index ad9fecb..c2a64e5 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZX.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZX.h @@ -4,7 +4,7 @@ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ Information contributed by Troels Norgaard. -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. _________________________________________________________________________ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZX82.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZX82.h index 147985f..c7cb805 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZX82.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZX82.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. ______________________________________________________________________________ diff --git a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZXS.h b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZXS.h index bada252..1e292c9 100644 --- a/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZXS.h +++ b/projects/Zeta/API/Z/formats/snapshot/machine/computer/ZX_Spectrum/ZXS.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. __________________________________________________________________ @@ -28,17 +28,17 @@ Released under the terms of the GNU Lesser General Public License v3. #include #include -#define Z_ZXS_MACHINE_DEFAULT 0 -#define Z_ZXS_MACHINE_48K_ISSUE_2 0x10 // ZX Spectrum 48K (Issue 2) -#define Z_ZXS_MACHINE_PLUS 0x20 // ZX Spectrum + (Model 3) -#define Z_ZXS_MACHINE_PLUS_128K 0x30 // ZX Spectrum 128 -#define Z_ZXS_MACHINE_PLUS2 0x40 // ZX Spectrum +2 -#define Z_ZXS_MACHINE_PLUS2A 0x50 // ZX Spectrum +2A -#define Z_ZXS_MACHINE_PLUS3 0x60 // ZX Spectrum +3 +#define Z_ZXS_MACHINE_MODEL_DEFAULT 0x00 +#define Z_ZXS_MACHINE_MODEL_ZX_SPECTRUM_48K_ISSUE_2 0x10 /* ZX Spectrum 48K (Issue 2) */ +#define Z_ZXS_MACHINE_MODEL_ZX_SPECTRUM_PLUS 0x20 /* ZX Spectrum + (Model 3) */ +#define Z_ZXS_MACHINE_MODEL_ZX_SPECTRUM_PLUS_128K 0x30 /* ZX Spectrum 128 */ +#define Z_ZXS_MACHINE_MODEL_ZX_SPECTRUM_PLUS2 0x40 /* ZX Spectrum +2 */ +#define Z_ZXS_MACHINE_MODEL_ZX_SPECTRUM_PLUS2A 0x50 /* ZX Spectrum +2A */ +#define Z_ZXS_MACHINE_MODEL_ZX_SPECTRUM_PLUS3 0x60 /* ZX Spectrum +3 */ -#define ZXH_NONSTANDARD 0x0001 // peripheral hardware +#define ZXH_NONSTANDARD 0x0001 /* peripheral hardware */ -#define Z_ZXS_ZIP_METHOD_STORE 0 // compression methods +#define Z_ZXS_ZIP_METHOD_STORE 0 /* compression methods */ #define Z_ZXS_ZIP_METHOD_SHRINK 0x0001 #define Z_ZXS_ZIP_METHOD_REDUCE_1 0x0002 #define Z_ZXS_ZIP_METHOD_REDUCE_2 0x0003 @@ -91,10 +91,10 @@ Released under the terms of the GNU Lesser General Public License v3. #define Z_ZXS_CHUNK_ID_ZX32 Z_UINT32_STRING('z','x','3','2') typedef Z_PACKED_STRUCTURE_BEGIN { - zuint32 structure_size; // structure size - zuint32 crc32; // crc - zuint32 uncompressed_size; // uncompressed size - zuint8 data[1]; + zuint32 structure_size; + zuint32 crc32; + zuint32 size_uncompressed; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXSZip; typedef Z_PACKED_STRUCTURE_BEGIN { @@ -134,7 +134,7 @@ typedef Z_PACKED_STRUCTURE_BEGIN { zuint32 current_position; zuint32 remain_block_size; zuint32 data_size; - zuint8 data[1]; + Z_FAM(zuint8 data[];) } Z_PACKED_STRUCTURE_END Z_ZXSTape; typedef Z_PACKED_STRUCTURE_BEGIN { diff --git a/projects/Zeta/API/Z/formats/storage_medium_image/NES_Game_Pak/TNES.h b/projects/Zeta/API/Z/formats/storage_medium_image/NES_Game_Pak/TNES.h index 4d6f97a..99ab58d 100644 --- a/projects/Zeta/API/Z/formats/storage_medium_image/NES_Game_Pak/TNES.h +++ b/projects/Zeta/API/Z/formats/storage_medium_image/NES_Game_Pak/TNES.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. ____________________________________________ diff --git a/projects/Zeta/API/Z/formats/storage_medium_image/NES_Game_Pak/UNIF.h b/projects/Zeta/API/Z/formats/storage_medium_image/NES_Game_Pak/UNIF.h index 2697796..fab6950 100644 --- a/projects/Zeta/API/Z/formats/storage_medium_image/NES_Game_Pak/UNIF.h +++ b/projects/Zeta/API/Z/formats/storage_medium_image/NES_Game_Pak/UNIF.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. ____________________________________________ diff --git a/projects/Zeta/API/Z/formats/storage_medium_image/NES_Game_Pak/iNES.h b/projects/Zeta/API/Z/formats/storage_medium_image/NES_Game_Pak/iNES.h index 7334e5e..4113b3b 100644 --- a/projects/Zeta/API/Z/formats/storage_medium_image/NES_Game_Pak/iNES.h +++ b/projects/Zeta/API/Z/formats/storage_medium_image/NES_Game_Pak/iNES.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. ___________________________________________________________ diff --git a/projects/Zeta/API/Z/formats/storage_medium_image/audio/TZX.h b/projects/Zeta/API/Z/formats/storage_medium_image/audio/TZX.h index a84bba9..f7acd6f 100644 --- a/projects/Zeta/API/Z/formats/storage_medium_image/audio/TZX.h +++ b/projects/Zeta/API/Z/formats/storage_medium_image/audio/TZX.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. .------------------------------------------------------------------------------. @@ -208,8 +208,8 @@ Released under the terms of the GNU Lesser General Public License v3. typedef Z_PACKED_STRUCTURE_BEGIN { zuint8 signature[7]; /* 'ZXTape!' */ zuint8 eof_marker; /* 1Ah */ - zuint8 major_version; - zuint8 minor_version; + zuint8 version_major; + zuint8 version_minor; } Z_PACKED_STRUCTURE_END Z_TZXHeader; /* MARK: - Block ID */ @@ -1228,8 +1228,8 @@ typedef Z_PACKED_STRUCTURE_BEGIN { zuint8 block_id; zuint8 signature[6]; /* 'XTape!' */ zuint8 eof_marker; /* 1Ah */ - zuint8 major_version; - zuint8 minor_version; + zuint8 version_major; + zuint8 version_minor; } Z_PACKED_STRUCTURE_END Z_TZXGlue; typedef Z_PACKED_STRUCTURE_BEGIN { diff --git a/projects/Zeta/API/Z/formats/storage_medium_image/audio/Warajevo_TAP.h b/projects/Zeta/API/Z/formats/storage_medium_image/audio/Warajevo_TAP.h index c23e12d..2429c61 100644 --- a/projects/Zeta/API/Z/formats/storage_medium_image/audio/Warajevo_TAP.h +++ b/projects/Zeta/API/Z/formats/storage_medium_image/audio/Warajevo_TAP.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. .------------------------------------------------------------------. diff --git a/projects/Zeta/API/Z/functions/Objective-C.hpp b/projects/Zeta/API/Z/functions/Objective-C.hpp index 12d49f2..57d4e12 100644 --- a/projects/Zeta/API/Z/functions/Objective-C.hpp +++ b/projects/Zeta/API/Z/functions/Objective-C.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_functions_Objective_C_HPP diff --git a/projects/Zeta/API/Z/functions/atomic.h b/projects/Zeta/API/Z/functions/atomic.h index b83911b..fab7134 100644 --- a/projects/Zeta/API/Z/functions/atomic.h +++ b/projects/Zeta/API/Z/functions/atomic.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_functions_atomic_H @@ -14,7 +14,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ /* MARK: - uint8 */ #ifdef Z_UINT8 - # if Z_COMPILER_HAS_FUNCTION(UINT8_ATOMIC_ADD_THEN_GET) # define z_uint8_atomic_add_then_get Z_COMPILER_FUNCTION(UINT8_ATOMIC_ADD_THEN_GET) # endif @@ -70,13 +69,11 @@ Released under the terms of the GNU Lesser General Public License v3. */ # if Z_COMPILER_HAS_FUNCTION(UINT8_ATOMIC_XOR_THEN_GET) # define z_uint8_atomic_xor_then_get Z_COMPILER_FUNCTION(UINT8_ATOMIC_XOR_THEN_GET) # endif - #endif /* MARK: - sint8 */ #ifdef Z_SINT8 - # if Z_COMPILER_HAS_FUNCTION(SINT8_ATOMIC_ADD_THEN_GET) # define z_sint8_atomic_add_then_get Z_COMPILER_FUNCTION(SINT8_ATOMIC_ADD_THEN_GET) # endif @@ -132,13 +129,11 @@ Released under the terms of the GNU Lesser General Public License v3. */ # if Z_COMPILER_HAS_FUNCTION(SINT8_ATOMIC_XOR_THEN_GET) # define z_sint8_atomic_xor_then_get Z_COMPILER_FUNCTION(SINT8_ATOMIC_XOR_THEN_GET) # endif - #endif /* MARK: - uint16 */ #ifdef Z_UINT16 - # if Z_COMPILER_HAS_FUNCTION(UINT16_ATOMIC_ADD_THEN_GET) # define z_uint16_atomic_add_then_get Z_COMPILER_FUNCTION(UINT16_ATOMIC_ADD_THEN_GET) # endif @@ -194,13 +189,11 @@ Released under the terms of the GNU Lesser General Public License v3. */ # if Z_COMPILER_HAS_FUNCTION(UINT16_ATOMIC_XOR_THEN_GET) # define z_uint16_atomic_xor_then_get Z_COMPILER_FUNCTION(UINT16_ATOMIC_XOR_THEN_GET) # endif - #endif /* MARK: - sint16 */ #ifdef Z_SINT16 - # if Z_COMPILER_HAS_FUNCTION(SINT16_ATOMIC_ADD_THEN_GET) # define z_sint16_atomic_add_then_get Z_COMPILER_FUNCTION(SINT16_ATOMIC_ADD_THEN_GET) # endif @@ -256,13 +249,11 @@ Released under the terms of the GNU Lesser General Public License v3. */ # if Z_COMPILER_HAS_FUNCTION(SINT16_ATOMIC_XOR_THEN_GET) # define z_sint16_atomic_xor_then_get Z_COMPILER_FUNCTION(SINT16_ATOMIC_XOR_THEN_GET) # endif - #endif /* MARK: - uint32 */ #ifdef Z_UINT32 - # if Z_COMPILER_HAS_FUNCTION(UINT32_ATOMIC_ADD_THEN_GET) # define z_uint32_atomic_add_then_get Z_COMPILER_FUNCTION(UINT32_ATOMIC_ADD_THEN_GET) # endif @@ -318,13 +309,11 @@ Released under the terms of the GNU Lesser General Public License v3. */ # if Z_COMPILER_HAS_FUNCTION(UINT32_ATOMIC_XOR_THEN_GET) # define z_uint32_atomic_xor_then_get Z_COMPILER_FUNCTION(UINT32_ATOMIC_XOR_THEN_GET) # endif - #endif /* MARK: - sint32 */ #ifdef Z_SINT32 - # if Z_COMPILER_HAS_FUNCTION(SINT32_ATOMIC_ADD_THEN_GET) # define z_sint32_atomic_add_then_get Z_COMPILER_FUNCTION(SINT32_ATOMIC_ADD_THEN_GET) # endif @@ -380,13 +369,11 @@ Released under the terms of the GNU Lesser General Public License v3. */ # if Z_COMPILER_HAS_FUNCTION(SINT32_ATOMIC_XOR_THEN_GET) # define z_sint32_atomic_xor_then_get Z_COMPILER_FUNCTION(SINT32_ATOMIC_XOR_THEN_GET) # endif - #endif /* MARK: - uint64 */ #ifdef Z_UINT64 - # if Z_COMPILER_HAS_FUNCTION(UINT64_ATOMIC_ADD_THEN_GET) # define z_uint64_atomic_add_then_get Z_COMPILER_FUNCTION(UINT64_ATOMIC_ADD_THEN_GET) # endif @@ -438,13 +425,11 @@ Released under the terms of the GNU Lesser General Public License v3. */ # if Z_COMPILER_HAS_FUNCTION(UINT64_ATOMIC_SUBTRACT_THEN_GET) # define z_uint64_atomic_subtract_then_get Z_COMPILER_FUNCTION(UINT64_ATOMIC_SUBTRACT_THEN_GET) # endif - #endif /* MARK: - sint64 */ #ifdef Z_SINT64 - # if Z_COMPILER_HAS_FUNCTION(UINT64_ATOMIC_XOR_THEN_GET) # define z_uint64_atomic_xor_then_get Z_COMPILER_FUNCTION(UINT64_ATOMIC_XOR_THEN_GET) # endif @@ -504,13 +489,11 @@ Released under the terms of the GNU Lesser General Public License v3. */ # if Z_COMPILER_HAS_FUNCTION(SINT64_ATOMIC_XOR_THEN_GET) # define z_sint64_atomic_xor_then_get Z_COMPILER_FUNCTION(SINT64_ATOMIC_XOR_THEN_GET) # endif - #endif /* MARK: - uint128 */ #ifdef Z_UINT128 - # if Z_COMPILER_HAS_FUNCTION(UINT128_ATOMIC_ADD_THEN_GET) # define z_uint128_atomic_add_then_get Z_COMPILER_FUNCTION(UINT128_ATOMIC_ADD_THEN_GET) # endif @@ -566,13 +549,11 @@ Released under the terms of the GNU Lesser General Public License v3. */ # if Z_COMPILER_HAS_FUNCTION(UINT128_ATOMIC_XOR_THEN_GET) # define z_uint128_atomic_xor_then_get Z_COMPILER_FUNCTION(UINT128_ATOMIC_XOR_THEN_GET) # endif - #endif /* MARK: - sint128 */ #ifdef Z_SINT128 - # if Z_COMPILER_HAS_FUNCTION(SINT128_ATOMIC_ADD_THEN_GET) # define z_sint128_atomic_add_then_get Z_COMPILER_FUNCTION(SINT128_ATOMIC_ADD_THEN_GET) # endif @@ -628,24 +609,50 @@ Released under the terms of the GNU Lesser General Public License v3. */ # if Z_COMPILER_HAS_FUNCTION(SINT128_ATOMIC_XOR_THEN_GET) # define z_sint128_atomic_xor_then_get Z_COMPILER_FUNCTION(SINT128_ATOMIC_XOR_THEN_GET) # endif - #endif /* MARK: - Function selectors */ -#define z_T_atomic_add_then_get( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_add_then_get ) -#define z_T_atomic_and_then_get( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_and_then_get ) -#define z_T_atomic_get_then_add( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_get_then_add ) -#define z_T_atomic_get_then_and( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_get_then_and ) -#define z_T_atomic_get_then_nand( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_get_then_nand ) -#define z_T_atomic_get_then_or( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_get_then_or ) -#define z_T_atomic_get_then_set_if_equal(T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_get_then_set_if_equal) -#define z_T_atomic_get_then_subtract( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_get_then_subtract ) -#define z_T_atomic_get_then_xor( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_get_then_xor ) -#define z_T_atomic_nand_then_get( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_nand_then_get ) -#define z_T_atomic_or_then_get( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_or_then_get ) -#define z_T_atomic_set_if_equal( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_set_if_equal ) -#define z_T_atomic_subtract_then_get( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_subtract_then_get ) -#define z_T_atomic_xor_then_get( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_xor_then_get ) +#define z_T_atomic_add_then_get(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_add_then_get) + +#define z_T_atomic_and_then_get(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_and_then_get) + +#define z_T_atomic_get_then_add(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_get_then_add) + +#define z_T_atomic_get_then_and(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_get_then_and) + +#define z_T_atomic_get_then_nand(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_get_then_nand) + +#define z_T_atomic_get_then_or(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_get_then_or) + +#define z_T_atomic_get_then_set_if_equal(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_get_then_set_if_equal) + +#define z_T_atomic_get_then_subtract(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_get_then_subtract) + +#define z_T_atomic_get_then_xor(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_get_then_xor) + +#define z_T_atomic_nand_then_get(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_nand_then_get) + +#define z_T_atomic_or_then_get(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_or_then_get) + +#define z_T_atomic_set_if_equal(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_set_if_equal) + +#define z_T_atomic_subtract_then_get(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_subtract_then_get) + +#define z_T_atomic_xor_then_get(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _atomic_xor_then_get) #endif /* Z_functions_atomic_H */ diff --git a/projects/Zeta/API/Z/functions/bitwise.h b/projects/Zeta/API/Z/functions/bitwise.h index 2063098..ff5558b 100644 --- a/projects/Zeta/API/Z/functions/bitwise.h +++ b/projects/Zeta/API/Z/functions/bitwise.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_functions_bitwise_H @@ -135,10 +135,19 @@ Released under the terms of the GNU Lesser General Public License v3. */ #undef Z_z_NATURAL_REVERSE #undef Z_z_NATURAL_ROTATE -#define z_T_little_endian(T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _little_endian) -#define z_T_big_endian( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _big_endian ) -#define z_T_pdp_endian( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _pdp_endian ) -#define z_T_rotate_left( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _rotate_left ) -#define z_T_rotate_right( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _rotate_right ) +#define z_T_little_endian(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _little_endian) + +#define z_T_big_endian(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _big_endian) + +#define z_T_pdp_endian(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _pdp_endian) + +#define z_T_rotate_left(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _rotate_left) + +#define z_T_rotate_right(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _rotate_right) #endif /* Z_functions_bitwise_H */ diff --git a/projects/Zeta/API/Z/functions/buffer.h b/projects/Zeta/API/Z/functions/buffer.h index 8d6a38e..5ef7bca 100644 --- a/projects/Zeta/API/Z/functions/buffer.h +++ b/projects/Zeta/API/Z/functions/buffer.h @@ -4,7 +4,7 @@ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ Copyright (C) 2012 Remis. -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_functions_buffer_H diff --git a/projects/Zeta/API/Z/functions/calendar.h b/projects/Zeta/API/Z/functions/calendar.h index 8f5a7ad..ab43027 100644 --- a/projects/Zeta/API/Z/functions/calendar.h +++ b/projects/Zeta/API/Z/functions/calendar.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_functions_calendar_H @@ -14,7 +14,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ static Z_INLINE -boolean z_gregorian_year_is_leap(zulong year) +zbool z_gregorian_year_is_leap(zulong year) {return Z_GREGORIAN_YEAR_IS_LEAP(year);} @@ -29,7 +29,7 @@ zuint8 z_gregorian_year_days_in_month(zulong year, zuint8 month) static Z_INLINE -boolean z_julian_year_is_leap(zulong year) +zbool z_julian_year_is_leap(zulong year) {return Z_JULIAN_YEAR_IS_LEAP(year);} diff --git a/projects/Zeta/API/Z/functions/casting.hpp b/projects/Zeta/API/Z/functions/casting.hpp index bab92de..a5888ea 100644 --- a/projects/Zeta/API/Z/functions/casting.hpp +++ b/projects/Zeta/API/Z/functions/casting.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_functions_casting_HPP diff --git a/projects/Zeta/API/Z/functions/character.h b/projects/Zeta/API/Z/functions/character.h index 7efbcbd..c873dd3 100644 --- a/projects/Zeta/API/Z/functions/character.h +++ b/projects/Zeta/API/Z/functions/character.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_functions_character_H @@ -14,63 +14,63 @@ Released under the terms of the GNU Lesser General Public License v3. */ #include -static Z_INLINE zboolean z_char_is_alphanumeric(zchar value) +static Z_INLINE zbool z_char_is_alphanumeric(zchar value) {return Z_CHAR_IS_ALPHANUMERIC(value);} -static Z_INLINE zboolean z_char_is_ascii(zchar value) +static Z_INLINE zbool z_char_is_ascii(zchar value) {return Z_CHAR_IS_ASCII(value);} -static Z_INLINE zboolean z_char_is_base_2_digit(zchar value) +static Z_INLINE zbool z_char_is_base_2_digit(zchar value) {return Z_CHAR_IS_BASE_2_DIGIT(value);} -static Z_INLINE zboolean z_char_is_base_8_digit(zchar value) +static Z_INLINE zbool z_char_is_base_8_digit(zchar value) {return Z_CHAR_IS_BASE_8_DIGIT(value);} -static Z_INLINE zboolean z_char_is_base_10_digit(zchar value) +static Z_INLINE zbool z_char_is_base_10_digit(zchar value) {return Z_CHAR_IS_BASE_10_DIGIT(value);} -static Z_INLINE zboolean z_char_is_base_16_digit(zchar value) +static Z_INLINE zbool z_char_is_base_16_digit(zchar value) {return Z_CHAR_IS_BASE_16_DIGIT(value);} -static Z_INLINE zboolean z_char_is_base_16_lowercase_digit(zchar value) +static Z_INLINE zbool z_char_is_base_16_lowercase_digit(zchar value) {return Z_CHAR_IS_BASE_16_LOWERCASE_DIGIT(value);} -static Z_INLINE zboolean z_char_is_base_16_uppercase_digit(zchar value) +static Z_INLINE zbool z_char_is_base_16_uppercase_digit(zchar value) {return Z_CHAR_IS_BASE_16_UPPERCASE_DIGIT(value);} -static Z_INLINE zboolean z_char_is_blank(zchar value) +static Z_INLINE zbool z_char_is_blank(zchar value) {return Z_CHAR_IS_BLANK(value);} -static Z_INLINE zboolean z_char_is_control(zchar value) +static Z_INLINE zbool z_char_is_control(zchar value) {return Z_CHAR_IS_CONTROL(value);} -static Z_INLINE zboolean z_char_is_graphical(zchar value) +static Z_INLINE zbool z_char_is_graphical(zchar value) {return Z_CHAR_IS_GRAPHICAL(value);} -static Z_INLINE zboolean z_char_is_letter(zchar value) +static Z_INLINE zbool z_char_is_letter(zchar value) {return Z_CHAR_IS_LETTER(value);} -static Z_INLINE zboolean z_char_is_lowercase_letter(zchar value) +static Z_INLINE zbool z_char_is_lowercase_letter(zchar value) {return Z_CHAR_IS_LOWERCASE_LETTER(value);} -static Z_INLINE zboolean z_char_is_printable(zchar value) +static Z_INLINE zbool z_char_is_printable(zchar value) {return Z_CHAR_IS_PRINTABLE(value);} -static Z_INLINE zboolean z_char_is_uppercase_letter(zchar value) +static Z_INLINE zbool z_char_is_uppercase_letter(zchar value) {return Z_CHAR_IS_UPPERCASE_LETTER(value);} diff --git a/projects/Zeta/API/Z/functions/class.hpp b/projects/Zeta/API/Z/functions/class.hpp index 29159bd..5d8dfb9 100644 --- a/projects/Zeta/API/Z/functions/class.hpp +++ b/projects/Zeta/API/Z/functions/class.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_functions_class_HPP @@ -13,6 +13,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ #include #include #include + namespace Zeta { @@ -31,7 +32,6 @@ namespace Zeta { # if Z_DIALECT_HAS(CPP11, LAMBDA) - template static Z_CT(CPP11) typename TypeIf< Type::is_class && Type::is_default_constructible, @@ -76,8 +76,9 @@ namespace Zeta { template static Z_CT(CPP11) Deleter deleter() Z_NOTHROW {return [](void *object) -> void {delete reinterpret_cast(object);};} - # endif + + } #endif // Z_functions_class_HPP diff --git a/projects/Zeta/API/Z/functions/hash.hpp b/projects/Zeta/API/Z/functions/hash.hpp index fca6c97..96a7331 100644 --- a/projects/Zeta/API/Z/functions/hash.hpp +++ b/projects/Zeta/API/Z/functions/hash.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_functions_hash_HPP @@ -50,7 +50,6 @@ namespace Zeta { # endif } - #undef Z_z_FNV #endif // Z_functions_hash_HPP diff --git a/projects/Zeta/API/Z/functions/math.h b/projects/Zeta/API/Z/functions/math.h index 9d41e4c..f677633 100644 --- a/projects/Zeta/API/Z/functions/math.h +++ b/projects/Zeta/API/Z/functions/math.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_functions_math_H @@ -31,9 +31,14 @@ Released under the terms of the GNU Lesser General Public License v3. */ {return z_##type##_minimum(z_##type##_maximum(value, minimum), maximum);} -#define z_T_clamp( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _clamp ) -#define z_T_maximum(T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _maximum) -#define z_T_minimum(T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _minimum) +#define z_T_clamp(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _clamp) + +#define z_T_maximum(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _maximum) + +#define z_T_minimum(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL)(z_, _minimum) /* MARK: - Partial implementation for signed types */ @@ -50,8 +55,11 @@ Released under the terms of the GNU Lesser General Public License v3. */ {return value >= (z##type)0 ? (z##type)1 : -(z##type)1;} -#define z_T_absolute(T) Z_INSERT_type(Z_##TYPE##_FIXED_FUNDAMENTAL(z_, _absolute) -#define z_T_sign( T) Z_INSERT_type(Z_##TYPE##_FIXED_FUNDAMENTAL(z_, _sign ) +#define z_T_absolute(T) \ + Z_INSERT_type(Z_##TYPE##_FIXED_FUNDAMENTAL(z_, _absolute) + +#define z_T_sign(T) \ + Z_INSERT_type(Z_##TYPE##_FIXED_FUNDAMENTAL(z_, _sign) /* MARK: - Implementation for real types */ @@ -59,7 +67,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ #define Z_z_IMPLEMENTATION_REAL(type, _, epsilon, infinity) \ \ static Z_INLINE \ - zboolean z_##type##_are_almost_equal(z##type a, z##type b) \ + zbool z_##type##_are_almost_equal(z##type a, z##type b) \ {return z_##type##_absolute(a - b) <= epsilon;} \ \ \ @@ -74,22 +82,22 @@ Released under the terms of the GNU Lesser General Public License v3. */ \ \ static Z_INLINE \ - zboolean z_##type##_is_almost_zero(z##type value) \ + zbool z_##type##_is_almost_zero(z##type value) \ {return z_##type##_absolute(value) <= epsilon;} \ \ \ static Z_INLINE \ - zboolean z_##type##_is_finite(z##type value) \ + zbool z_##type##_is_finite(z##type value) \ {return value == value && value != infinity && value != -infinity;} \ \ \ static Z_INLINE \ - zboolean z_##type##_is_infinity(z##type value) \ + zbool z_##type##_is_infinity(z##type value) \ {return value == infinity || value == -infinity;} \ \ \ static Z_INLINE \ - zboolean z_##type##_is_nan(z##type value) \ + zbool z_##type##_is_nan(z##type value) \ {return !(value == value);} \ \ \ @@ -127,17 +135,38 @@ Released under the terms of the GNU Lesser General Public License v3. */ } -#define z_T_are_almost_equal(T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _are_almost_equal) -#define z_T_clamp_01( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _clamp_01 ) -#define z_T_inverse_lerp( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _inverse_lerp ) -#define z_T_is_almost_zero( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _is_almost_zero ) -#define z_T_is_finite( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _is_finite ) -#define z_T_is_infinity( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _is_infinity ) -#define z_T_is_nan( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _is_nan ) -#define z_T_lerp( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _lerp ) -#define z_T_sign_or_zero( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _sign_or_zero ) -#define z_T_smootherstep( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _smootherstep ) -#define z_T_smoothstep( T) Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _smoothstep ) +#define z_T_are_almost_equal(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _are_almost_equal) + +#define z_T_clamp_01(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _clamp_01) + +#define z_T_inverse_lerp(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _inverse_lerp) + +#define z_T_is_almost_zero(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _is_almost_zero) + +#define z_T_is_finite(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _is_finite) + +#define z_T_is_infinity(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _is_infinity) + +#define z_T_is_nan(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _is_nan) + +#define z_T_lerp(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _lerp) + +#define z_T_sign_or_zero(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _sign_or_zero) + +#define z_T_smootherstep(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _smootherstep) + +#define z_T_smoothstep(T) \ + Z_INSERT_type(Z_##T##_FIXED_FUNDAMENTAL(z_, _smoothstep) /* MARK: - uint8 */ @@ -146,47 +175,47 @@ Z_z_IMPLEMENTATION_COMMON(uint8) static Z_INLINE -zboolean z_uint8_addition_overflows(zuint8 a, zuint8 b) +zbool z_uint8_addition_overflows(zuint8 a, zuint8 b) {return (zuint16)a + (zuint16)b > Z_UINT8_MAXIMUM;} static Z_INLINE -zboolean z_uint8_addition_overflows_3(zuint8 a, zuint8 b, zuint8 c) +zbool z_uint8_addition_overflows_3(zuint8 a, zuint8 b, zuint8 c) {return (zuint16)a + (zuint16)b + (zuint16)c > Z_UINT8_MAXIMUM;} static Z_INLINE -zboolean z_uint8_addition_overflows_4(zuint8 a, zuint8 b, zuint8 c, zuint8 d) +zbool z_uint8_addition_overflows_4(zuint8 a, zuint8 b, zuint8 c, zuint8 d) {return (zuint16)a + (zuint16)b + (zuint16)c + (zuint16)d > Z_UINT8_MAXIMUM;} static Z_INLINE -zboolean z_uint8_multiplication_overflows(zuint8 a, zuint8 b) +zbool z_uint8_multiplication_overflows(zuint8 a, zuint8 b) {return (zuint16)a * (zuint16)b > Z_UINT8_MAXIMUM;} /*static Z_INLINE -zboolean z_uint8_multiplication_overflows_3(zuint8 a, zuint8 b, zuint8 c) +zbool z_uint8_multiplication_overflows_3(zuint8 a, zuint8 b, zuint8 c) {return Z_FALSE;} static Z_INLINE -zboolean z_uint8_multiplication_overflows_4(zuint8 a, zuint8 b, zuint8 c, zuint8 d) +zbool z_uint8_multiplication_overflows_4(zuint8 a, zuint8 b, zuint8 c, zuint8 d) {return Z_FALSE;}*/ static Z_INLINE -zboolean z_uint8_subtraction_overflows(zuint8 a, zuint8 b) +zbool z_uint8_subtraction_overflows(zuint8 a, zuint8 b) {return b > a;} /*static Z_INLINE -zboolean z_uint8_subtraction_overflows_3(zuint8 a, zuint8 b, zuint8 c) +zbool z_uint8_subtraction_overflows_3(zuint8 a, zuint8 b, zuint8 c) {return Z_FALSE;} static Z_INLINE -zboolean z_uint8_subtraction_overflows_4(zuint8 a, zuint8 b, zuint8 c, zuint8 d) +zbool z_uint8_subtraction_overflows_4(zuint8 a, zuint8 b, zuint8 c, zuint8 d) {return Z_FALSE;}*/ @@ -197,47 +226,47 @@ Z_z_IMPLEMENTATION_SIGNED(sint8) /*static Z_INLINE -zboolean z_sint8_addition_overflows(zsint8 a, zsint8 b) +zbool z_sint8_addition_overflows(zsint8 a, zsint8 b) {return Z_FALSE;} static Z_INLINE -zboolean z_sint8_addition_overflows_3(zsint8 a, zsint8 b, zsint8 c) +zbool z_sint8_addition_overflows_3(zsint8 a, zsint8 b, zsint8 c) {return Z_FALSE;} static Z_INLINE -zboolean z_sint8_addition_overflows_4(zsint8 a, zsint8 b, zsint8 c, zsint8 d) +zbool z_sint8_addition_overflows_4(zsint8 a, zsint8 b, zsint8 c, zsint8 d) {return Z_FALSE;} static Z_INLINE -zboolean z_sint8_multiplication_overflows(zsint8 a, zsint8 b) +zbool z_sint8_multiplication_overflows(zsint8 a, zsint8 b) {return Z_FALSE;} static Z_INLINE -zboolean z_sint8_multiplication_overflows_3(zsint8 a, zsint8 b, zsint8 c) +zbool z_sint8_multiplication_overflows_3(zsint8 a, zsint8 b, zsint8 c) {return Z_FALSE;} static Z_INLINE -zboolean z_sint8_multiplication_overflows_4(zsint8 a, zsint8 b, zsint8 c, zsint8 d) +zbool z_sint8_multiplication_overflows_4(zsint8 a, zsint8 b, zsint8 c, zsint8 d) {return Z_FALSE;} static Z_INLINE -zboolean z_sint8_subtraction_overflows(zsint8 a, zsint8 b) +zbool z_sint8_subtraction_overflows(zsint8 a, zsint8 b) {return Z_FALSE;} static Z_INLINE -zboolean z_sint8_subtraction_overflows_3(zsint8 a, zsint8 b, zsint8 c) +zbool z_sint8_subtraction_overflows_3(zsint8 a, zsint8 b, zsint8 c) {return Z_FALSE;} static Z_INLINE -zboolean z_sint8_subtraction_overflows_4(zsint8 a, zsint8 b, zsint8 c, zsint8 d) +zbool z_sint8_subtraction_overflows_4(zsint8 a, zsint8 b, zsint8 c, zsint8 d) {return Z_FALSE;}*/ @@ -247,47 +276,47 @@ Z_z_IMPLEMENTATION_COMMON(uint16) static Z_INLINE -zboolean z_uint16_addition_overflows(zuint16 a, zuint16 b) +zbool z_uint16_addition_overflows(zuint16 a, zuint16 b) {return (zuint32)a + (zuint32)b > Z_UINT16_MAXIMUM;} static Z_INLINE -zboolean z_uint16_addition_overflows_3(zuint16 a, zuint16 b, zuint16 c) +zbool z_uint16_addition_overflows_3(zuint16 a, zuint16 b, zuint16 c) {return (zuint32)a + (zuint32)b + (zuint32)c > Z_UINT16_MAXIMUM;} static Z_INLINE -zboolean z_uint16_addition_overflows_4(zuint16 a, zuint16 b, zuint16 c, zuint16 d) +zbool z_uint16_addition_overflows_4(zuint16 a, zuint16 b, zuint16 c, zuint16 d) {return (zuint32)a + (zuint32)b + (zuint32)c + (zuint32)d > Z_UINT16_MAXIMUM;} static Z_INLINE -zboolean z_uint16_multiplication_overflows(zuint16 a, zuint16 b) +zbool z_uint16_multiplication_overflows(zuint16 a, zuint16 b) {return (zuint32)a * (zuint32)b > Z_UINT16_MAXIMUM;} /*static Z_INLINE -zboolean z_uint16_multiplication_overflows_3(zuint16 a, zuint16 b, zuint16 c) +zbool z_uint16_multiplication_overflows_3(zuint16 a, zuint16 b, zuint16 c) {return Z_FALSE;} static Z_INLINE -zboolean z_uint16_multiplication_overflows_4(zuint16 a, zuint16 b, zuint16 c, zuint16 d) +zbool z_uint16_multiplication_overflows_4(zuint16 a, zuint16 b, zuint16 c, zuint16 d) {return Z_FALSE;}*/ static Z_INLINE -zboolean z_uint16_subtraction_overflows(zuint16 a, zuint16 b) +zbool z_uint16_subtraction_overflows(zuint16 a, zuint16 b) {return b > a;} /*static Z_INLINE -zboolean z_uint16_subtraction_overflows_3(zuint16 a, zuint16 b, zuint16 c) +zbool z_uint16_subtraction_overflows_3(zuint16 a, zuint16 b, zuint16 c) {return Z_FALSE;} static Z_INLINE -zboolean z_uint16_subtraction_overflows_4(zuint16 a, zuint16 b, zuint16 c, zuint16 d) +zbool z_uint16_subtraction_overflows_4(zuint16 a, zuint16 b, zuint16 c, zuint16 d) {return Z_FALSE;}*/ @@ -298,47 +327,47 @@ Z_z_IMPLEMENTATION_SIGNED(sint16) /*static Z_INLINE -zboolean z_sint16_addition_overflows(zsint16 a, zsint16 b) +zbool z_sint16_addition_overflows(zsint16 a, zsint16 b) {return Z_FALSE;} static Z_INLINE -zboolean z_sint16_addition_overflows_3(zsint16 a, zsint16 b, zsint16 c) +zbool z_sint16_addition_overflows_3(zsint16 a, zsint16 b, zsint16 c) {return Z_FALSE;} static Z_INLINE -zboolean z_sint16_addition_overflows_4(zsint16 a, zsint16 b, zsint16 c, zsint16 d) +zbool z_sint16_addition_overflows_4(zsint16 a, zsint16 b, zsint16 c, zsint16 d) {return Z_FALSE;} static Z_INLINE -zboolean z_sint16_multiplication_overflows(zsint16 a, zsint16 b) +zbool z_sint16_multiplication_overflows(zsint16 a, zsint16 b) {return Z_FALSE;} static Z_INLINE -zboolean z_sint16_multiplication_overflows_3(zsint16 a, zsint16 b, zsint16 c) +zbool z_sint16_multiplication_overflows_3(zsint16 a, zsint16 b, zsint16 c) {return Z_FALSE;} static Z_INLINE -zboolean z_sint16_multiplication_overflows_4(zsint16 a, zsint16 b, zsint16 c, zsint16 d) +zbool z_sint16_multiplication_overflows_4(zsint16 a, zsint16 b, zsint16 c, zsint16 d) {return Z_FALSE;} static Z_INLINE -zboolean z_sint16_subtraction_overflows(zsint16 a, zsint16 b) +zbool z_sint16_subtraction_overflows(zsint16 a, zsint16 b) {return Z_FALSE;} static Z_INLINE -zboolean z_sint16_subtraction_overflows_3(zsint16 a, zsint16 b, zsint16 c) +zbool z_sint16_subtraction_overflows_3(zsint16 a, zsint16 b, zsint16 c) {return Z_FALSE;} static Z_INLINE -zboolean z_sint16_subtraction_overflows_4(zsint16 a, zsint16 b, zsint16 c, zsint16 d) +zbool z_sint16_subtraction_overflows_4(zsint16 a, zsint16 b, zsint16 c, zsint16 d) {return Z_FALSE;}*/ @@ -348,47 +377,47 @@ Z_z_IMPLEMENTATION_COMMON(uint32) /*static Z_INLINE -zboolean z_uint32_addition_overflows(zuint32 a, zuint32 b) +zbool z_uint32_addition_overflows(zuint32 a, zuint32 b) {return Z_FALSE;} static Z_INLINE -zboolean z_uint32_addition_overflows_3(zuint32 a, zuint32 b, zuint32 c) +zbool z_uint32_addition_overflows_3(zuint32 a, zuint32 b, zuint32 c) {return Z_FALSE;} static Z_INLINE -zboolean z_uint32_addition_overflows_4(zuint32 a, zuint32 b, zuint32 c, zuint32 d) +zbool z_uint32_addition_overflows_4(zuint32 a, zuint32 b, zuint32 c, zuint32 d) {return Z_FALSE;} static Z_INLINE -zboolean z_uint32_multiplication_overflows(zuint32 a, zuint32 b) +zbool z_uint32_multiplication_overflows(zuint32 a, zuint32 b) {return Z_FALSE;} static Z_INLINE -zboolean z_uint32_multiplication_overflows_3(zuint32 a, zuint32 b, zuint32 c) +zbool z_uint32_multiplication_overflows_3(zuint32 a, zuint32 b, zuint32 c) {return Z_FALSE;} static Z_INLINE -zboolean z_uint32_multiplication_overflows_4(zuint32 a, zuint32 b, zuint32 c, zuint32 d) +zbool z_uint32_multiplication_overflows_4(zuint32 a, zuint32 b, zuint32 c, zuint32 d) {return Z_FALSE;} static Z_INLINE -zboolean z_uint32_subtraction_overflows(zuint32 a, zuint32 b) +zbool z_uint32_subtraction_overflows(zuint32 a, zuint32 b) {return b > a;} static Z_INLINE -zboolean z_uint32_subtraction_overflows_3(zuint32 a, zuint32 b, zuint32 c) +zbool z_uint32_subtraction_overflows_3(zuint32 a, zuint32 b, zuint32 c) {return Z_FALSE;} static Z_INLINE -zboolean z_uint32_subtraction_overflows_4(zuint32 a, zuint32 b, zuint32 c, zuint32 d) +zbool z_uint32_subtraction_overflows_4(zuint32 a, zuint32 b, zuint32 c, zuint32 d) {return Z_FALSE;}*/ @@ -399,47 +428,47 @@ Z_z_IMPLEMENTATION_SIGNED(sint32) /*static Z_INLINE -zboolean z_sint32_addition_overflows(zsint32 a, zsint32 b) +zbool z_sint32_addition_overflows(zsint32 a, zsint32 b) {return Z_FALSE;} static Z_INLINE -zboolean z_sint32_addition_overflows_3(zsint32 a, zsint32 b, zsint32 c) +zbool z_sint32_addition_overflows_3(zsint32 a, zsint32 b, zsint32 c) {return Z_FALSE;} static Z_INLINE -zboolean z_sint32_addition_overflows_4(zsint32 a, zsint32 b, zsint32 c, zsint32 d) +zbool z_sint32_addition_overflows_4(zsint32 a, zsint32 b, zsint32 c, zsint32 d) {return Z_FALSE;} static Z_INLINE -zboolean z_sint32_multiplication_overflows(zsint32 a, zsint32 b) +zbool z_sint32_multiplication_overflows(zsint32 a, zsint32 b) {return Z_FALSE;} static Z_INLINE -zboolean z_sint32_multiplication_overflows_3(zsint32 a, zsint32 b, zsint32 c) +zbool z_sint32_multiplication_overflows_3(zsint32 a, zsint32 b, zsint32 c) {return Z_FALSE;} static Z_INLINE -zboolean z_sint32_multiplication_overflows_4(zsint32 a, zsint32 b, zsint32 c, zsint32 d) +zbool z_sint32_multiplication_overflows_4(zsint32 a, zsint32 b, zsint32 c, zsint32 d) {return Z_FALSE;} static Z_INLINE -zboolean z_sint32_subtraction_overflows(zsint32 a, zsint32 b) +zbool z_sint32_subtraction_overflows(zsint32 a, zsint32 b) {return Z_FALSE;} static Z_INLINE -zboolean z_sint32_subtraction_overflows_3(zsint32 a, zsint32 b, zsint32 c) +zbool z_sint32_subtraction_overflows_3(zsint32 a, zsint32 b, zsint32 c) {return Z_FALSE;} static Z_INLINE -zboolean z_sint32_subtraction_overflows_4(zsint32 a, zsint32 b, zsint32 c, zsint32 d) +zbool z_sint32_subtraction_overflows_4(zsint32 a, zsint32 b, zsint32 c, zsint32 d) {return Z_FALSE;}*/ @@ -451,46 +480,46 @@ zboolean z_sint32_subtraction_overflows_4(zsint32 a, zsint32 b, zsint32 c, zsint /*static Z_INLINE - zboolean z_uint64_addition_overflows(zuint64 a, zuint64 b) + zbool z_uint64_addition_overflows(zuint64 a, zuint64 b) {return Z_FALSE;} static Z_INLINE - zboolean z_uint64_addition_overflows_3(zuint64 a, zuint64 b, zuint64 c) + zbool z_uint64_addition_overflows_3(zuint64 a, zuint64 b, zuint64 c) {return Z_FALSE;} static Z_INLINE - zboolean z_uint64_addition_overflows_4(zuint64 a, zuint64 b, zuint64 c, zuint64 d) + zbool z_uint64_addition_overflows_4(zuint64 a, zuint64 b, zuint64 c, zuint64 d) {return Z_FALSE;} static Z_INLINE - zboolean z_uint64_multiplication_overflows(zuint64 a, zuint64 b) + zbool z_uint64_multiplication_overflows(zuint64 a, zuint64 b) {return Z_FALSE;} static Z_INLINE - zboolean z_uint64_multiplication_overflows_3(zuint64 a, zuint64 b, zuint64 c) + zbool z_uint64_multiplication_overflows_3(zuint64 a, zuint64 b, zuint64 c) {return Z_FALSE;} static Z_INLINE - zboolean z_uint64_multiplication_overflows_4(zuint64 a, zuint64 b, zuint64 c, zuint64 d) + zbool z_uint64_multiplication_overflows_4(zuint64 a, zuint64 b, zuint64 c, zuint64 d) {return Z_FALSE;} static Z_INLINE - zboolean z_uint64_subtraction_overflows(zuint64 a, zuint64 b) + zbool z_uint64_subtraction_overflows(zuint64 a, zuint64 b) {return b > a;} static Z_INLINE - zboolean z_uint64_subtraction_overflows_3(zuint64 a, zuint64 b, zuint64 c) + zbool z_uint64_subtraction_overflows_3(zuint64 a, zuint64 b, zuint64 c) {return Z_FALSE;} static Z_INLINE - zboolean z_uint64_subtraction_overflows_4(zuint64 a, zuint64 b, zuint64 c, zuint64 d) + zbool z_uint64_subtraction_overflows_4(zuint64 a, zuint64 b, zuint64 c, zuint64 d) {return Z_FALSE;}*/ #endif @@ -505,47 +534,47 @@ zboolean z_sint32_subtraction_overflows_4(zsint32 a, zsint32 b, zsint32 c, zsint /*static Z_INLINE - zboolean z_sint64_addition_overflows(zsint64 a, zsint64 b) + zbool z_sint64_addition_overflows(zsint64 a, zsint64 b) {return Z_FALSE;} static Z_INLINE - zboolean z_sint64_addition_overflows_3(zsint64 a, zsint64 b, zsint64 c) + zbool z_sint64_addition_overflows_3(zsint64 a, zsint64 b, zsint64 c) {return Z_FALSE;} static Z_INLINE - zboolean z_sint64_addition_overflows_4(zsint64 a, zsint64 b, zsint64 c, zsint64 d) + zbool z_sint64_addition_overflows_4(zsint64 a, zsint64 b, zsint64 c, zsint64 d) {return Z_FALSE;} static Z_INLINE - zboolean z_sint64_multiplication_overflows(zsint64 a, zsint64 b) + zbool z_sint64_multiplication_overflows(zsint64 a, zsint64 b) {return Z_FALSE;} static Z_INLINE - zboolean z_sint64_multiplication_overflows_3(zsint64 a, zsint64 b, zsint64 c) + zbool z_sint64_multiplication_overflows_3(zsint64 a, zsint64 b, zsint64 c) {return Z_FALSE;} static Z_INLINE - zboolean z_sint64_multiplication_overflows_4(zsint64 a, zsint64 b, zsint64 c, zsint64 d) + zbool z_sint64_multiplication_overflows_4(zsint64 a, zsint64 b, zsint64 c, zsint64 d) {return Z_FALSE;} static Z_INLINE - zboolean z_sint64_subtraction_overflows(zsint64 a, zsint64 b) + zbool z_sint64_subtraction_overflows(zsint64 a, zsint64 b) {return Z_FALSE;} static Z_INLINE - zboolean z_sint64_subtraction_overflows_3(zsint64 a, zsint64 b, zsint64 c) + zbool z_sint64_subtraction_overflows_3(zsint64 a, zsint64 b, zsint64 c) {return Z_FALSE;} static Z_INLINE - zboolean z_sint64_subtraction_overflows_4(zsint64 a, zsint64 b, zsint64 c, zsint64 d) + zbool z_sint64_subtraction_overflows_4(zsint64 a, zsint64 b, zsint64 c, zsint64 d) {return Z_FALSE;}*/ #endif @@ -559,47 +588,47 @@ zboolean z_sint32_subtraction_overflows_4(zsint32 a, zsint32 b, zsint32 c, zsint /*static Z_INLINE - zboolean z_uint128_addition_overflows(zuint128 a, zuint128 b) + zbool z_uint128_addition_overflows(zuint128 a, zuint128 b) {return Z_FALSE;} static Z_INLINE - zboolean z_uint128_addition_overflows_3(zuint128 a, zuint128 b, zuint128 c) + zbool z_uint128_addition_overflows_3(zuint128 a, zuint128 b, zuint128 c) {return Z_FALSE;} static Z_INLINE - zboolean z_uint128_addition_overflows_4(zuint128 a, zuint128 b, zuint128 c, zuint128 d) + zbool z_uint128_addition_overflows_4(zuint128 a, zuint128 b, zuint128 c, zuint128 d) {return Z_FALSE;} static Z_INLINE - zboolean z_uint128_multiplication_overflows(zuint128 a, zuint128 b) + zbool z_uint128_multiplication_overflows(zuint128 a, zuint128 b) {return Z_FALSE;} static Z_INLINE - zboolean z_uint128_multiplication_overflows_3(zuint128 a, zuint128 b, zuint128 c) + zbool z_uint128_multiplication_overflows_3(zuint128 a, zuint128 b, zuint128 c) {return Z_FALSE;} static Z_INLINE - zboolean z_uint128_multiplication_overflows_4(zuint128 a, zuint128 b, zuint128 c, zuint128 d) + zbool z_uint128_multiplication_overflows_4(zuint128 a, zuint128 b, zuint128 c, zuint128 d) {return Z_FALSE;} static Z_INLINE - zboolean z_uint128_subtraction_overflows(zuint128 a, zuint128 b) + zbool z_uint128_subtraction_overflows(zuint128 a, zuint128 b) {return b > a;} static Z_INLINE - zboolean z_uint128_subtraction_overflows_3(zuint128 a, zuint128 b, zuint128 c) + zbool z_uint128_subtraction_overflows_3(zuint128 a, zuint128 b, zuint128 c) {return Z_FALSE;} static Z_INLINE - zboolean z_uint128_subtraction_overflows_4(zuint128 a, zuint128 b, zuint128 c, zuint128 d) + zbool z_uint128_subtraction_overflows_4(zuint128 a, zuint128 b, zuint128 c, zuint128 d) {return Z_FALSE;}*/ #endif @@ -614,47 +643,47 @@ zboolean z_sint32_subtraction_overflows_4(zsint32 a, zsint32 b, zsint32 c, zsint /*static Z_INLINE - zboolean z_sint128_addition_overflows(zsint128 a, zsint128 b) + zbool z_sint128_addition_overflows(zsint128 a, zsint128 b) {return Z_FALSE;} static Z_INLINE - zboolean z_sint128_addition_overflows_3(zsint128 a, zsint128 b, zsint128 c) + zbool z_sint128_addition_overflows_3(zsint128 a, zsint128 b, zsint128 c) {return Z_FALSE;} static Z_INLINE - zboolean z_sint128_addition_overflows_4(zsint128 a, zsint128 b, zsint128 c, zsint128 d) + zbool z_sint128_addition_overflows_4(zsint128 a, zsint128 b, zsint128 c, zsint128 d) {return Z_FALSE;} static Z_INLINE - zboolean z_sint128_multiplication_overflows(zsint128 a, zsint128 b) + zbool z_sint128_multiplication_overflows(zsint128 a, zsint128 b) {return Z_FALSE;} static Z_INLINE - zboolean z_sint128_multiplication_overflows_3(zsint128 a, zsint128 b, zsint128 c) + zbool z_sint128_multiplication_overflows_3(zsint128 a, zsint128 b, zsint128 c) {return Z_FALSE;} static Z_INLINE - zboolean z_sint128_multiplication_overflows_4(zsint128 a, zsint128 b, zsint128 c, zsint128 d) + zbool z_sint128_multiplication_overflows_4(zsint128 a, zsint128 b, zsint128 c, zsint128 d) {return Z_FALSE;} static Z_INLINE - zboolean z_sint128_subtraction_overflows(zsint128 a, zsint128 b) + zbool z_sint128_subtraction_overflows(zsint128 a, zsint128 b) {return Z_FALSE;} static Z_INLINE - zboolean z_sint128_subtraction_overflows_3(zsint128 a, zsint128 b, zsint128 c) + zbool z_sint128_subtraction_overflows_3(zsint128 a, zsint128 b, zsint128 c) {return Z_FALSE;} static Z_INLINE - zboolean z_sint128_subtraction_overflows_4(zsint128 a, zsint128 b, zsint128 c, zsint128 d) + zbool z_sint128_subtraction_overflows_4(zsint128 a, zsint128 b, zsint128 c, zsint128 d) {return Z_FALSE;}*/ #endif @@ -731,16 +760,32 @@ zboolean z_sint32_subtraction_overflows_4(zsint32 a, zsint32 b, zsint32 c, zsint /* MARK: - Function selectors */ +#define z_T_addition_overflows(TYPE) \ + Z_INSERT_##T##_fixed_type(z_, _addition_overflows) -#define z_T_addition_overflows( TYPE) Z_INSERT_##T##_fixed_type(z_, _addition_overflows ) -#define z_T_addition_overflows_3( TYPE) Z_INSERT_##T##_fixed_type(z_, _addition_overflows_3 ) -#define z_T_addition_overflows_4( TYPE) Z_INSERT_##T##_fixed_type(z_, _addition_overflows_4 ) -#define z_T_multiplication_overflows( TYPE) Z_INSERT_##T##_fixed_type(z_, _addition_overflows ) -#define z_T_multiplication_overflows_3(TYPE) Z_INSERT_##T##_fixed_type(z_, _addition_overflows_3 ) -#define z_T_multiplication_overflows_4(TYPE) Z_INSERT_##T##_fixed_type(z_, _addition_overflows_4 ) -#define z_T_subtraction_overflows( TYPE) Z_INSERT_##T##_fixed_type(z_, _subtraction_overflows ) -#define z_T_subtraction_overflows_3( TYPE) Z_INSERT_##T##_fixed_type(z_, _subtraction_overflows_3) -#define z_T_subtraction_overflows_4( TYPE) Z_INSERT_##T##_fixed_type(z_, _subtraction_overflows_4) +#define z_T_addition_overflows_3(TYPE) \ + Z_INSERT_##T##_fixed_type(z_, _addition_overflows_3) + +#define z_T_addition_overflows_4(TYPE) \ + Z_INSERT_##T##_fixed_type(z_, _addition_overflows_4) + +#define z_T_multiplication_overflows(TYPE) \ + Z_INSERT_##T##_fixed_type(z_, _addition_overflows) + +#define z_T_multiplication_overflows_3(TYPE) \ + Z_INSERT_##T##_fixed_type(z_, _addition_overflows_3) + +#define z_T_multiplication_overflows_4(TYPE) \ + Z_INSERT_##T##_fixed_type(z_, _addition_overflows_4) + +#define z_T_subtraction_overflows(TYPE) \ + Z_INSERT_##T##_fixed_type(z_, _subtraction_overflows) + +#define z_T_subtraction_overflows_3(TYPE) \ + Z_INSERT_##T##_fixed_type(z_, _subtraction_overflows_3) + +#define z_T_subtraction_overflows_4(TYPE) \ + Z_INSERT_##T##_fixed_type(z_, _subtraction_overflows_4) /* MARK: - Default real type definitions */ diff --git a/projects/Zeta/API/Z/functions/math.hpp b/projects/Zeta/API/Z/functions/math.hpp index e432b91..198a643 100644 --- a/projects/Zeta/API/Z/functions/math.hpp +++ b/projects/Zeta/API/Z/functions/math.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_functions_math_HPP @@ -11,9 +11,9 @@ Released under the terms of the GNU Lesser General Public License v3. */ #include - namespace Zeta { + template static Z_CT(CPP11) t maximum(t a, t b) Z_NOTHROW {return a > b ? a : b;} @@ -31,7 +31,6 @@ namespace Zeta { // MARK: - Functions for signed types - template static Z_CT(CPP11) t absolute(t value) Z_NOTHROW {return value < t(0) ? -value : value;} @@ -44,9 +43,8 @@ namespace Zeta { // MARK: - Functions for real types - template - static Z_CT(CPP11) Boolean are_almost_equal(t a, t b) Z_NOTHROW + static Z_CT(CPP11) Bool are_almost_equal(t a, t b) Z_NOTHROW {return absolute(a - b) <= Type::epsilon();} @@ -61,12 +59,12 @@ namespace Zeta { template - static Z_CT(CPP11) Boolean is_almost_zero(t value) Z_NOTHROW + static Z_CT(CPP11) Bool is_almost_zero(t value) Z_NOTHROW {return absolute(value) <= Type::epsilon();} template - static Z_CT(CPP11) Boolean is_finite(t value) Z_NOTHROW + static Z_CT(CPP11) Bool is_finite(t value) Z_NOTHROW { return value == value && value != Type::infinity() && @@ -75,14 +73,14 @@ namespace Zeta { template - static Z_CT(CPP11) Boolean is_infinity(t value) Z_NOTHROW + static Z_CT(CPP11) Bool is_infinity(t value) Z_NOTHROW { return value == Type::infinity() || value == -Type::infinity();} template - static Z_CT(CPP11) Boolean is_nan(t value) Z_NOTHROW + static Z_CT(CPP11) Bool is_nan(t value) Z_NOTHROW {return !(value == value);} @@ -118,7 +116,8 @@ namespace Zeta { x = (x - a) / (b - a); return x * x * (t(3.0) - t(2.0) * x); } + + } - #endif // Z_functions_math_HPP diff --git a/projects/Zeta/API/Z/functions/type.hpp b/projects/Zeta/API/Z/functions/type.hpp index 8639f18..ee57364 100644 --- a/projects/Zeta/API/Z/functions/type.hpp +++ b/projects/Zeta/API/Z/functions/type.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_functions_type_HPP @@ -11,11 +11,10 @@ Released under the terms of the GNU Lesser General Public License v3. */ #include - namespace Zeta { -# if Z_COMPILER_IS(GCC) || Z_COMPILER_IS(CLANG) || Z_COMPILER_IS(APPLE_CLANG) +# if Z_COMPILER_IS(GCC) || Z_COMPILER_IS(CLANG) || Z_COMPILER_IS(APPLE_CLANG) template static Z_CT(CPP14) USize type_string_size() Z_NOTHROW { @@ -46,9 +45,9 @@ namespace Zeta { # elif Z_COMPILER_IS(MSVC) - # endif + + } - #endif // Z_functions_type_HPP diff --git a/projects/Zeta/API/Z/functions/unevaluated.hpp b/projects/Zeta/API/Z/functions/unevaluated.hpp index 8941d50..4468649 100644 --- a/projects/Zeta/API/Z/functions/unevaluated.hpp +++ b/projects/Zeta/API/Z/functions/unevaluated.hpp @@ -3,17 +3,15 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_functions_unevaluated_HPP #define Z_functions_unevaluated_HPP - namespace Zeta { template t fake() Z_NOTHROW; } - #endif // Z_functions_unevaluated_HPP diff --git a/projects/Zeta/API/Z/hardware/ISA/6502.h b/projects/Zeta/API/Z/hardware/ISA/6502.h index dd43dfa..3590502 100644 --- a/projects/Zeta/API/Z/hardware/ISA/6502.h +++ b/projects/Zeta/API/Z/hardware/ISA/6502.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_hardware_ISA_6502_H diff --git a/projects/Zeta/API/Z/hardware/ISA/RISC-V.h b/projects/Zeta/API/Z/hardware/ISA/RISC-V.h index a92a787..1a3a5da 100644 --- a/projects/Zeta/API/Z/hardware/ISA/RISC-V.h +++ b/projects/Zeta/API/Z/hardware/ISA/RISC-V.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_hardware_ISA_RISC_V_H @@ -125,11 +125,11 @@ Released under the terms of the GNU Lesser General Public License v3. */ #define Z_RISC_V_CSR_HGATP 0x680 /* Debug/Trace Registers */ -#define Z_RISC_V_CSR_hcontext 0x6A8 +#define Z_RISC_V_CSR_HCONTEXT 0x6A8 /* Hypervisor Counter/Timer Virtualization Registers */ -#define Z_RISC_V_CSR_htimedelta 0x605 -#define Z_RISC_V_CSR_htimedeltah 0x615 +#define Z_RISC_V_CSR_HTIMEDELTA 0x605 +#define Z_RISC_V_CSR_HTIMEDELTAH 0x615 /* Virtual Supervisor Registers */ #define Z_RISC_V_CSR_VSSTATUS 0x200 diff --git a/projects/Zeta/API/Z/hardware/bus/USB.h b/projects/Zeta/API/Z/hardware/bus/USB.h index 22c6b86..40af1c4 100644 --- a/projects/Zeta/API/Z/hardware/bus/USB.h +++ b/projects/Zeta/API/Z/hardware/bus/USB.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_hardware_bus_USB_H diff --git a/projects/Zeta/API/Z/hardware/machine/computer/ZX_Spectrum.h b/projects/Zeta/API/Z/hardware/machine/computer/ZX_Spectrum.h index ed9085b..200b8fe 100644 --- a/projects/Zeta/API/Z/hardware/machine/computer/ZX_Spectrum.h +++ b/projects/Zeta/API/Z/hardware/machine/computer/ZX_Spectrum.h @@ -14,7 +14,7 @@ /______/_/ \_\ |______/| ___/ \____/ \____| |_| |_| |____,_|_| |_| |_| |_| -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. @@ -274,10 +274,10 @@ Released under the terms of the GNU Lesser General Public License v3. | Firmware | 0 | 1 | |-----------|-----+=====' | 4000-7FFF | RAM | -| Screen 1 | 5 | +| Screen 0 | 5 | |-----------|-----| | 8000-BFFF | RAM | -| | 2 | Screen 2 +| | 2 | Screen 1 |-----------|-----+--------------------------------------|--. | C000-FFFF | RAM | RAM | RAM | RAM | RAM | RAM | RAM | RAM | | User | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | @@ -652,7 +652,7 @@ typedef Z_PACKED_UNION_BEGIN { /*----------------. | 7 6 5 4 3 2 1 0 | '-\_/-|-|-|-\___/-' -unused| | | '---- user (C000h) +unused| | | '---- user (C000h-FFFFh) | | '-------- VRAM | '---------- ROM '------------ disable */ @@ -798,10 +798,10 @@ typedef Z_PACKED_UNION_BEGIN { #define Z_ZX_SPECTRUM_PLUS_128K_CYCLES_PER_FULL_BORDER_LINE 176 #define Z_ZX_SPECTRUM_PLUS_128K_CYCLES_PER_LATERAL_BORDER_LINE 24 #define Z_ZX_SPECTRUM_PLUS_128K_CYCLES_PER_PAPER_LINE 128 -#define Z_ZX_SPECTRUM_PLUS_128K_CYCLES_PER_INT 36 +#define Z_ZX_SPECTRUM_PLUS_128K_CYCLES_PER_INT 35 #define Z_ZX_SPECTRUM_PLUS_128K_CYCLES_AT_VBLANK 0 #define Z_ZX_SPECTRUM_PLUS_128K_CYCLES_AT_INT 24 -#define Z_ZX_SPECTRUM_PLUS_128K_CYCLES_AT_INT_END 60 +#define Z_ZX_SPECTRUM_PLUS_128K_CYCLES_AT_INT_END 59 #define Z_ZX_SPECTRUM_PLUS_128K_CYCLES_AT_TOP_BORDER 3420 #define Z_ZX_SPECTRUM_PLUS_128K_CYCLES_AT_PAPER_REGION 14364 #define Z_ZX_SPECTRUM_PLUS_128K_CYCLES_AT_PAPER 14388 diff --git a/projects/Zeta/API/Z/inspection/C++.h b/projects/Zeta/API/Z/inspection/C++.h index d7c7107..41747d3 100644 --- a/projects/Zeta/API/Z/inspection/C++.h +++ b/projects/Zeta/API/Z/inspection/C++.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_CPP_H @@ -13,9 +13,10 @@ Released under the terms of the GNU Lesser General Public License v3. */ #include #ifdef __cplusplus - # ifndef Z_CPP -# if __cplusplus >= 202002L +# if __cplusplus >= 202302L +# define Z_CPP Z_CPP23 +# elif __cplusplus >= 202002L # define Z_CPP Z_CPP20 # elif __cplusplus >= 201703L # define Z_CPP Z_CPP17 @@ -30,7 +31,10 @@ Released under the terms of the GNU Lesser General Public License v3. */ # endif # endif -# if Z_CPP == Z_CPP20 +# if Z_CPP == Z_CPP23 +# include +# define Z_CPP_NAME Z_CPP_NAME_CPP23 +# elif Z_CPP == Z_CPP20 # include # define Z_CPP_NAME Z_CPP_NAME_CPP20 # elif Z_CPP == Z_CPP17 @@ -53,24 +57,46 @@ Released under the terms of the GNU Lesser General Public License v3. */ # elif Z_CPP == Z_CPP1 # define Z_CPP_NAME Z_CPP_NAME_CPP1 # else -# error "Invalid Z_CPP key." +# error "Invalid `Z_CPP` key." # endif - #endif /* MARK: - Getters */ -#define Z_CPP_HAS( FEATURE ) Z_IS_TRUE(Z_CPP_HAS_##FEATURE ) -#define Z_CPP_HAS_ATTRIBUTE( ATTRIBUTE ) Z_IS_TRUE(Z_CPP_HAS_ATTRIBUTE_##ATTRIBUTE ) -#define Z_CPP_HAS_IDENTIFIER( IDENTIFIER ) Z_IS_TRUE(Z_CPP_HAS_IDENTIFIER_##IDENTIFIER ) -#define Z_CPP_HAS_LITERAL( LITERAL ) Z_IS_TRUE(Z_CPP_HAS_LITERAL_##LITERAL ) -#define Z_CPP_HAS_OPERATOR( OPERATOR ) Z_IS_TRUE(Z_CPP_HAS_OPERATOR_##OPERATOR ) -#define Z_CPP_HAS_OPERATOR_CASE( OPERATOR, CASE ) Z_IS_TRUE(Z_CPP_HAS_OPERATOR_CASE_##OPERATOR##_##CASE ) -#define Z_CPP_HAS_PREPROCESSOR_IDENTIFIER(PREPROCESSOR_IDENTIFIER) Z_IS_TRUE(Z_CPP_HAS_PREPROCESSOR_IDENTIFIER_##PREPROCESSOR_IDENTIFIER) -#define Z_CPP_HAS_PREPROCESSOR_OPERATOR( PREPROCESSOR_OPERATOR ) Z_IS_TRUE(Z_CPP_HAS_PREPROCESSOR_OPERATOR_##PREPROCESSOR_OPERATOR ) -#define Z_CPP_HAS_SPECIFIER( SPECIFIER ) Z_IS_TRUE(Z_CPP_HAS_SPECIFIER_##SPECIFIER ) -#define Z_CPP_HAS_SPECIFIER_CASE( SPECIFIER, CASE ) Z_IS_TRUE(Z_CPP_HAS_SPECIFIER_CASE_##SPECIFIER##_##CASE ) -#define Z_CPP_HAS_STORAGE_CLASS( STORAGE_CLASS ) Z_IS_TRUE(Z_CPP_HAS_STORAGE_CLASS_##STORAGE_CLASS ) -#define Z_CPP_HAS_TYPE( TYPE ) Z_IS_TRUE(Z_CPP_HAS_TYPE_##TYPE ) +#define Z_CPP_HAS(FEATURE) \ + Z_IS_TRUE(Z_CPP_HAS_##FEATURE) + +#define Z_CPP_HAS_ATTRIBUTE(ATTRIBUTE) \ + Z_IS_TRUE(Z_CPP_HAS_ATTRIBUTE_##ATTRIBUTE) + +#define Z_CPP_HAS_IDENTIFIER(IDENTIFIER) \ + Z_IS_TRUE(Z_CPP_HAS_IDENTIFIER_##IDENTIFIER) + +#define Z_CPP_HAS_LITERAL(LITERAL) \ + Z_IS_TRUE(Z_CPP_HAS_LITERAL_##LITERAL) + +#define Z_CPP_HAS_OPERATOR(OPERATOR) \ + Z_IS_TRUE(Z_CPP_HAS_OPERATOR_##OPERATOR) + +#define Z_CPP_HAS_OPERATOR_CASE(OPERATOR, CASE) \ + Z_IS_TRUE(Z_CPP_HAS_OPERATOR_CASE_##OPERATOR##_##CASE) + +#define Z_CPP_HAS_PREPROCESSOR_IDENTIFIER(PREPROCESSOR_IDENTIFIER) \ + Z_IS_TRUE(Z_CPP_HAS_PREPROCESSOR_IDENTIFIER_##PREPROCESSOR_IDENTIFIER) + +#define Z_CPP_HAS_PREPROCESSOR_OPERATOR(PREPROCESSOR_OPERATOR) \ + Z_IS_TRUE(Z_CPP_HAS_PREPROCESSOR_OPERATOR_##PREPROCESSOR_OPERATOR) + +#define Z_CPP_HAS_SPECIFIER(SPECIFIER) \ + Z_IS_TRUE(Z_CPP_HAS_SPECIFIER_##SPECIFIER) + +#define Z_CPP_HAS_SPECIFIER_CASE(SPECIFIER, CASE) \ + Z_IS_TRUE(Z_CPP_HAS_SPECIFIER_CASE_##SPECIFIER##_##CASE) + +#define Z_CPP_HAS_STORAGE_CLASS(STORAGE_CLASS) \ + Z_IS_TRUE(Z_CPP_HAS_STORAGE_CLASS_##STORAGE_CLASS) + +#define Z_CPP_HAS_TYPE(TYPE) \ + Z_IS_TRUE(Z_CPP_HAS_TYPE_##TYPE) #endif /* Z_inspection_CPP_H */ diff --git a/projects/Zeta/API/Z/inspection/C++/modules/C++03.h b/projects/Zeta/API/Z/inspection/C++/modules/C++03.h index 6d983f7..1a47102 100644 --- a/projects/Zeta/API/Z/inspection/C++/modules/C++03.h +++ b/projects/Zeta/API/Z/inspection/C++/modules/C++03.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_CPP_modules_CPP03_H diff --git a/projects/Zeta/API/Z/inspection/C++/modules/C++11.h b/projects/Zeta/API/Z/inspection/C++/modules/C++11.h index eb5d88d..51fa51c 100644 --- a/projects/Zeta/API/Z/inspection/C++/modules/C++11.h +++ b/projects/Zeta/API/Z/inspection/C++/modules/C++11.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_CPP_modules_CPP11_H diff --git a/projects/Zeta/API/Z/inspection/C++/modules/C++14.h b/projects/Zeta/API/Z/inspection/C++/modules/C++14.h index 1702b5b..5152109 100644 --- a/projects/Zeta/API/Z/inspection/C++/modules/C++14.h +++ b/projects/Zeta/API/Z/inspection/C++/modules/C++14.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_CPP_modules_CPP14_H diff --git a/projects/Zeta/API/Z/inspection/C++/modules/C++17.h b/projects/Zeta/API/Z/inspection/C++/modules/C++17.h index 1bacde5..611c9ac 100644 --- a/projects/Zeta/API/Z/inspection/C++/modules/C++17.h +++ b/projects/Zeta/API/Z/inspection/C++/modules/C++17.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_CPP_modules_CPP17_H diff --git a/projects/Zeta/API/Z/inspection/C++/modules/C++20.h b/projects/Zeta/API/Z/inspection/C++/modules/C++20.h index 6288980..e6aef88 100644 --- a/projects/Zeta/API/Z/inspection/C++/modules/C++20.h +++ b/projects/Zeta/API/Z/inspection/C++/modules/C++20.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_CPP_modules_CPP20_H diff --git a/projects/Zeta/API/Z/inspection/C++/modules/C++23.h b/projects/Zeta/API/Z/inspection/C++/modules/C++23.h new file mode 100644 index 0000000..8e2e056 --- /dev/null +++ b/projects/Zeta/API/Z/inspection/C++/modules/C++23.h @@ -0,0 +1,14 @@ +/* Zeta API - Z/inspection/C++/modules/C++23.h + ______ ______________ ___ +|__ / | ___|___ ___|/ \ + / /__| __| | | / - \ + /______|_____| |__| /__/ \__\ +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. +Released under the terms of the GNU Lesser General Public License v3. */ + +#ifndef Z_inspection_CPP_modules_CPP23_H +#define Z_inspection_CPP_modules_CPP23_H + +#include + +#endif /* Z_inspection_CPP_modules_CPP23_H */ diff --git a/projects/Zeta/API/Z/inspection/C++/modules/C++98.h b/projects/Zeta/API/Z/inspection/C++/modules/C++98.h index 0283ae2..781acc0 100644 --- a/projects/Zeta/API/Z/inspection/C++/modules/C++98.h +++ b/projects/Zeta/API/Z/inspection/C++/modules/C++98.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_CPP_modules_CPP98_H diff --git a/projects/Zeta/API/Z/inspection/C.h b/projects/Zeta/API/Z/inspection/C.h index 24672bf..0c811ac 100644 --- a/projects/Zeta/API/Z/inspection/C.h +++ b/projects/Zeta/API/Z/inspection/C.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_C_H @@ -17,6 +17,8 @@ Released under the terms of the GNU Lesser General Public License v3. */ # define Z_C Z_C78 # elif !defined(__STDC_VERSION__) # define Z_C Z_C89 +# elif __STDC_VERSION__ >= 202311L +# define Z_C Z_C23 # elif __STDC_VERSION__ >= 201710L # define Z_C Z_C17 # elif __STDC_VERSION__ >= 201112L @@ -30,7 +32,10 @@ Released under the terms of the GNU Lesser General Public License v3. */ # endif #endif -#if Z_C == Z_C17 +#if Z_C == Z_C23 +# include +# define Z_C_NAME Z_C_NAME_C23 +#elif Z_C == Z_C17 # include # define Z_C_NAME Z_C_NAME_C17 #elif Z_C == Z_C11 @@ -52,24 +57,51 @@ Released under the terms of the GNU Lesser General Public License v3. */ # include # define Z_C_NAME Z_C_NAME_C78 #else -# error "Invalid Z_C key." +# error "Invalid `Z_C` key." #endif /* MARK: - Getters */ -#define Z_C_HAS( FEATURE ) Z_IS_TRUE(Z_C_HAS_##FEATURE ) -#define Z_C_HAS_ATTRIBUTE( ATTRIBUTE ) Z_IS_TRUE(Z_C_HAS_ATTRIBUTE_##ATTRIBUTE ) -#define Z_C_HAS_ESCAPE_SEQUENCE( ESCAPE_SEQUENCE ) Z_IS_TRUE(Z_C_HAS_ESCAPE_SEQUENCE_##ESCAPE_SEQUENCE ) -#define Z_C_HAS_IDENTIFIER( IDENTIFIER ) Z_IS_TRUE(Z_C_HAS_IDENTIFIER_##IDENTIFIER ) -#define Z_C_HAS_LITERAL( LITERAL ) Z_IS_TRUE(Z_C_HAS_LITERAL_##LITERAL ) -#define Z_C_HAS_OPERATOR( OPERATOR ) Z_IS_TRUE(Z_C_HAS_OPERATOR_##OPERATOR ) -#define Z_C_HAS_PREPROCESSOR_DIRECTIVE(PREPROCESSOR_DIRECTIVE) Z_IS_TRUE(Z_C_HAS_PREPROCESSOR_DIRECTIVE_##PREPROCESSOR_DIRECTIVE) -#define Z_C_HAS_PREPROCESSOR_OPERATOR( PREPROCESSOR_OPERATOR ) Z_IS_TRUE(Z_C_HAS_PREPROCESSOR_OPERATOR_##PREPROCESSOR_OPERATOR ) -#define Z_C_HAS_SPECIFIER( SPECIFIER ) Z_IS_TRUE(Z_C_HAS_SPECIFIER_##SPECIFIER ) -#define Z_C_HAS_STD_PRAGMA( STD_PRAGMA ) Z_IS_TRUE(Z_C_HAS_STD_PRAGMA_##STD_PRAGMA ) -#define Z_C_HAS_STORAGE_CLASS( STORAGE_CLASS ) Z_IS_TRUE(Z_C_HAS_STORAGE_CLASS_##STORAGE_CLASS ) -#define Z_C_HAS_TYPE( TYPE ) Z_IS_TRUE(Z_C_HAS_TYPE_##TYPE ) -#define Z_C_HAS_TYPE_MODIFIER( TYPE_MODIFIER ) Z_IS_TRUE(Z_C_HAS_TYPE_MODIFIER_##TYPE_MODIFIER ) -#define Z_C_HAS_TYPE_QUALIFIER( TYPE_QUALIFIER ) Z_IS_TRUE(Z_C_HAS_TYPE_QUALIFIER_##TYPE_QUALIFIER ) +#define Z_C_HAS(FEATURE) \ + Z_IS_TRUE(Z_C_HAS_##FEATURE) + +#define Z_C_HAS_ATTRIBUTE(ATTRIBUTE) \ + Z_IS_TRUE(Z_C_HAS_ATTRIBUTE_##ATTRIBUTE) + +#define Z_C_HAS_ESCAPE_SEQUENCE(ESCAPE_SEQUENCE) \ + Z_IS_TRUE(Z_C_HAS_ESCAPE_SEQUENCE_##ESCAPE_SEQUENCE) + +#define Z_C_HAS_IDENTIFIER(IDENTIFIER) \ + Z_IS_TRUE(Z_C_HAS_IDENTIFIER_##IDENTIFIER) + +#define Z_C_HAS_LITERAL(LITERAL) \ + Z_IS_TRUE(Z_C_HAS_LITERAL_##LITERAL) + +#define Z_C_HAS_OPERATOR(OPERATOR) \ + Z_IS_TRUE(Z_C_HAS_OPERATOR_##OPERATOR) + +#define Z_C_HAS_PREPROCESSOR_DIRECTIVE(PREPROCESSOR_DIRECTIVE) \ + Z_IS_TRUE(Z_C_HAS_PREPROCESSOR_DIRECTIVE_##PREPROCESSOR_DIRECTIVE) + +#define Z_C_HAS_PREPROCESSOR_OPERATOR(PREPROCESSOR_OPERATOR) \ + Z_IS_TRUE(Z_C_HAS_PREPROCESSOR_OPERATOR_##PREPROCESSOR_OPERATOR) + +#define Z_C_HAS_SPECIFIER(SPECIFIER) \ + Z_IS_TRUE(Z_C_HAS_SPECIFIER_##SPECIFIER) + +#define Z_C_HAS_STD_PRAGMA(STD_PRAGMA) \ + Z_IS_TRUE(Z_C_HAS_STD_PRAGMA_##STD_PRAGMA) + +#define Z_C_HAS_STORAGE_CLASS(STORAGE_CLASS) \ + Z_IS_TRUE(Z_C_HAS_STORAGE_CLASS_##STORAGE_CLASS) + +#define Z_C_HAS_TYPE(TYPE) \ + Z_IS_TRUE(Z_C_HAS_TYPE_##TYPE) + +#define Z_C_HAS_TYPE_MODIFIER(TYPE_MODIFIER) \ + Z_IS_TRUE(Z_C_HAS_TYPE_MODIFIER_##TYPE_MODIFIER) + +#define Z_C_HAS_TYPE_QUALIFIER(TYPE_QUALIFIER) \ + Z_IS_TRUE(Z_C_HAS_TYPE_QUALIFIER_##TYPE_QUALIFIER) #endif /* Z_inspection_C_H */ diff --git a/projects/Zeta/API/Z/inspection/C/modules/C11.h b/projects/Zeta/API/Z/inspection/C/modules/C11.h index 1e7b7aa..1b04526 100644 --- a/projects/Zeta/API/Z/inspection/C/modules/C11.h +++ b/projects/Zeta/API/Z/inspection/C/modules/C11.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_C_modules_C11_H diff --git a/projects/Zeta/API/Z/inspection/C/modules/C23.h b/projects/Zeta/API/Z/inspection/C/modules/C23.h index 0f01059..9ea7d60 100644 --- a/projects/Zeta/API/Z/inspection/C/modules/C23.h +++ b/projects/Zeta/API/Z/inspection/C/modules/C23.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_C_modules_C23_H diff --git a/projects/Zeta/API/Z/inspection/C/modules/C78.h b/projects/Zeta/API/Z/inspection/C/modules/C78.h index 68bbac8..ce56ee0 100644 --- a/projects/Zeta/API/Z/inspection/C/modules/C78.h +++ b/projects/Zeta/API/Z/inspection/C/modules/C78.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_C_modules_C78_H diff --git a/projects/Zeta/API/Z/inspection/C/modules/C89.h b/projects/Zeta/API/Z/inspection/C/modules/C89.h index 5572d05..bd2bcf5 100644 --- a/projects/Zeta/API/Z/inspection/C/modules/C89.h +++ b/projects/Zeta/API/Z/inspection/C/modules/C89.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_C_modules_C89_H diff --git a/projects/Zeta/API/Z/inspection/C/modules/C95.h b/projects/Zeta/API/Z/inspection/C/modules/C95.h index 3200638..3468e0a 100644 --- a/projects/Zeta/API/Z/inspection/C/modules/C95.h +++ b/projects/Zeta/API/Z/inspection/C/modules/C95.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_C_modules_C95_H diff --git a/projects/Zeta/API/Z/inspection/C/modules/C99.h b/projects/Zeta/API/Z/inspection/C/modules/C99.h index b167909..d8f4a6d 100644 --- a/projects/Zeta/API/Z/inspection/C/modules/C99.h +++ b/projects/Zeta/API/Z/inspection/C/modules/C99.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_C_modules_C99_H diff --git a/projects/Zeta/API/Z/inspection/ISA.h b/projects/Zeta/API/Z/inspection/ISA.h index f627c8b..3b62a8f 100644 --- a/projects/Zeta/API/Z/inspection/ISA.h +++ b/projects/Zeta/API/Z/inspection/ISA.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_ISA_H @@ -156,7 +156,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ # define Z_ISA_IS_Z80 1 # define Z_ISA_NAME Z_ISA_NAME_Z80 #else -# error "Invalid Z_ISA key." +# error "Invalid `Z_ISA` key." #endif #ifndef Z_ISA_INTEGRAL_ENDIANNESS @@ -194,13 +194,16 @@ Released under the terms of the GNU Lesser General Public License v3. */ # define Z_ISA_INTEGRAL_ENDIANNESS Z_ENDIANNESS_BIG # elif Z_ISA == Z_ISA_UNKNOWN -# error "It is necessary to define `Z_ISA_INTEGRAL_ENDIANNESS` for unknown ISAs." +# error "It is necessary to predefine `Z_ISA_INTEGRAL_ENDIANNESS` for unknown ISAs." # else -# error "It is necessary to define `Z_ISA_INTEGRAL_ENDIANNESS` for bi-endian ISAs not handled by the compiler driver." +# error "It is necessary to predefine `Z_ISA_INTEGRAL_ENDIANNESS` for bi-endian ISAs not handled by the compiler driver." # endif #endif -#define Z_ISA_IS( ISA ) Z_IS_TRUE(Z_ISA_IS_##ISA ) -#define Z_ISA_HAS_INTEGRAL(bits) Z_IS_TRUE(Z_ISA_HAS_INTEGRAL_##bits##BIT) +#define Z_ISA_IS(ISA) \ + Z_IS_TRUE(Z_ISA_IS_##ISA) + +#define Z_ISA_HAS_INTEGRAL(bits) \ + Z_IS_TRUE(Z_ISA_HAS_INTEGRAL_##bits##BIT) #endif /* Z_inspection_ISA_H */ diff --git a/projects/Zeta/API/Z/inspection/ISA/detection.h b/projects/Zeta/API/Z/inspection/ISA/detection.h index 65ccce9..ca9e7f8 100644 --- a/projects/Zeta/API/Z/inspection/ISA/detection.h +++ b/projects/Zeta/API/Z/inspection/ISA/detection.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_ISA_detection_H @@ -162,13 +162,13 @@ Released under the terms of the GNU Lesser General Public License v3. */ # define Z_ISA Z_ISA_M68K -#elif defined(__mips64 ) || \ - defined(__mips64__) || \ - (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3)) || \ - (defined(_MIPS_ISA) && \ - ((defined(_MIPS_ISA_MIPS64) && _MIPS_ISA == _MIPS_ISA_MIPS64) || \ - (defined(_MIPS_ISA_MIPS4 ) && _MIPS_ISA == _MIPS_ISA_MIPS4 ) || \ - (defined(_MIPS_ISA_MIPS3 ) && _MIPS_ISA == _MIPS_ISA_MIPS3 ))) +#elif defined(__mips64 ) || \ + defined(__mips64__) || \ + (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3)) || \ + (defined(_MIPS_ISA) && ( \ + (defined(_MIPS_ISA_MIPS64) && _MIPS_ISA == _MIPS_ISA_MIPS64) || \ + (defined(_MIPS_ISA_MIPS4 ) && _MIPS_ISA == _MIPS_ISA_MIPS4 ) || \ + (defined(_MIPS_ISA_MIPS3 ) && _MIPS_ISA == _MIPS_ISA_MIPS3 ))) # define Z_ISA Z_ISA_MIPS64 diff --git a/projects/Zeta/API/Z/inspection/OS.h b/projects/Zeta/API/Z/inspection/OS.h index ce2a6d9..d583866 100644 --- a/projects/Zeta/API/Z/inspection/OS.h +++ b/projects/Zeta/API/Z/inspection/OS.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_OS_H @@ -271,7 +271,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ # define Z_OS_IS_ZETA 1 # define Z_OS_NAME Z_OS_NAME_ZETA #elif -# error "Invalid Z_OS key." +# error "Invalid `Z_OS` key." #endif #if Z_OS == Z_OS_AIX || \ @@ -334,7 +334,10 @@ Released under the terms of the GNU Lesser General Public License v3. */ /* MARK: - Getters */ -#define Z_OS_IS( OS ) Z_IS_TRUE(Z_OS_IS_##OS ) -#define Z_OS_HAS(WHAT) Z_IS_TRUE(Z_OS_HAS_##WHAT) +#define Z_OS_IS(OS) \ + Z_IS_TRUE(Z_OS_IS_##OS) + +#define Z_OS_HAS(WHAT) \ + Z_IS_TRUE(Z_OS_HAS_##WHAT) #endif /* Z_inspection_OS_H */ diff --git a/projects/Zeta/API/Z/inspection/OS/detection.h b/projects/Zeta/API/Z/inspection/OS/detection.h index 68ad095..c659ecf 100644 --- a/projects/Zeta/API/Z/inspection/OS/detection.h +++ b/projects/Zeta/API/Z/inspection/OS/detection.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_OS_detection_H diff --git a/projects/Zeta/API/Z/inspection/Z.h b/projects/Zeta/API/Z/inspection/Z.h index 0b8c892..0cc577f 100644 --- a/projects/Zeta/API/Z/inspection/Z.h +++ b/projects/Zeta/API/Z/inspection/Z.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_Z_H diff --git a/projects/Zeta/API/Z/inspection/character_set.h b/projects/Zeta/API/Z/inspection/character_set.h index 0f6794c..0c7e284 100644 --- a/projects/Zeta/API/Z/inspection/character_set.h +++ b/projects/Zeta/API/Z/inspection/character_set.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_character_set_H diff --git a/projects/Zeta/API/Z/inspection/compiler.h b/projects/Zeta/API/Z/inspection/compiler.h index 71016df..c9bc365 100644 --- a/projects/Zeta/API/Z/inspection/compiler.h +++ b/projects/Zeta/API/Z/inspection/compiler.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_compiler_H @@ -15,41 +15,107 @@ Released under the terms of the GNU Lesser General Public License v3. */ #define Z_COMPILER_IS(COMPILER) Z_IS_TRUE(Z_COMPILER_IS_##COMPILER) -#define Z_COMPILER_DIALECT_HAS( LANGUAGE, FEATURE ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_##FEATURE ) -#define Z_COMPILER_DIALECT_HAS_ATTRIBUTE( LANGUAGE, ATTRIBUTE ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_ATTRIBUTE_##ATTRIBUTE ) -#define Z_COMPILER_DIALECT_HAS_ESCAPE_SEQUENCE( LANGUAGE, ESCAPE_SEQUENCE ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_ESCAPE_SEQUENCE_##ESCAPE_SEQUENCE ) -#define Z_COMPILER_DIALECT_HAS_IDENTIFIER( LANGUAGE, IDENTIFIER ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_IDENTIFIER_##IDENTIFIER ) -#define Z_COMPILER_DIALECT_HAS_LITERAL( LANGUAGE, LITERAL ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_LITERAL_##LITERAL ) -#define Z_COMPILER_DIALECT_HAS_OPERATOR( LANGUAGE, OPERATOR ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_OPERATOR_##OPERATOR ) -#define Z_COMPILER_DIALECT_HAS_OPERATOR_CASE( LANGUAGE, OPERATOR, CASE ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_OPERATOR_CASE_##OPERATOR##_##CASE ) -#define Z_COMPILER_DIALECT_HAS_PREPROCESSOR_DIRECTIVE( LANGUAGE, PREPROCESSOR_DIRECTIVE ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_PREPROCESSOR_DIRECTIVE_##PREPROCESSOR_DIRECTIVE ) -#define Z_COMPILER_DIALECT_HAS_PREPROCESSOR_IDENTIFIER(LANGUAGE, PREPROCESSOR_IDENTIFIER) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_PREPROCESSOR_IDENTIFIER_##PREPROCESSOR_IDENTIFIER) -#define Z_COMPILER_DIALECT_HAS_PREPROCESSOR_OPERATOR( LANGUAGE, PREPROCESSOR_OPERATOR ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_PREPROCESSOR_OPERATOR_##PREPROCESSOR_OPERATOR ) -#define Z_COMPILER_DIALECT_HAS_SPECIFIER( LANGUAGE, SPECIFIER ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_SPECIFIER_##SPECIFIER ) -#define Z_COMPILER_DIALECT_HAS_SPECIFIER_CASE( LANGUAGE, SPECIFIER, CASE ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_SPECIFIER_CASE_##SPECIFIER##_##CASE ) -#define Z_COMPILER_DIALECT_HAS_STD_PRAGMA( LANGUAGE, STD_PRAGMA ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_STD_PRAGMA_##STD_PRAGMA ) -#define Z_COMPILER_DIALECT_HAS_STORAGE_CLASS( LANGUAGE, STORAGE_CLASS ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_STORAGE_CLASS_##STORAGE_CLASS ) -#define Z_COMPILER_DIALECT_HAS_TYPE( LANGUAGE, TYPE ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_TYPE_##TYPE ) -#define Z_COMPILER_DIALECT_HAS_TYPE_MODIFIER( LANGUAGE, TYPE_MODIFIER ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_TYPE_MODIFIER_##TYPE_MODIFIER ) -#define Z_COMPILER_DIALECT_HAS_TYPE_QUALIFIER( LANGUAGE, TYPE_QUALIFIER ) Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_TYPE_QUALIFIER_##TYPE_QUALIFIER ) +#define Z_COMPILER_DIALECT_HAS(LANGUAGE, FEATURE) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_##FEATURE) -#define Z_COMPILER_HAS( FEATURE ) Z_IS_TRUE(Z_COMPILER_HAS_##FEATURE ) -#define Z_COMPILER_HAS_ATTRIBUTE( ATTRIBUTE ) Z_IS_TRUE(Z_COMPILER_HAS_ATTRIBUTE_##ATTRIBUTE ) -#define Z_COMPILER_HAS_CONSTANT( CONSTANT ) Z_IS_TRUE(Z_COMPILER_HAS_CONSTANT_##CONSTANT ) -#define Z_COMPILER_HAS_FUNCTION( FUNCTION ) Z_IS_TRUE(Z_COMPILER_HAS_FUNCTION_##FUNCTION ) -#define Z_COMPILER_HAS_LITERAL( LITERAL ) Z_IS_TRUE(Z_COMPILER_HAS_LITERAL_##LITERAL ) -#define Z_COMPILER_HAS_MACRO( MACRO ) Z_IS_TRUE(Z_COMPILER_HAS_MACRO_##MACRO ) -#define Z_COMPILER_HAS_MAGIC_CONSTANT(MAGIC_CONSTANT) Z_IS_TRUE(Z_COMPILER_HAS_MAGIC_CONSTANT_##MAGIC_CONSTANT) -#define Z_COMPILER_HAS_TRAIT( TRAIT ) Z_IS_TRUE(Z_COMPILER_HAS_TRAIT_##TRAIT ) -#define Z_COMPILER_HAS_TYPE( TYPE ) Z_IS_TRUE(Z_COMPILER_HAS_TYPE_##TYPE ) -#define Z_COMPILER_ATTRIBUTE( ATTRIBUTE ) Z_COMPILER_ATTRIBUTE_##ATTRIBUTE -#define Z_COMPILER_CONSTANT( CONSTANT ) Z_COMPILER_CONSTANT_##CONSTANT -#define Z_COMPILER_FUNCTION( FUNCTION ) Z_COMPILER_FUNCTION_##FUNCTION -#define Z_COMPILER_LITERAL( LITERAL ) Z_COMPILER_LITERAL_##LITERAL -#define Z_COMPILER_MACRO( MACRO ) Z_COMPILER_MACRO_##MACRO -#define Z_COMPILER_MAGIC_CONSTANT( MAGIC_CONSTANT) Z_COMPILER_MAGIC_CONSTANT_##MAGIC_CONSTANT -#define Z_COMPILER_TRAIT( TRAIT ) Z_COMPILER_TRAIT_##TRAIT -#define Z_COMPILER_TYPE( TYPE ) Z_COMPILER_TYPE_##TYPE +#define Z_COMPILER_DIALECT_HAS_ATTRIBUTE(LANGUAGE, ATTRIBUTE) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_ATTRIBUTE_##ATTRIBUTE) + +#define Z_COMPILER_DIALECT_HAS_ESCAPE_SEQUENCE(LANGUAGE, ESCAPE_SEQUENCE) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_ESCAPE_SEQUENCE_##ESCAPE_SEQUENCE) + +#define Z_COMPILER_DIALECT_HAS_IDENTIFIER(LANGUAGE, IDENTIFIER) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_IDENTIFIER_##IDENTIFIER) + +#define Z_COMPILER_DIALECT_HAS_LITERAL(LANGUAGE, LITERAL) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_LITERAL_##LITERAL) + +#define Z_COMPILER_DIALECT_HAS_OPERATOR(LANGUAGE, OPERATOR) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_OPERATOR_##OPERATOR) + +#define Z_COMPILER_DIALECT_HAS_OPERATOR_CASE(LANGUAGE, OPERATOR, CASE) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_OPERATOR_CASE_##OPERATOR##_##CASE) + +#define Z_COMPILER_DIALECT_HAS_PREPROCESSOR_DIRECTIVE(LANGUAGE, PREPROCESSOR_DIRECTIVE) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_PREPROCESSOR_DIRECTIVE_##PREPROCESSOR_DIRECTIVE) + +#define Z_COMPILER_DIALECT_HAS_PREPROCESSOR_IDENTIFIER(LANGUAGE, PREPROCESSOR_IDENTIFIER) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_PREPROCESSOR_IDENTIFIER_##PREPROCESSOR_IDENTIFIER) + +#define Z_COMPILER_DIALECT_HAS_PREPROCESSOR_OPERATOR(LANGUAGE, PREPROCESSOR_OPERATOR) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_PREPROCESSOR_OPERATOR_##PREPROCESSOR_OPERATOR) + +#define Z_COMPILER_DIALECT_HAS_SPECIFIER(LANGUAGE, SPECIFIER) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_SPECIFIER_##SPECIFIER) + +#define Z_COMPILER_DIALECT_HAS_SPECIFIER_CASE(LANGUAGE, SPECIFIER, CASE) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_SPECIFIER_CASE_##SPECIFIER##_##CASE) + +#define Z_COMPILER_DIALECT_HAS_STD_PRAGMA(LANGUAGE, STD_PRAGMA) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_STD_PRAGMA_##STD_PRAGMA) + +#define Z_COMPILER_DIALECT_HAS_STORAGE_CLASS(LANGUAGE, STORAGE_CLASS) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_STORAGE_CLASS_##STORAGE_CLASS) + +#define Z_COMPILER_DIALECT_HAS_TYPE(LANGUAGE, TYPE) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_TYPE_##TYPE) + +#define Z_COMPILER_DIALECT_HAS_TYPE_MODIFIER(LANGUAGE, TYPE_MODIFIER) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_TYPE_MODIFIER_##TYPE_MODIFIER) + +#define Z_COMPILER_DIALECT_HAS_TYPE_QUALIFIER(LANGUAGE, TYPE_QUALIFIER) \ + Z_IS_TRUE(Z_COMPILER_HAS_##LANGUAGE##_TYPE_QUALIFIER_##TYPE_QUALIFIER) + +#define Z_COMPILER_HAS(FEATURE) \ + Z_IS_TRUE(Z_COMPILER_HAS_##FEATURE) + +#define Z_COMPILER_HAS_ATTRIBUTE(ATTRIBUTE) \ + Z_IS_TRUE(Z_COMPILER_HAS_ATTRIBUTE_##ATTRIBUTE) + +#define Z_COMPILER_HAS_CONSTANT(CONSTANT) \ + Z_IS_TRUE(Z_COMPILER_HAS_CONSTANT_##CONSTANT) + +#define Z_COMPILER_HAS_FUNCTION(FUNCTION) \ + Z_IS_TRUE(Z_COMPILER_HAS_FUNCTION_##FUNCTION) + +#define Z_COMPILER_HAS_LITERAL(LITERAL) \ + Z_IS_TRUE(Z_COMPILER_HAS_LITERAL_##LITERAL) + +#define Z_COMPILER_HAS_MACRO(MACRO) \ + Z_IS_TRUE(Z_COMPILER_HAS_MACRO_##MACRO) + +#define Z_COMPILER_HAS_MAGIC_CONSTANT(MAGIC_CONSTANT) \ + Z_IS_TRUE(Z_COMPILER_HAS_MAGIC_CONSTANT_##MAGIC_CONSTANT) + +#define Z_COMPILER_HAS_TRAIT(TRAIT) \ + Z_IS_TRUE(Z_COMPILER_HAS_TRAIT_##TRAIT) + +#define Z_COMPILER_HAS_TYPE(TYPE) \ + Z_IS_TRUE(Z_COMPILER_HAS_TYPE_##TYPE) + +#define Z_COMPILER_ATTRIBUTE(ATTRIBUTE) \ + Z_COMPILER_ATTRIBUTE_##ATTRIBUTE + +#define Z_COMPILER_CONSTANT(CONSTANT) \ + Z_COMPILER_CONSTANT_##CONSTANT + +#define Z_COMPILER_FUNCTION(FUNCTION) \ + Z_COMPILER_FUNCTION_##FUNCTION + +#define Z_COMPILER_LITERAL(LITERAL) \ + Z_COMPILER_LITERAL_##LITERAL + +#define Z_COMPILER_MACRO(MACRO) \ + Z_COMPILER_MACRO_##MACRO + +#define Z_COMPILER_MAGIC_CONSTANT(MAGIC_CONSTANT) \ + Z_COMPILER_MAGIC_CONSTANT_##MAGIC_CONSTANT + +#define Z_COMPILER_TRAIT(TRAIT) \ + Z_COMPILER_TRAIT_##TRAIT + +#define Z_COMPILER_TYPE(TYPE) \ + Z_COMPILER_TYPE_##TYPE #ifdef Z_COMPILER_HEADER # include Z_COMPILER_HEADER @@ -111,7 +177,8 @@ Released under the terms of the GNU Lesser General Public License v3. */ # include # elif Z_COMPILER == Z_COMPILER_FUJITSU_CPP # include */ -# elif Z_COMPILER == Z_COMPILER_GCC +/*# elif Z_COMPILER == Z_COMPILER_GCC*/ +# elif Z_COMPILER == Z_COMPILER_GCC || Z_COMPILER == Z_COMPILER_MINGW_W64 || Z_COMPILER == Z_COMPILER_MINGW # include /*# elif Z_COMPILER == Z_COMPILER_GREEN_HILL_C_CPP # include @@ -131,6 +198,8 @@ Released under the terms of the GNU Lesser General Public License v3. */ # include # elif Z_COMPILER == Z_COMPILER_INTEL_CPP # include +# elif Z_COMPILER == Z_COMPILER_JCC +# include # elif Z_COMPILER == Z_COMPILER_KAI_CPP # include # elif Z_COMPILER == Z_COMPILER_KEIL_C166 @@ -149,6 +218,8 @@ Released under the terms of the GNU Lesser General Public License v3. */ # include # elif Z_COMPILER == Z_COMPILER_MINGW # include +# elif Z_COMPILER == Z_COMPILER_MINGW_W64 +# include # elif Z_COMPILER == Z_COMPILER_MIPS_PRO # include # elif Z_COMPILER == Z_COMPILER_MIRACLE_C @@ -226,7 +297,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ # elif Z_COMPILER == Z_COMPILER_UNKNOWN # include # else -# error "Invalid Z_COMPILER key." +# error "Invalid `Z_COMPILER` key." # endif #endif diff --git a/projects/Zeta/API/Z/inspection/compiler/completion.h b/projects/Zeta/API/Z/inspection/compiler/completion.h index 7c34549..29b5ebb 100644 --- a/projects/Zeta/API/Z/inspection/compiler/completion.h +++ b/projects/Zeta/API/Z/inspection/compiler/completion.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Copyright (C) 2018 Sofía Ortega Sosa. Released under the terms of the GNU Lesser General Public License v3. */ diff --git a/projects/Zeta/API/Z/inspection/compiler/detection.h b/projects/Zeta/API/Z/inspection/compiler/detection.h index 5ad36b0..d2a642d 100644 --- a/projects/Zeta/API/Z/inspection/compiler/detection.h +++ b/projects/Zeta/API/Z/inspection/compiler/detection.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_compiler_detection_H @@ -122,6 +122,9 @@ Released under the terms of the GNU Lesser General Public License v3. */ #elif defined(__INTEL_COMPILER) || defined(__ICC) || defined(__ECC) || defined(__ICL) # define Z_COMPILER Z_COMPILER_INTEL_CPP +#elif defined(__JCC__) || defined(__jcc__) +# define Z_COMPILER Z_COMPILER_JCC + #elif defined(__KCC) # define Z_COMPILER Z_COMPILER_KAI_CPP @@ -146,7 +149,14 @@ Released under the terms of the GNU Lesser General Public License v3. */ #elif defined(_MRI) # define Z_COMPILER Z_COMPILER_MICROTEC_C_CPP -#elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__) +/*------------------------------------------------------------. +| TODO: There seems to be no way to distinguish between MinGW | +| and MinGW-w64 32-bit. Investigate. | +'============================================================*/ +#elif defined(__MINGW64__) +# define Z_COMPILER Z_COMPILER_MINGW_W64 + +#elif defined(__MINGW32__) # define Z_COMPILER Z_COMPILER_MINGW #elif defined(__sgi) || defined(sgi) diff --git a/projects/Zeta/API/Z/inspection/compiler/modules/Clang.h b/projects/Zeta/API/Z/inspection/compiler/modules/Clang.h index e2a9587..864cc2f 100644 --- a/projects/Zeta/API/Z/inspection/compiler/modules/Clang.h +++ b/projects/Zeta/API/Z/inspection/compiler/modules/Clang.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. .------------------------------------------------------------------------------. @@ -333,7 +333,7 @@ Released under the terms of the GNU Lesser General Public License v3. # define Z_COMPILER_BIT_FIELD_ORDER_ALL Z_ORDER_NORMAL #else -# error "Clang module: Can not detect the endianness of the integral types." +# error "Clang driver: Cannot detect the endianness of integral types." #endif /*#define Z_COMPILER_BIT_FIELD_ORDER_8BIT*/ @@ -489,7 +489,7 @@ Released under the terms of the GNU Lesser General Public License v3. # define Z_COMPILER_FIXED_FUNDAMENTAL_FLOAT Z_FUNDAMENTAL_BFP64 # elif -# error "Clang module: Can not detect the format of the float type." +# error "Clang driver: Can not detect the format of the `float` type." # endif #endif @@ -504,7 +504,7 @@ Released under the terms of the GNU Lesser General Public License v3. # define Z_COMPILER_FIXED_FUNDAMENTAL_DOUBLE Z_FUNDAMENTAL_BFP64 # else -# error "Clang module: Can not detect the format of the double type." +# error "Clang driver: Cannot detect the format of the `double` type." # endif #endif @@ -539,7 +539,7 @@ Released under the terms of the GNU Lesser General Public License v3. # elif defined(Z_COMPILER_ISA) && Z_COMPILER_ISA == Z_ISA_X86_32 # define Z_COMPILER_FIXED_FUNDAMENTAL_LDOUBLE Z_FUNDAMENTAL_X87_DE96 # else -# error "Clang module: Can not detect the format of the long double type." +# error "Clang driver: Cannot detect the format of the `long double` type." # endif # endif @@ -550,7 +550,7 @@ Released under the terms of the GNU Lesser General Public License v3. # define Z_COMPILER_FIXED_FUNDAMENTAL_LDOUBLE Z_FUNDAMENTAL_BFP128 # else -# error "Clang module: Can not detect the format of the long double type." +# error "Clang driver: Cannot detect the format of the `long double` type." # endif #endif @@ -1651,34 +1651,6 @@ Released under the terms of the GNU Lesser General Public License v3. #define Z_COMPILER_TYPE_VAL __builtin_va_list /* v2.6 */ -#ifdef __UINT16_C_SUFFIX__ /* v3.5 */ -# define Z_COMPILER_LITERAL_UINT16(number) (__extension__ Z_JOIN_2(number, __UINT16_C_SUFFIX__)) -#endif - -#ifdef __INT16_C_SUFFIX__ /* v3.5 */ -# define Z_COMPILER_LITERAL_SINT16(number) (__extension__ Z_JOIN_2(number, __INT16_C_SUFFIX__)) -#endif - -#ifdef __UINT32_C_SUFFIX__ /* v3.5 */ -# define Z_COMPILER_LITERAL_UINT32(number) (__extension__ Z_JOIN_2(number, __UINT32_C_SUFFIX__)) -#endif - -#ifdef __INT32_C_SUFFIX__ /* v3.5 */ -# define Z_COMPILER_LITERAL_SINT32(number) (__extension__ Z_JOIN_2(number, __INT32_C_SUFFIX__)) -#endif - -#ifdef __UINT64_C_SUFFIX__ /* v3.5 */ -# define Z_COMPILER_LITERAL_UINT64(number) (__extension__ Z_JOIN_2(number, __UINT64_C_SUFFIX__)) -#endif - -#ifdef __INT64_C_SUFFIX__ /* v2.7 */ -# define Z_COMPILER_LITERAL_SINT64(number) (__extension__ Z_JOIN_2(number, __INT64_C_SUFFIX__)) - -# ifndef __UINT64_C_SUFFIX__ -# define Z_COMPILER_LITERAL_SINT64(number) (__extension__ Z_JOIN_2(Z_SUFFIX_U(number), __INT64_C_SUFFIX__)) -# endif -#endif - /*#define Z_COMPILER_TYPE_UINT24*/ /*#define Z_COMPILER_TYPE_SINT24*/ /*#define Z_COMPILER_TYPE_UINT40*/ @@ -1701,14 +1673,20 @@ Released under the terms of the GNU Lesser General Public License v3. /*#define Z_COMPILER_TYPE_BFLOAT16*/ /*#define Z_COMPILER_LITERAL_UINT8(number)*/ /*#define Z_COMPILER_LITERAL_SINT8(number)*/ +/*#define Z_COMPILER_LITERAL_UINT16(number)*/ +/*#define Z_COMPILER_LITERAL_SINT16(number)*/ /*#define Z_COMPILER_LITERAL_UINT24(number)*/ /*#define Z_COMPILER_LITERAL_SINT24(number)*/ +/*#define Z_COMPILER_LITERAL_UINT32(number)*/ +/*#define Z_COMPILER_LITERAL_SINT32(number)*/ /*#define Z_COMPILER_LITERAL_UINT40(number)*/ /*#define Z_COMPILER_LITERAL_SINT40(number)*/ /*#define Z_COMPILER_LITERAL_UINT48(number)*/ /*#define Z_COMPILER_LITERAL_SINT48(number)*/ /*#define Z_COMPILER_LITERAL_UINT56(number)*/ /*#define Z_COMPILER_LITERAL_SINT56(number)*/ +/*#define Z_COMPILER_LITERAL_UINT64(number)*/ +/*#define Z_COMPILER_LITERAL_SINT64(number)*/ /*#define Z_COMPILER_LITERAL_UINT128(number)*/ /*#define Z_COMPILER_LITERAL_SINT128(number)*/ /*#define Z_COMPILER_LITERAL_BFP16(number)*/ @@ -1788,6 +1766,10 @@ Released under the terms of the GNU Lesser General Public License v3. # define Z_COMPILER_CONSTANT_SLLONG_MAXIMUM __LONG_LONG_MAX__ #endif +#ifdef __BOOL_WIDTH__ +# define Z_COMPILER_CONSTANT_BOOL_WIDTH __BOOL_WIDTH__ +#endif + #ifdef __SIZEOF_WCHAR_T__ /* v2.8 */ # define Z_COMPILER_CONSTANT_WCHAR_SIZE __SIZEOF_WCHAR_T__ #endif @@ -1932,6 +1914,7 @@ Released under the terms of the GNU Lesser General Public License v3. /*#define Z_COMPILER_CONSTANT_LLONG_WIDTH*/ /*#define Z_COMPILER_CONSTANT_ULLONG_MAXIMUM*/ /*#define Z_COMPILER_CONSTANT_SLLONG_MINIMUM*/ +/*#define Z_COMPILER_CONSTANT_BOOL_SIZE*/ /*#define Z_COMPILER_CONSTANT_WCHAR_MINIMUM*/ /*#define Z_COMPILER_CONSTANT_SSIZE_MAXIMUM*/ /*#define Z_COMPILER_CONSTANT_SSIZE_MINIMUM*/ diff --git a/projects/Zeta/API/Z/inspection/compiler/modules/GCC.h b/projects/Zeta/API/Z/inspection/compiler/modules/GCC.h index 8a845a8..a05a7f1 100644 --- a/projects/Zeta/API/Z/inspection/compiler/modules/GCC.h +++ b/projects/Zeta/API/Z/inspection/compiler/modules/GCC.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_compiler_modules_GCC_H @@ -862,6 +862,8 @@ Released under the terms of the GNU Lesser General Public License v3. */ /*#define Z_COMPILER_CONSTANT_SLONG_MINIMUM*/ /*#define Z_COMPILER_CONSTANT_ULLONG_MAXIMUM*/ /*#define Z_COMPILER_CONSTANT_SLLONG_MINIMUM*/ +/*#define Z_COMPILER_CONSTANT_BOOL_SIZE*/ +/*#define Z_COMPILER_CONSTANT_BOOL_WIDTH*/ /*#define Z_COMPILER_CONSTANT_SSIZE_MAXIMUM*/ /*#define Z_COMPILER_CONSTANT_SSIZE_MINIMUM*/ /*#define Z_COMPILER_CONSTANT_UINTMAX_SIZE*/ diff --git a/projects/Zeta/API/Z/inspection/compiler/modules/MSVC.h b/projects/Zeta/API/Z/inspection/compiler/modules/MSVC.h index 6bdd905..13d082f 100644 --- a/projects/Zeta/API/Z/inspection/compiler/modules/MSVC.h +++ b/projects/Zeta/API/Z/inspection/compiler/modules/MSVC.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_compiler_modules_MSVC_H @@ -562,6 +562,8 @@ Released under the terms of the GNU Lesser General Public License v3. */ /*#define Z_COMPILER_CONSTANT_ULLONG_MAXIMUM*/ /*#define Z_COMPILER_CONSTANT_SLLONG_MAXIMUM*/ /*#define Z_COMPILER_CONSTANT_SLLONG_MINIMUM*/ +/*#define Z_COMPILER_CONSTANT_BOOL_SIZE*/ +/*#define Z_COMPILER_CONSTANT_BOOL_WIDTH*/ /*#define Z_COMPILER_CONSTANT_WCHAR_SIZE*/ /*#define Z_COMPILER_CONSTANT_WCHAR_WIDTH*/ /*#define Z_COMPILER_CONSTANT_WCHAR_MAXIMUM*/ diff --git a/projects/Zeta/API/Z/inspection/compiler/modules/TinyCC.h b/projects/Zeta/API/Z/inspection/compiler/modules/TinyCC.h index 933eb33..96e7663 100644 --- a/projects/Zeta/API/Z/inspection/compiler/modules/TinyCC.h +++ b/projects/Zeta/API/Z/inspection/compiler/modules/TinyCC.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_compiler_modules_TinyCC_H diff --git a/projects/Zeta/API/Z/inspection/compiler/modules/cc65.h b/projects/Zeta/API/Z/inspection/compiler/modules/cc65.h index 46d49d7..a236e4b 100644 --- a/projects/Zeta/API/Z/inspection/compiler/modules/cc65.h +++ b/projects/Zeta/API/Z/inspection/compiler/modules/cc65.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_compiler_modules_cc65_H diff --git a/projects/Zeta/API/Z/inspection/compiler/modules/generic.h b/projects/Zeta/API/Z/inspection/compiler/modules/generic.h index 1d6abc5..6d70686 100644 --- a/projects/Zeta/API/Z/inspection/compiler/modules/generic.h +++ b/projects/Zeta/API/Z/inspection/compiler/modules/generic.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_compiler_modules_generic_H diff --git a/projects/Zeta/API/Z/inspection/compiler/modules/template.h b/projects/Zeta/API/Z/inspection/compiler/modules/template.h index eaa18fa..21fe624 100644 --- a/projects/Zeta/API/Z/inspection/compiler/modules/template.h +++ b/projects/Zeta/API/Z/inspection/compiler/modules/template.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_compiler_modules_template_H @@ -451,6 +451,8 @@ Released under the terms of the GNU Lesser General Public License v3. */ /*#define Z_COMPILER_CONSTANT_ULLONG_MAXIMUM*/ /*#define Z_COMPILER_CONSTANT_SLLONG_MAXIMUM*/ /*#define Z_COMPILER_CONSTANT_SLLONG_MINIMUM*/ +/*#define Z_COMPILER_CONSTANT_BOOL_SIZE*/ +/*#define Z_COMPILER_CONSTANT_BOOL_WIDTH*/ /*#define Z_COMPILER_CONSTANT_WCHAR_SIZE*/ /*#define Z_COMPILER_CONSTANT_WCHAR_WIDTH*/ /*#define Z_COMPILER_CONSTANT_WCHAR_MAXIMUM*/ diff --git a/projects/Zeta/API/Z/inspection/data_model.h b/projects/Zeta/API/Z/inspection/data_model.h index 06afe48..c7f396e 100644 --- a/projects/Zeta/API/Z/inspection/data_model.h +++ b/projects/Zeta/API/Z/inspection/data_model.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_data_model_H @@ -23,7 +23,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ # include # ifndef Z_DATA_MODEL -# error "Z_DATA_MODEL not defined." +# error "`Z_DATA_MODEL` key not defined." # endif # endif # endif @@ -86,18 +86,31 @@ Released under the terms of the GNU Lesser General Public License v3. */ # define Z_INSERT_DATA_MODEL(lht, rht) lht##SILP64##rht #else -# error "Invalid Z_DATA_MODEL key." +# error "Invalid `Z_DATA_MODEL` key." #endif /* MARK: - Getters */ -#define Z_DATA_MODEL_IS( DATA_MODEL) Z_IS_TRUE(Z_DATA_MODEL_IS_##DATA_MODEL ) -#define Z_DATA_MODEL_HAS_LITERAL(TYPE ) Z_IS_TRUE(Z_DATA_MODEL_HAS_LITERAL_##TYPE) -#define Z_DATA_MODEL_HAS_TYPE( TYPE ) Z_IS_TRUE(Z_DATA_MODEL_HAS_TYPE_##TYPE ) -#define Z_DATA_MODEL_WIDTH( TYPE ) Z_INSERT_DATA_MODEL(Z_, _WIDTH_##TYPE) -#define Z_DATA_MODEL_FUNDAMENTAL(TYPE ) Z_DATA_MODEL_FUNDAMENTAL_##TYPE -#define Z_DATA_MODEL_LITERAL( TYPE ) Z_DATA_MODEL_LITERAL_##TYPE -#define Z_DATA_MODEL_TYPE( TYPE ) Z_DATA_MODEL_TYPE_##TYPE +#define Z_DATA_MODEL_IS(DATA_MODEL) \ + Z_IS_TRUE(Z_DATA_MODEL_IS_##DATA_MODEL) + +#define Z_DATA_MODEL_HAS_LITERAL(TYPE) \ + Z_IS_TRUE(Z_DATA_MODEL_HAS_LITERAL_##TYPE) + +#define Z_DATA_MODEL_HAS_TYPE(TYPE) \ + Z_IS_TRUE(Z_DATA_MODEL_HAS_TYPE_##TYPE) + +#define Z_DATA_MODEL_WIDTH(TYPE) \ + Z_INSERT_DATA_MODEL(Z_, _WIDTH_##TYPE) + +#define Z_DATA_MODEL_FUNDAMENTAL(TYPE) \ + Z_DATA_MODEL_FUNDAMENTAL_##TYPE + +#define Z_DATA_MODEL_LITERAL(TYPE) \ + Z_DATA_MODEL_LITERAL_##TYPE + +#define Z_DATA_MODEL_TYPE(TYPE) \ + Z_DATA_MODEL_TYPE_##TYPE /* MARK: - Selection: int8 */ diff --git a/projects/Zeta/API/Z/inspection/data_model/deduction.h b/projects/Zeta/API/Z/inspection/data_model/deduction.h index 99c6252..87de1db 100644 --- a/projects/Zeta/API/Z/inspection/data_model/deduction.h +++ b/projects/Zeta/API/Z/inspection/data_model/deduction.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_data_model_deduction_H diff --git a/projects/Zeta/API/Z/inspection/data_model/detection.h b/projects/Zeta/API/Z/inspection/data_model/detection.h index 26df80e..c5d9139 100644 --- a/projects/Zeta/API/Z/inspection/data_model/detection.h +++ b/projects/Zeta/API/Z/inspection/data_model/detection.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_data_model_detection_H diff --git a/projects/Zeta/API/Z/inspection/floating-point.h b/projects/Zeta/API/Z/inspection/floating-point.h index f64a087..3b39df2 100644 --- a/projects/Zeta/API/Z/inspection/floating-point.h +++ b/projects/Zeta/API/Z/inspection/floating-point.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_floating_point_H @@ -34,7 +34,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ # define Z_FLOATING_POINT_LITERAL_DFP64 Z_SAME # else -# error "Invalid Z_FLOATING_POINT_FIXED_FUNDAMENTAL_DOUBLE key." +# error "Invalid `Z_FLOATING_POINT_FIXED_FUNDAMENTAL_DOUBLE` key." # endif #endif @@ -62,7 +62,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ # endif # else -# error "Invalid Z_FLOATING_POINT_FIXED_FUNDAMENTAL_FLOAT key." +# error "Invalid `Z_FLOATING_POINT_FIXED_FUNDAMENTAL_FLOAT` key." # endif #endif @@ -120,7 +120,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ # define Z_FLOATING_POINT_LITERAL_IBM_ED Z_SUFFIX_L # else -# error "Invalid Z_FLOATING_POINT_FIXED_FUNDAMENTAL_LDOUBLE key." +# error "Invalid `Z_FLOATING_POINT_FIXED_FUNDAMENTAL_LDOUBLE` key." # endif #endif @@ -303,7 +303,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ # ifdef Z_COMPILER_FIXED_FUNDAMENTAL_FLOAT128X # define Z_FLOATING_POINT_FIXED_FUNDAMENTAL_FLOAT128X Z_COMPILER_FIXED_FUNDAMENTAL_FLOAT128X # else -# error "Z_FLOATING_POINT_FIXED_FUNDAMENTAL_FLOAT128X not defined." +# error "`Z_FLOATING_POINT_FIXED_FUNDAMENTAL_FLOAT128X` key not defined." # endif #endif @@ -319,16 +319,25 @@ Released under the terms of the GNU Lesser General Public License v3. */ # ifdef Z_COMPILER_FIXED_FUNDAMENTAL_DECIMAL128X # define Z_FLOATING_POINT_FIXED_FUNDAMENTAL_DECIMAL128X Z_COMPILER_FIXED_FUNDAMENTAL_DECIMAL128X # else -# error "Z_FLOATING_POINT_FIXED_FUNDAMENTAL_DECIMAL128X not defined." +# error "`Z_FLOATING_POINT_FIXED_FUNDAMENTAL_DECIMAL128X` key not defined." # endif #endif #include -#define Z_FLOATING_POINT_HAS_TYPE( TYPE) Z_IS_TRUE(Z_FLOATING_POINT_HAS_TYPE_##TYPE) -#define Z_FLOATING_POINT_TYPE( TYPE) Z_FLOATING_POINT_TYPE_##TYPE -#define Z_FLOATING_POINT_LITERAL( TYPE) Z_FLOATING_POINT_LITERAL_##TYPE -#define Z_FLOATING_POINT_FUNDAMENTAL( TYPE) Z_FLOATING_POINT_FUNDAMENTAL_##TYPE -#define Z_FLOATING_POINT_FIXED_FUNDAMENTAL(TYPE) Z_FLOATING_POINT_FIXED_FUNDAMENTAL_##TYPE +#define Z_FLOATING_POINT_HAS_TYPE(TYPE) \ + Z_IS_TRUE(Z_FLOATING_POINT_HAS_TYPE_##TYPE) + +#define Z_FLOATING_POINT_TYPE(TYPE) \ + Z_FLOATING_POINT_TYPE_##TYPE + +#define Z_FLOATING_POINT_LITERAL(TYPE) \ + Z_FLOATING_POINT_LITERAL_##TYPE + +#define Z_FLOATING_POINT_FUNDAMENTAL(TYPE) \ + Z_FLOATING_POINT_FUNDAMENTAL_##TYPE + +#define Z_FLOATING_POINT_FIXED_FUNDAMENTAL(TYPE) \ + Z_FLOATING_POINT_FIXED_FUNDAMENTAL_##TYPE #endif /* Z_inspection_floating_point_H */ diff --git a/projects/Zeta/API/Z/inspection/floating-point/completion.h b/projects/Zeta/API/Z/inspection/floating-point/completion.h index 87e66b4..e85a85a 100644 --- a/projects/Zeta/API/Z/inspection/floating-point/completion.h +++ b/projects/Zeta/API/Z/inspection/floating-point/completion.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_floating_point_completion_H diff --git a/projects/Zeta/API/Z/inspection/language.h b/projects/Zeta/API/Z/inspection/language.h index 456d878..3533f1d 100644 --- a/projects/Zeta/API/Z/inspection/language.h +++ b/projects/Zeta/API/Z/inspection/language.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_language_H diff --git a/projects/Zeta/API/Z/inspection/platform.h b/projects/Zeta/API/Z/inspection/platform.h index b3f861c..69f3160 100644 --- a/projects/Zeta/API/Z/inspection/platform.h +++ b/projects/Zeta/API/Z/inspection/platform.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_platform_H @@ -25,6 +25,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ # define Z_PLATFORM Z_PLATFORM_UNKNOWN #endif -#define Z_PLATFORM_IS(PLATFORM) (Z_PLATFORM == Z_PLATFORM_##PLATFORM) +#define Z_PLATFORM_IS(PLATFORM) \ + (Z_PLATFORM == Z_PLATFORM_##PLATFORM) #endif /* Z_inspection_platform_H */ diff --git a/projects/Zeta/API/Z/inspection/platform/detection.h b/projects/Zeta/API/Z/inspection/platform/detection.h index 1b2d292..e54ffa0 100644 --- a/projects/Zeta/API/Z/inspection/platform/detection.h +++ b/projects/Zeta/API/Z/inspection/platform/detection.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_inspection_platform_detection_H diff --git a/projects/Zeta/API/Z/keys/C++.h b/projects/Zeta/API/Z/keys/C++.h index d16b3fd..212b1ab 100644 --- a/projects/Zeta/API/Z/keys/C++.h +++ b/projects/Zeta/API/Z/keys/C++.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_keys_CPP_H @@ -17,6 +17,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ #define Z_CPP14 6 #define Z_CPP17 7 #define Z_CPP20 8 +#define Z_CPP23 9 #define Z_CPP_NAME_CPP1 "C++ v1.0" #define Z_CPP_NAME_CPP2 "C++ v2.0" @@ -26,5 +27,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ #define Z_CPP_NAME_CPP14 "ISO/IEC 14882:2014" #define Z_CPP_NAME_CPP17 "ISO/IEC 14882:2017" #define Z_CPP_NAME_CPP20 "ISO/IEC 14882:2020" +#define Z_CPP_NAME_CPP23 "ISO/IEC 14882:2024" #endif /* Z_keys_CPP_H */ diff --git a/projects/Zeta/API/Z/keys/C.h b/projects/Zeta/API/Z/keys/C.h index aa73159..0209520 100644 --- a/projects/Zeta/API/Z/keys/C.h +++ b/projects/Zeta/API/Z/keys/C.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_keys_C_H @@ -16,6 +16,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ #define Z_C99 5 #define Z_C11 6 #define Z_C17 7 +#define Z_C23 8 #define Z_C_NAME_C78 "K&R C" #define Z_C_NAME_C89 "ANSI X3.159-1989" @@ -24,5 +25,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ #define Z_C_NAME_C99 "ISO/IEC 9899:1999" #define Z_C_NAME_C11 "ISO/IEC 9899:2011" #define Z_C_NAME_C17 "ISO/IEC 9899:2018" +#define Z_C_NAME_C23 "ISO/IEC 9899:2024" #endif /* Z_keys_C_H */ diff --git a/projects/Zeta/API/Z/keys/ISA.h b/projects/Zeta/API/Z/keys/ISA.h index 10a9b33..98497a1 100644 --- a/projects/Zeta/API/Z/keys/ISA.h +++ b/projects/Zeta/API/Z/keys/ISA.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_keys_ISA_H diff --git a/projects/Zeta/API/Z/keys/OS.h b/projects/Zeta/API/Z/keys/OS.h index 3844f7b..86d99b8 100644 --- a/projects/Zeta/API/Z/keys/OS.h +++ b/projects/Zeta/API/Z/keys/OS.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_keys_OS_H @@ -40,7 +40,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ #define Z_OS_IRIX 28 /* SGI */ #define Z_OS_LEMON_OS 29 /* Roberts-White, J.J. */ #define Z_OS_LINUX 30 /* Torvalds, Linus */ -#define Z_OS_LUNIX 31 /* Dallmann, Daniel */ +#define Z_OS_LUNIX 31 /* Dallmann, Daniel */ #define Z_OS_LYNX_OS 32 /* Lynx Software Technologies */ #define Z_OS_MAC_OS 33 /* Apple Computer */ #define Z_OS_MAC_OS_X 34 /* Apple Computer */ diff --git a/projects/Zeta/API/Z/keys/compiler.h b/projects/Zeta/API/Z/keys/compiler.h index df99b00..ebaa355 100644 --- a/projects/Zeta/API/Z/keys/compiler.h +++ b/projects/Zeta/API/Z/keys/compiler.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_keys_compiler_H @@ -46,52 +46,54 @@ Released under the terms of the GNU Lesser General Public License v3. */ #define Z_COMPILER_IBM_Z_OS_C_CPP 34 /* */ #define Z_COMPILER_IMAGECRAFT_C 35 /* */ #define Z_COMPILER_INTEL_CPP 36 /* Intel */ -#define Z_COMPILER_KAI_CPP 37 /* Kuck & Associates */ -#define Z_COMPILER_KEIL_C166 38 /* */ -#define Z_COMPILER_KEIL_C51 39 /* */ -#define Z_COMPILER_KEIL_CARM 40 /* */ -#define Z_COMPILER_LCC 41 /* Fraser, Christopher W. - Hanson, David R. */ -#define Z_COMPILER_MCC 42 /* Sainz de Baranda y Goñi, Manuel */ -#define Z_COMPILER_METAWARE_HIGH_C_CPP 43 /* */ -#define Z_COMPILER_MICROTEC_C_CPP 44 /* */ -#define Z_COMPILER_MINGW 45 /* Peters, Colin */ -#define Z_COMPILER_MIPS_PRO 46 /* */ -#define Z_COMPILER_MIRACLE_C 47 /* */ -#define Z_COMPILER_MPW_CPP 48 /* */ -#define Z_COMPILER_MSC 49 /* Microsoft */ -#define Z_COMPILER_MSVC 50 /* Microsoft */ -#define Z_COMPILER_NDP_C 51 /* Microway */ -#define Z_COMPILER_NORCROFT_C 52 /* */ -#define Z_COMPILER_NVC 53 /* NVIDIA */ -#define Z_COMPILER_NWCC 54 /* */ -#define Z_COMPILER_OPEN64 55 /* */ -#define Z_COMPILER_ORACLE_PRO_C_PRECOMPILER 56 /* */ -#define Z_COMPILER_ORACLE_SOLARIS_STUDIO 57 /* */ -#define Z_COMPILER_PACIFIC_C 58 /* */ -#define Z_COMPILER_PALM_C_CPP 59 /* */ -#define Z_COMPILER_PCC 60 /* Johnson, Stephen C. */ -#define Z_COMPILER_PELLES_C 61 /* Orinius, Pelle */ -#define Z_COMPILER_PGI_C_CPP 62 /* */ -#define Z_COMPILER_RENESAS_C_CPP 63 /* */ -#define Z_COMPILER_SAS_C 64 /* */ -#define Z_COMPILER_SCCZ80 65 /* Z88DK */ -#define Z_COMPILER_SDCC 66 /* */ -#define Z_COMPILER_SNC 67 /* SN Systems */ -#define Z_COMPILER_SYMANTEC_CPP 68 /* */ -#define Z_COMPILER_SYSTEMS_C 69 /* Dignus */ -#define Z_COMPILER_TENDRA 70 /* DERA */ -#define Z_COMPILER_THINK_C 71 /* */ -#define Z_COMPILER_TI_C_CPP_COMPILER 72 /* */ -#define Z_COMPILER_TINY_CC 73 /* Bellard, Fabrice */ -#define Z_COMPILER_TURBO_C 74 /* Borland */ -#define Z_COMPILER_TURBO_CPP 75 /* Borland */ -#define Z_COMPILER_ULTRA_C_CPP 76 /* Microware Systems */ -#define Z_COMPILER_USL 77 /* */ -#define Z_COMPILER_VBCC 78 /* Barthelmann, Volker */ -#define Z_COMPILER_VOS_C 79 /* Stratus Technologies */ -#define Z_COMPILER_VOS_STANDARD_C 80 /* Stratus Technologies */ -#define Z_COMPILER_WATCOM_C_CPP 81 /* Watcom International */ -#define Z_COMPILER_ZORTECH_CPP 82 /* */ +#define Z_COMPILER_JCC 37 /* Kelly, John */ +#define Z_COMPILER_KAI_CPP 38 /* Kuck & Associates */ +#define Z_COMPILER_KEIL_C166 39 /* */ +#define Z_COMPILER_KEIL_C51 40 /* */ +#define Z_COMPILER_KEIL_CARM 41 /* */ +#define Z_COMPILER_LCC 42 /* Fraser, Christopher W. - Hanson, David R. */ +#define Z_COMPILER_MCC 43 /* Sainz de Baranda y Goñi, Manuel */ +#define Z_COMPILER_METAWARE_HIGH_C_CPP 44 /* */ +#define Z_COMPILER_MICROTEC_C_CPP 45 /* */ +#define Z_COMPILER_MINGW 46 /* Peters, Colin */ +#define Z_COMPILER_MINGW_W64 47 /* OneVision Software */ +#define Z_COMPILER_MIPS_PRO 48 /* */ +#define Z_COMPILER_MIRACLE_C 49 /* */ +#define Z_COMPILER_MPW_CPP 50 /* */ +#define Z_COMPILER_MSC 51 /* Microsoft */ +#define Z_COMPILER_MSVC 52 /* Microsoft */ +#define Z_COMPILER_NDP_C 53 /* Microway */ +#define Z_COMPILER_NORCROFT_C 54 /* */ +#define Z_COMPILER_NVC 55 /* NVIDIA */ +#define Z_COMPILER_NWCC 56 /* */ +#define Z_COMPILER_OPEN64 57 /* */ +#define Z_COMPILER_ORACLE_PRO_C_PRECOMPILER 58 /* */ +#define Z_COMPILER_ORACLE_SOLARIS_STUDIO 59 /* */ +#define Z_COMPILER_PACIFIC_C 60 /* */ +#define Z_COMPILER_PALM_C_CPP 61 /* */ +#define Z_COMPILER_PCC 62 /* Johnson, Stephen C. */ +#define Z_COMPILER_PELLES_C 63 /* Orinius, Pelle */ +#define Z_COMPILER_PGI_C_CPP 64 /* */ +#define Z_COMPILER_RENESAS_C_CPP 65 /* */ +#define Z_COMPILER_SAS_C 66 /* */ +#define Z_COMPILER_SCCZ80 67 /* Z88DK */ +#define Z_COMPILER_SDCC 68 /* */ +#define Z_COMPILER_SNC 69 /* SN Systems */ +#define Z_COMPILER_SYMANTEC_CPP 70 /* */ +#define Z_COMPILER_SYSTEMS_C 71 /* Dignus */ +#define Z_COMPILER_TENDRA 72 /* DERA */ +#define Z_COMPILER_THINK_C 73 /* */ +#define Z_COMPILER_TI_C_CPP_COMPILER 74 /* */ +#define Z_COMPILER_TINY_CC 75 /* Bellard, Fabrice */ +#define Z_COMPILER_TURBO_C 76 /* Borland */ +#define Z_COMPILER_TURBO_CPP 77 /* Borland */ +#define Z_COMPILER_ULTRA_C_CPP 78 /* Microware Systems */ +#define Z_COMPILER_USL 79 /* */ +#define Z_COMPILER_VBCC 80 /* Barthelmann, Volker */ +#define Z_COMPILER_VOS_C 81 /* Stratus Technologies */ +#define Z_COMPILER_VOS_STANDARD_C 82 /* Stratus Technologies */ +#define Z_COMPILER_WATCOM_C_CPP 83 /* Watcom International */ +#define Z_COMPILER_ZORTECH_CPP 84 /* */ #define Z_COMPILER_NAME_ACC "ACC" #define Z_COMPILER_NAME_ADAPTIVE_CPP "AdaptiveCpp" @@ -129,6 +131,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ #define Z_COMPILER_NAME_IBM_Z_OS_C_CPP "IBM z/OS C/C++" #define Z_COMPILER_NAME_IMAGECRAFT_C "ImageCraft C" #define Z_COMPILER_NAME_INTEL_CPP "Intel C++" +#define Z_COMPILER_NAME_JCC "JCC" #define Z_COMPILER_NAME_KAI_CPP "KAI C++" #define Z_COMPILER_NAME_KEIL_C166 "KEIL C166" #define Z_COMPILER_NAME_KEIL_C51 "KEIL C51" @@ -138,6 +141,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ #define Z_COMPILER_NAME_METAWARE_HIGH_C_CPP "MetaWare High C/C++" #define Z_COMPILER_NAME_MICROTEC_C_CPP "Microtec C/C++" #define Z_COMPILER_NAME_MINGW "MinGW" +#define Z_COMPILER_NAME_MINGW_W64 "MinGW-w64" #define Z_COMPILER_NAME_MIPS_PRO "MIPSpro" #define Z_COMPILER_NAME_MIRACLE_C "Miracle C" #define Z_COMPILER_NAME_MPW_CPP "MPW C++" diff --git a/projects/Zeta/API/Z/keys/data_model.h b/projects/Zeta/API/Z/keys/data_model.h index 3c08b89..c06522f 100644 --- a/projects/Zeta/API/Z/keys/data_model.h +++ b/projects/Zeta/API/Z/keys/data_model.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_keys_data_model_H diff --git a/projects/Zeta/API/Z/keys/endianness.h b/projects/Zeta/API/Z/keys/endianness.h index 5a92e87..c7b24a7 100644 --- a/projects/Zeta/API/Z/keys/endianness.h +++ b/projects/Zeta/API/Z/keys/endianness.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_keys_endianness_H diff --git a/projects/Zeta/API/Z/keys/fundamental.h b/projects/Zeta/API/Z/keys/fundamental.h index 3424306..c892ce1 100644 --- a/projects/Zeta/API/Z/keys/fundamental.h +++ b/projects/Zeta/API/Z/keys/fundamental.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_keys_fundamental_H @@ -23,7 +23,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ #define Z_FUNDAMENTAL_SLONG 9 /* signed long int */ #define Z_FUNDAMENTAL_ULLONG 10 /* (C99/C++11) unsigned long long int */ #define Z_FUNDAMENTAL_SLLONG 11 /* (C99/C++11) signed long long int */ -#define Z_FUNDAMENTAL_BOOL 12 /* (C99) _Bool / (C++98) bool */ +#define Z_FUNDAMENTAL_BOOL 12 /* (C99) _Bool / (C23/C++98) bool */ #define Z_FUNDAMENTAL_WCHAR 13 /* (C++98) wchar_t */ #define Z_FUNDAMENTAL_CHAR8 14 /* (C++20) char8_t */ #define Z_FUNDAMENTAL_CHAR16 15 /* (C++11) char16_t */ diff --git a/projects/Zeta/API/Z/keys/language.h b/projects/Zeta/API/Z/keys/language.h index ce3f4b7..cc1b67a 100644 --- a/projects/Zeta/API/Z/keys/language.h +++ b/projects/Zeta/API/Z/keys/language.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_keys_language_H diff --git a/projects/Zeta/API/Z/keys/number.h b/projects/Zeta/API/Z/keys/number.h index 1653623..85ca95d 100644 --- a/projects/Zeta/API/Z/keys/number.h +++ b/projects/Zeta/API/Z/keys/number.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_keys_number_H diff --git a/projects/Zeta/API/Z/keys/order.h b/projects/Zeta/API/Z/keys/order.h index 9f22fa7..cb01a09 100644 --- a/projects/Zeta/API/Z/keys/order.h +++ b/projects/Zeta/API/Z/keys/order.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_keys_order_H diff --git a/projects/Zeta/API/Z/keys/platform.h b/projects/Zeta/API/Z/keys/platform.h index 2a595ef..10912f7 100644 --- a/projects/Zeta/API/Z/keys/platform.h +++ b/projects/Zeta/API/Z/keys/platform.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_keys_platform_H @@ -96,5 +96,4 @@ Released under the terms of the GNU Lesser General Public License v3. */ #define Z_PLATFORM_XBOX_360 2042 /* Microsoft */ #define Z_PLATFORM_XBOX_ONE 2043 /* Microsoft */ - #endif /* Z_keys_platform_H */ diff --git a/projects/Zeta/API/Z/macros/T.h b/projects/Zeta/API/Z/macros/T.h index b84a674..7f7efde 100644 --- a/projects/Zeta/API/Z/macros/T.h +++ b/projects/Zeta/API/Z/macros/T.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_T_H diff --git a/projects/Zeta/API/Z/macros/array.h b/projects/Zeta/API/Z/macros/array.h index f0ec3f3..b8af05c 100644 --- a/projects/Zeta/API/Z/macros/array.h +++ b/projects/Zeta/API/Z/macros/array.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_array_H diff --git a/projects/Zeta/API/Z/macros/bit-field.h b/projects/Zeta/API/Z/macros/bit-field.h index 2eb3045..bc5b574 100644 --- a/projects/Zeta/API/Z/macros/bit-field.h +++ b/projects/Zeta/API/Z/macros/bit-field.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_bit_field_H diff --git a/projects/Zeta/API/Z/macros/bitwise.h b/projects/Zeta/API/Z/macros/bitwise.h index 7265487..efb263f 100644 --- a/projects/Zeta/API/Z/macros/bitwise.h +++ b/projects/Zeta/API/Z/macros/bitwise.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_bitwise_H diff --git a/projects/Zeta/API/Z/macros/calendar.h b/projects/Zeta/API/Z/macros/calendar.h index a7b537c..0c89c4e 100644 --- a/projects/Zeta/API/Z/macros/calendar.h +++ b/projects/Zeta/API/Z/macros/calendar.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_calendar_H diff --git a/projects/Zeta/API/Z/macros/casting.h b/projects/Zeta/API/Z/macros/casting.h index a312d43..10bf1f9 100644 --- a/projects/Zeta/API/Z/macros/casting.h +++ b/projects/Zeta/API/Z/macros/casting.h @@ -3,16 +3,22 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_casting_H #define Z_macros_casting_H #ifdef __cplusplus -# define Z_CAST(type) type +# define Z_CAST( type) type +# define Z_CONST_CAST( type) const_cast +# define Z_REINTERPRET_CAST(type) reinterpret_cast +# define Z_STATIC_CAST( type) static_cast #else # define Z_CAST +# define Z_CONST_CAST +# define Z_REINTERPRET_CAST +# define Z_STATIC_CAST #endif #endif /* Z_macros_casting_H */ diff --git a/projects/Zeta/API/Z/macros/character.h b/projects/Zeta/API/Z/macros/character.h index 80e3500..daa5c86 100644 --- a/projects/Zeta/API/Z/macros/character.h +++ b/projects/Zeta/API/Z/macros/character.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_character_H @@ -93,17 +93,15 @@ Released under the terms of the GNU Lesser General Public License v3. */ (value) == 'Z') #endif -#define Z_CHAR_IS_BASE_16_LOWERCASE_DIGIT(value) ( \ - Z_CHAR_IS_BASE_10_DIGIT (value) || \ - Z_CHAR_IS_BASE_16_LOWERCASE_LETTER(value)) +#define Z_CHAR_IS_BASE_16_LOWERCASE_DIGIT(value) \ + (Z_CHAR_IS_BASE_10_DIGIT(value) || Z_CHAR_IS_BASE_16_LOWERCASE_LETTER(value)) -#define Z_CHAR_IS_BASE_16_UPPERCASE_DIGIT(value) ( \ - Z_CHAR_IS_BASE_10_DIGIT (value) || \ - Z_CHAR_IS_BASE_16_UPPERCASE_LETTER(value)) +#define Z_CHAR_IS_BASE_16_UPPERCASE_DIGIT(value) \ + (Z_CHAR_IS_BASE_10_DIGIT(value) || Z_CHAR_IS_BASE_16_UPPERCASE_LETTER(value)) #if Z_CHARACTER_SET_IS_ASCII # define Z_CHAR_IS_CONTROL(value) \ - (((value) & 0xE0) == 0 || (value) == 0x7F) + (((value) & 0xE0) == 0 || (value) == 0x7F) # define Z_CHAR_IS_GRAPHICAL(value) \ ((value) >= '!' && (value) <= '~') @@ -124,23 +122,21 @@ Released under the terms of the GNU Lesser General Public License v3. */ Z_CHAR_IS_BASE_16_LOWERCASE_LETTER(value) || \ Z_CHAR_IS_BASE_16_UPPERCASE_LETTER(value)) -# define Z_CHAR_IS_LETTER(value) ( \ - Z_CHAR_IS_LOWERCASE_LETTER(value) || \ - Z_CHAR_IS_UPPERCASE_LETTER(value)) +# define Z_CHAR_IS_LETTER(value) \ + (Z_CHAR_IS_LOWERCASE_LETTER(value) || Z_CHAR_IS_UPPERCASE_LETTER(value)) #endif #if Z_CHARACTER_SET_UPPERCASE_LETTERS_ARE_CONSECUTIVE && \ Z_CHARACTER_SET_LOWERCASE_LETTERS_ARE_CONSECUTIVE # define Z_CHAR_LOWERCASE(value) \ - ((value) >= 'A' && (value) <= 'Z' ? (value) - 'A' + 'a' : (value)) + ((value) >= 'A' && (value) <= 'Z' ? (value) - 'A' + 'a' : (value)) # define Z_CHAR_UPPERCASE(value) \ - ((value) >= 'a' && (value) <= 'z' ? (value) - 'a' + 'A' : (value)) + ((value) >= 'a' && (value) <= 'z' ? (value) - 'a' + 'A' : (value)) #endif -#define Z_CHAR_IS_ALPHANUMERIC(value) ( \ - Z_CHAR_IS_BASE_10_DIGIT(value) || \ - Z_CHAR_IS_LETTER (value)) +#define Z_CHAR_IS_ALPHANUMERIC(value) \ + (Z_CHAR_IS_BASE_10_DIGIT(value) || Z_CHAR_IS_LETTER(value)) #endif /* Z_macros_character_H */ diff --git a/projects/Zeta/API/Z/macros/hash.h b/projects/Zeta/API/Z/macros/hash.h index fa66df6..ebe3ebf 100644 --- a/projects/Zeta/API/Z/macros/hash.h +++ b/projects/Zeta/API/Z/macros/hash.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_hash_H @@ -14,11 +14,15 @@ Released under the terms of the GNU Lesser General Public License v3. */ /* MARK: - FNV-0 */ #define Z_FNV0_32_INITIALIZER 0 -#define Z_FNV0_32_UPDATE(hash, value) (((hash) * Z_UINT32(0x01000193)) ^ (value)) + +#define Z_FNV0_32_UPDATE(hash, value) \ + (((hash) * Z_UINT32(0x01000193)) ^ (value)) #ifdef Z_UINT64 # define Z_FNV0_64_INITIALIZER 0 -# define Z_FNV0_64_UPDATE(hash, value) (((hash) * Z_UINT64(0x00000100000001B3)) ^ (value)) + +# define Z_FNV0_64_UPDATE(hash, value) \ + (((hash) * Z_UINT64(0x00000100000001B3)) ^ (value)) #endif /* MARK: - FNV-1 */ @@ -34,11 +38,15 @@ Released under the terms of the GNU Lesser General Public License v3. */ /* MARK: - FNV-1a */ #define Z_FNV1A_32_INITIALIZER Z_FNV1_32_INITIALIZER -#define Z_FNV1A_32_UPDATE(hash, value) (((hash) ^ (value)) * Z_UINT32(0x01000193)) + +#define Z_FNV1A_32_UPDATE(hash, value) \ + (((hash) ^ (value)) * Z_UINT32(0x01000193)) #ifdef Z_UINT64 # define Z_FNV1A_64_INITIALIZER Z_FNV1_64_INITIALIZER -# define Z_FNV1A_64_UPDATE(hash, value) (((hash) ^ (value)) * Z_UINT64(0x00000100000001B3)) + +# define Z_FNV1A_64_UPDATE(hash, value) \ + (((hash) ^ (value)) * Z_UINT64(0x00000100000001B3)) #endif #endif /* Z_macros_hash_H */ diff --git a/projects/Zeta/API/Z/macros/iteration.h b/projects/Zeta/API/Z/macros/iteration.h index 670abd3..1b12075 100644 --- a/projects/Zeta/API/Z/macros/iteration.h +++ b/projects/Zeta/API/Z/macros/iteration.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_iteration_H diff --git a/projects/Zeta/API/Z/macros/language.h b/projects/Zeta/API/Z/macros/language.h index 73c59c9..f69471a 100644 --- a/projects/Zeta/API/Z/macros/language.h +++ b/projects/Zeta/API/Z/macros/language.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_language_H diff --git a/projects/Zeta/API/Z/macros/language.hpp b/projects/Zeta/API/Z/macros/language.hpp index 964c481..c02aab8 100644 --- a/projects/Zeta/API/Z/macros/language.hpp +++ b/projects/Zeta/API/Z/macros/language.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_language_HPP diff --git a/projects/Zeta/API/Z/macros/math.h b/projects/Zeta/API/Z/macros/math.h index b90ca3f..49b1c01 100644 --- a/projects/Zeta/API/Z/macros/math.h +++ b/projects/Zeta/API/Z/macros/math.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_math_H diff --git a/projects/Zeta/API/Z/macros/structure.h b/projects/Zeta/API/Z/macros/structure.h index 33fa529..29123c4 100644 --- a/projects/Zeta/API/Z/macros/structure.h +++ b/projects/Zeta/API/Z/macros/structure.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_structure_H diff --git a/projects/Zeta/API/Z/macros/token.h b/projects/Zeta/API/Z/macros/token.h index c7a37e5..305f2ce 100644 --- a/projects/Zeta/API/Z/macros/token.h +++ b/projects/Zeta/API/Z/macros/token.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_token_H @@ -17,7 +17,7 @@ Released under the terms of the GNU Lesser General Public License v3. */ #define Z_SAME(token) token #define Z_z_STRINGIFY(token) #token -#define Z_STRINGIFY( token) Z_z_STRINGIFY(token) +#define Z_STRINGIFY( token) Z_z_STRINGIFY(token) #define Z_z_PREFIX_0( rht) 0##rht #define Z_z_PREFIX_0x( rht) 0x##rht diff --git a/projects/Zeta/API/Z/macros/variadic.h b/projects/Zeta/API/Z/macros/variadic.h index 37584bf..f9ec8a9 100644 --- a/projects/Zeta/API/Z/macros/variadic.h +++ b/projects/Zeta/API/Z/macros/variadic.h @@ -4,7 +4,7 @@ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ Copyright (C) 2006 Laurent Deniau . -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_variadic_H diff --git a/projects/Zeta/API/Z/macros/variadic_control.h b/projects/Zeta/API/Z/macros/variadic_control.h index d257844..cae579a 100644 --- a/projects/Zeta/API/Z/macros/variadic_control.h +++ b/projects/Zeta/API/Z/macros/variadic_control.h @@ -4,7 +4,7 @@ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ Copyright (C) 2015 Petr Kobalicek . -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_variadic_control_H diff --git a/projects/Zeta/API/Z/macros/variadic_pasting.h b/projects/Zeta/API/Z/macros/variadic_pasting.h index 2f90419..41326bc 100644 --- a/projects/Zeta/API/Z/macros/variadic_pasting.h +++ b/projects/Zeta/API/Z/macros/variadic_pasting.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_variadic_pasting_H diff --git a/projects/Zeta/API/Z/macros/version.h b/projects/Zeta/API/Z/macros/version.h index 202d65d..a5d24c4 100644 --- a/projects/Zeta/API/Z/macros/version.h +++ b/projects/Zeta/API/Z/macros/version.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_macros_version_H diff --git a/projects/Zeta/API/Z/protocols/network/7/HTTP.h b/projects/Zeta/API/Z/protocols/network/7/HTTP.h index 25662d4..ddea8ce 100644 --- a/projects/Zeta/API/Z/protocols/network/7/HTTP.h +++ b/projects/Zeta/API/Z/protocols/network/7/HTTP.h @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_protocols_network_7_HTTP_H diff --git a/projects/Zeta/API/Z/traits/TypeCount.hpp b/projects/Zeta/API/Z/traits/TypeCount.hpp index 5064485..9ec6a61 100644 --- a/projects/Zeta/API/Z/traits/TypeCount.hpp +++ b/projects/Zeta/API/Z/traits/TypeCount.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_traits_TypeCount_HPP diff --git a/projects/Zeta/API/Z/traits/TypeList.hpp b/projects/Zeta/API/Z/traits/TypeList.hpp index 7b6193d..dc5b4fd 100644 --- a/projects/Zeta/API/Z/traits/TypeList.hpp +++ b/projects/Zeta/API/Z/traits/TypeList.hpp @@ -3,7 +3,7 @@ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ -Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. +Copyright (C) 2006-2025 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_traits_TypeList_HPP @@ -70,7 +70,6 @@ Released under the terms of the GNU Lesser General Public License v3. */ # endif namespace Zeta { - template struct TypeListSize; template