You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(208) |
Nov
(108) |
Dec
(114) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(160) |
Feb
(184) |
Mar
(149) |
Apr
(148) |
May
(168) |
Jun
(144) |
Jul
(194) |
Aug
(47) |
Sep
(40) |
Oct
(44) |
Nov
(54) |
Dec
(30) |
2005 |
Jan
(77) |
Feb
(77) |
Mar
(69) |
Apr
(22) |
May
(21) |
Jun
(4) |
Jul
(3) |
Aug
(1) |
Sep
(11) |
Oct
(26) |
Nov
|
Dec
(10) |
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(7) |
Jun
(11) |
Jul
(59) |
Aug
(51) |
Sep
(34) |
Oct
(6) |
Nov
(4) |
Dec
(24) |
2007 |
Jan
(102) |
Feb
(69) |
Mar
(50) |
Apr
(56) |
May
(198) |
Jun
(119) |
Jul
(51) |
Aug
(48) |
Sep
(49) |
Oct
(87) |
Nov
(107) |
Dec
(79) |
2008 |
Jan
(46) |
Feb
(32) |
Mar
(60) |
Apr
(15) |
May
(39) |
Jun
(60) |
Jul
(30) |
Aug
(26) |
Sep
(11) |
Oct
(26) |
Nov
(50) |
Dec
(56) |
2009 |
Jan
(55) |
Feb
(7) |
Mar
(8) |
Apr
(21) |
May
(15) |
Jun
(13) |
Jul
(20) |
Aug
(14) |
Sep
(19) |
Oct
(6) |
Nov
(3) |
Dec
(7) |
2010 |
Jan
(4) |
Feb
(9) |
Mar
(1) |
Apr
|
May
(13) |
Jun
(1) |
Jul
(4) |
Aug
(11) |
Sep
(11) |
Oct
(23) |
Nov
(16) |
Dec
(33) |
2011 |
Jan
(49) |
Feb
(33) |
Mar
(12) |
Apr
(73) |
May
(44) |
Jun
(71) |
Jul
(14) |
Aug
(3) |
Sep
(12) |
Oct
|
Nov
(44) |
Dec
(25) |
2012 |
Jan
(36) |
Feb
(28) |
Mar
(7) |
Apr
|
May
(21) |
Jun
(14) |
Jul
(7) |
Aug
|
Sep
(8) |
Oct
(18) |
Nov
(25) |
Dec
(59) |
2013 |
Jan
(30) |
Feb
(30) |
Mar
(14) |
Apr
(7) |
May
(91) |
Jun
(11) |
Jul
(5) |
Aug
(4) |
Sep
(21) |
Oct
(6) |
Nov
|
Dec
(4) |
2014 |
Jan
(6) |
Feb
(5) |
Mar
(3) |
Apr
(2) |
May
(7) |
Jun
|
Jul
(3) |
Aug
(2) |
Sep
(6) |
Oct
|
Nov
(1) |
Dec
(8) |
2015 |
Jan
(7) |
Feb
(2) |
Mar
(77) |
Apr
(23) |
May
(69) |
Jun
(26) |
Jul
(2) |
Aug
(4) |
Sep
(2) |
Oct
(7) |
Nov
(9) |
Dec
(17) |
2016 |
Jan
(5) |
Feb
(1) |
Mar
(18) |
Apr
(57) |
May
(134) |
Jun
(96) |
Jul
(52) |
Aug
(76) |
Sep
(26) |
Oct
(49) |
Nov
(44) |
Dec
(23) |
2017 |
Jan
(72) |
Feb
(13) |
Mar
(29) |
Apr
(19) |
May
(61) |
Jun
(75) |
Jul
(58) |
Aug
(165) |
Sep
(62) |
Oct
(23) |
Nov
(41) |
Dec
(11) |
2018 |
Jan
(18) |
Feb
(16) |
Mar
(20) |
Apr
(56) |
May
(28) |
Jun
(49) |
Jul
(37) |
Aug
(15) |
Sep
(32) |
Oct
(11) |
Nov
(10) |
Dec
(11) |
2019 |
Jan
(50) |
Feb
(12) |
Mar
(26) |
Apr
(12) |
May
(6) |
Jun
|
Jul
(6) |
Aug
|
Sep
(10) |
Oct
(1) |
Nov
(1) |
Dec
|
2020 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(12) |
Oct
|
Nov
|
Dec
|
2021 |
Jan
|
Feb
(39) |
Mar
(31) |
Apr
|
May
(2) |
Jun
(2) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2023 |
Jan
(1) |
Feb
(1) |
Mar
(19) |
Apr
(2) |
May
(4) |
Jun
(14) |
Jul
(11) |
Aug
(7) |
Sep
(7) |
Oct
(18) |
Nov
(5) |
Dec
|
2024 |
Jan
(2) |
Feb
(5) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(4) |
Aug
|
Sep
|
Oct
(7) |
Nov
|
Dec
|
From: <sba...@us...> - 2023-08-21 17:12:56
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch master in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/4b1a7e6f32ec5c364ab05c2577199a868a80aaba/ commit 4b1a7e6f32ec5c364ab05c2577199a868a80aaba Author: Miroslav Ďurčík <743...@us...> AuthorDate: Mon Aug 7 23:48:13 2023 +0200 ci: Daily test (pre)release as new release with date+time, dropping older releases (#42) plus: - repeat release creation/update to update body after files have been updated. Forcing updating of files in SourceForge, if release existed already. - Append current date and time to nightly build's tag, remove all but the last 5 such releases. https://github.com/arki55/fuse-fuse/pull/42 https://sourceforge.net/p/arki55-fuse-mod/tickets/13/ --- .github/workflows/nightly_build.yml | 5 +- .github/workflows/test_release.yml | 110 +++++++++++++++++++++++++++++++++++- 2 files changed, 111 insertions(+), 4 deletions(-) diff --git a/.github/workflows/nightly_build.yml b/.github/workflows/nightly_build.yml index af63e72e..7cac7eba 100755 --- a/.github/workflows/nightly_build.yml +++ b/.github/workflows/nightly_build.yml @@ -17,7 +17,7 @@ jobs: contents: write steps: - name: "Checkout code" - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 - name: "Merge fresh ${{ vars.PARENT_FUSE_BRANCH }} from ${{ vars.PARENT_FUSE_REPO }}" @@ -29,6 +29,7 @@ jobs: git push # Build and release nightly prerelease version from master (no draft) + # Add current date and time to the tag, keep latest 5 master: needs: [catchup] name: "Nightly build from master" @@ -38,5 +39,7 @@ jobs: draft: false generateReleaseNotes: true libspectrum_branch: "master" + add_date_time: true + keep_latest: 5 secrets: RELEASE_TOKEN: "${{ secrets.RELEASE_TOKEN }}" diff --git a/.github/workflows/test_release.yml b/.github/workflows/test_release.yml index fbcd136f..00787455 100644 --- a/.github/workflows/test_release.yml +++ b/.github/workflows/test_release.yml @@ -25,7 +25,17 @@ on: required: true default: "master" description: "Libspectrum's branch to use" - + add_date_time: + type: boolean + required: false + default: false + description: "If enabled, current date and time is added to the name and tag of release, making it unique." + keep_latest: + type: number + required: false + default: 0 + description: "Number of latest releases to keep (only if date and time is appended)" + # Reused also from nightly build workflow workflow_call: inputs: @@ -48,6 +58,16 @@ on: required: false default: "master" description: "Libspectrum's branch to use" + add_date_time: + type: boolean + required: false + default: false + description: "If enabled, current date and time is added to the name and tag of release, making it unique." + keep_latest: + type: number + required: false + default: 0 + description: "Number of latest releases to keep (only if date and time is appended)" secrets: RELEASE_TOKEN: required: true @@ -108,6 +128,9 @@ jobs: - build-win32-ui-default - build-sdl-ui-sdl-sound runs-on: ubuntu-latest + outputs: + use_tag: ${{ steps.prep.outputs.use_tag }} + use_tag_base: ${{ steps.prep.outputs.use_tag_base }} steps: # Prepare friendly tag name ( slashes => _ ) - name: (1) Prepare variables @@ -115,16 +138,43 @@ jobs: run: | ref_name="${{ github.ref_name }}" use_tag="test_${ref_name//\//_}" + use_tag_base="${use_tag}" + + if [[ ${{ inputs.add_date_time == 'true' }} ]]; then + dt=`date "+%Y-%m-%d--%H-%M-%S"` + use_tag="${use_tag}_${dt}" + fi + echo "Tag name: ${use_tag}" + echo "Tag base: ${use_tag_base}" echo "use_tag=${use_tag}" >> "$GITHUB_OUTPUT" + echo "use_tag_base=${use_tag_base}" >> "$GITHUB_OUTPUT" - - name: (2) Download all generated files + # Prepare readme file for created release + - name: (2) Prepare description file + id: readme + run: | + readme_file="README.md" + echo "README file: ${readme_file}" + echo "readme_file=${readme_file}" >> "$GITHUB_OUTPUT" + + # Generate readme file. + # Make sure to be always unique, otherwise sync to SourceForge will not work. + # Adding current date and time should suffice. + echo -e "### ${{ inputs.reason }}\n\nRepo: ${{ github.repositoryUrl }}\n\nBranch: ${{ github.ref_name }}\n\nActor: ${{ github.actor }}\n\nCreated: `date -u`\n\n\ + " >> "$readme_file" + echo "Content: " + cat "$readme_file" + + - name: (3) Download all generated files uses: actions/download-artifact@v3 - - name: (3) Created release with zip files + - name: (4) Create release with zip files uses: ncipollo/release-action@v1 + id: create-release with: name: "Test build for ${{ github.ref_name }}" + # Attach all generated build zips artifacts: "*/*.zip" # determines structure of files in Source Forge @@ -139,7 +189,61 @@ jobs: token: "${{ secrets.RELEASE_TOKEN }}" # Allow updating releases allowUpdates: true + # Force updating of artifacts + replacesArtifacts: true + removeArtifacts: true # Generate release note? generateReleaseNotes: ${{ inputs.generateReleaseNotes }} # Any error should fail the build artifactErrorsFailBuild: true + # Do not set body now - only in the next step + + # Allow GitHub take breath, sync stuff + - run: sleep 5 + + - name: (5) Update body of release (forcing files sync to SourceForge) + uses: ncipollo/release-action@v1 + with: + # Repeat some values as they were in the previous step + name: "Test build for ${{ github.ref_name }}" + tag: "${{ steps.prep.outputs.use_tag }}" + prerelease: true + draft: ${{ inputs.draft }} + commit: ${{ github.ref_name }} + token: "${{ secrets.RELEASE_TOKEN }}" + allowUpdates: true + artifactErrorsFailBuild: true + generateReleaseNotes: ${{ inputs.generateReleaseNotes }} + + # Keep files as they are here - no adding, updating or deleting + + # Use readme.md file for the body part NOW + bodyFile: ${{ steps.readme.outputs.readme_file }} + + - name: (6) Adding summary + run: | + echo '### New test release has been created :open_file_folder:' >> $GITHUB_STEP_SUMMARY + echo 'Id: ${{ steps.create-release.outputs.id }}' >> $GITHUB_STEP_SUMMARY + echo 'Url: ${{ steps.create-release.outputs.html_url }}' >> $GITHUB_STEP_SUMMARY + echo 'Upload Url: ${{ steps.create-release.outputs.upload_url }}' >> $GITHUB_STEP_SUMMARY + echo 'Tag base: ${{ steps.prep.outputs.use_tag_base }}' >> $GITHUB_STEP_SUMMARY + echo 'Tag name: ${{ steps.prep.outputs.use_tag }}' >> $GITHUB_STEP_SUMMARY + + ############################################### + ### Cleanup, delete olf releases (optional) ### + ############################################### + cleanup: + if: inputs.add_date_time && inputs.keep_latest>0 + name: "Delete Older Releases" + needs: + - release + runs-on: ubuntu-latest + steps: + - name: Delete Older Releases + uses: dev-drprasad/delete-older-releases@v0.2.1 + with: + keep_latest: ${{ inputs.keep_latest }} + delete_tags: true + delete_tag_pattern: "${{ needs.release.outputs.use_tag_base }}" + env: + GITHUB_TOKEN: "${{ secrets.RELEASE_TOKEN }}" |
From: <sba...@us...> - 2023-08-21 17:12:54
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch master in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/06039b514e8391d5fe7c7b8e88c9ac9a888f67fe/ commit 06039b514e8391d5fe7c7b8e88c9ac9a888f67fe Author: Miroslav Durcik / Arki55 <mir...@gm...> AuthorDate: Tue Jul 25 15:31:06 2023 +0200 ci: Remove unused workflow file --- .github/workflows/deploy_build_sub.yml | 119 --------------------------------- 1 file changed, 119 deletions(-) diff --git a/.github/workflows/deploy_build_sub.yml b/.github/workflows/deploy_build_sub.yml deleted file mode 100644 index e94ade4e..00000000 --- a/.github/workflows/deploy_build_sub.yml +++ /dev/null @@ -1,119 +0,0 @@ -# Reusable workflow for deploying build file(s) via FTP -name: Upload to FTP -run-name: Upload build file(s) to FTP / ${{ github.actor }} / - -on: - workflow_call: - inputs: - # Name this setup (no spaces please) - artefact: - type: string - required: true - deploy_zip: - type: boolean - required: true - deploy_sha1: - type: boolean - required: false - default: false - secrets: - DEPLOY_ZIP_PATH: - description: "Relative path that prefixes uploaded ZIP file on FTP server" - required: true - DEPLOY_ZIP_HOST: - description: "Hostname of FTP server where ZIP package will be uploaded" - required: true - DEPLOY_ZIP_USER: - description: "Username that will be used for uploading ZIP file to FTP server" - required: true - DEPLOY_ZIP_PASS: - description: "Password for user that will be used for uploading ZIP package to FTP server" - required: true - -jobs: - upload: - name: Upload to FTP - runs-on: ubuntu-latest - timeout-minutes: 5 - env: - file_path_artefact: ${{ inputs.artefact }} - file_path_zip: ${{ inputs.artefact }}.zip - file_path_sha1: ${{ inputs.artefact }}.zip.sha1 - - deploy_zip_path: ${{ secrets.DEPLOY_ZIP_PATH }} - deploy_zip_host: ${{ secrets.DEPLOY_ZIP_HOST }} - deploy_zip_user: ${{ secrets.DEPLOY_ZIP_USER }} - deploy_zip_pass: ${{ secrets.DEPLOY_ZIP_PASS }} - steps: - - name: (1) Download build artefact - uses: actions/download-artifact@v3 - with: - name: ${{ env.file_path_artefact }} - - - name: (2) Verify FTP/DEPLOY secrets are set - if: ${{ inputs.deploy_zip }} - run: | - error=0 - if [[ -z "${{ env.deploy_zip_path }}" ]]; then - echo "::error::DEPLOY_ZIP_PATH secret missing" - error=1 - fi - - if [[ -z "${{ env.deploy_zip_host }}" ]]; then - echo "::error::DEPLOY_ZIP_HOST secret missing" - error=1 - fi - - if [[ -z "${{ env.deploy_zip_user }}" ]]; then - echo "::error::DEPLOY_ZIP_USER secret missing" - error=1 - fi - - if [[ -z "${{ env.deploy_zip_pass }}" ]]; then - echo "::error::DEPLOY_ZIP_PASS secret missing" - error=1 - fi - - if [[ $error -eq 1 ]]; then - exit 1 - fi - - echo "All FTP/DEPLOY parameters set" - - - name: (3a) Prepare data before deploy (zip) - id: deploy-zip - if: ${{ inputs.deploy_zip }} - run: | - cd ${GITHUB_WORKSPACE} - echo "Content of directory:" - ls -laR - - echo "Deploying file ${{ env.file_path_zip }}" - - src="${GITHUB_WORKSPACE}/${{ env.file_path_zip }}" - dest="${{ env.deploy_zip_path }}/${{ github.ref_name }}/${{ env.file_path_zip }}" - - echo "Source file: $src" - echo "Destination file: $dest" - - echo "src=${src}" >> "$GITHUB_OUTPUT" - echo "dest=${dest}" >> "$GITHUB_OUTPUT" - - - name: (3b) 📂 Send zip file - uses: bayssmekanique/action-simple-file-upload@v1.1.3 - with: - host: "${{ env.deploy_zip_host }}" - user: "${{ env.deploy_zip_user }}" - password: "${{ env.deploy_zip_pass }}" - src: "${{ steps.deploy-zip.outputs.src }}" - dest: "${{ steps.deploy-zip.outputs.dest }}" - - - name: (3) Deploy SHA1 file (different location) - if: ${{ inputs.deploy_sha1 }} - run: | - echo "Deploying file ${{ env.file_path_sha1 }}" - echo "Not implemented yet" - - - name: (4) Finish - run: | - echo "🍏 Finishing with status ${{ job.status }}." |
From: <sba...@us...> - 2023-08-21 17:12:53
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch master in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/165e303c7e6e245f163567df5ab3758add002911/ commit 165e303c7e6e245f163567df5ab3758add002911 Author: Miroslav Ďurčík <743...@us...> AuthorDate: Tue Jul 25 15:19:51 2023 +0200 CI: TEST-BUILD and Nightly Build GitHub workflows feat: --with-test-build configure parameter. Implemented new configure parameter --with-test-build="<First line\\nSecond line" This enables special messages and popups within the application warning about the purpose of this special build. This should distinguish it from the official build. CI: Test-Build workflow - Implemented new github workflow to build so called Test-Builds and release them as GitHub pre-release. Optionally synced to SourceForge. - Initially only windows win32 (ui) and windows SDL configurations have been implemented. "Test version of Fuse App" can be triggered only manually from Actions tab, provided 3 parameters: Libspectrum's branch, description and if to mark generated release as draft. - Test Build workflow is triggered manually or on pull request - On top of used --with-test-build configure parameter, the M4 FUSE_VERSION constant is changed to TEST-BUILD, thus affecting all "About Fuse" dialogs. - Test releases can be updated, workflow can be executed multiple times for the same branch. CI: Added workflow for nightly build : creates pre-release from current master - Allow manual execution of nightly build + every day at 1 AM automatically - Nightly build should generate release notes (list of recent commits) - Master from fuse (source forge) is merged before doing nightly build https://sourceforge.net/p/arki55-fuse-mod/tickets/13/ --- .github/workflows/build_linux.yml | 2 +- .github/workflows/build_macos.yml | 2 +- .github/workflows/build_wii.yml | 2 +- .github/workflows/build_wii_sub.yml | 1 - .github/workflows/build_windows.yml | 7 +- .github/workflows/build_windows_sub.yml | 171 +++++++++++++++++++++++-- .github/workflows/deploy_build_sub.yml | 119 +++++++++++++++++ .github/workflows/nightly_build.yml | 42 ++++++ .github/workflows/test_release.yml | 145 +++++++++++++++++++++ .github/workflows/test_release_windows_sub.yml | 45 +++++++ configure.ac | 30 ++++- fuse.c | 23 ++++ ui/widget/error.c | 12 +- 13 files changed, 582 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml index 4cd04b26..eeeea7f4 100644 --- a/.github/workflows/build_linux.yml +++ b/.github/workflows/build_linux.yml @@ -2,7 +2,7 @@ name: Fuse App For Linux run-name: Build Fuse App for Linux / ${{ github.actor }} / # Executed upon each commit pushed, merge commit in PR -on: [push, pull_request] +on: [pull_request] jobs: libspectrum: diff --git a/.github/workflows/build_macos.yml b/.github/workflows/build_macos.yml index 787071e9..dd613b59 100644 --- a/.github/workflows/build_macos.yml +++ b/.github/workflows/build_macos.yml @@ -2,7 +2,7 @@ name: Fuse App For MacOS run-name: Build Fuse App for MacOS / ${{ github.actor }} / # Executed upon each commit pushed, merge commit in PR -on: [push, pull_request] +on: [pull_request] jobs: libspectrum: diff --git a/.github/workflows/build_wii.yml b/.github/workflows/build_wii.yml index 66d91384..e2917858 100644 --- a/.github/workflows/build_wii.yml +++ b/.github/workflows/build_wii.yml @@ -2,7 +2,7 @@ name: Fuse App For WII run-name: Build Fuse App for WII / ${{ github.actor }} / # Executed upon each commit pushed, merge commit in PR -on: [push, pull_request] +on: [pull_request] jobs: libspectrum: diff --git a/.github/workflows/build_wii_sub.yml b/.github/workflows/build_wii_sub.yml index 7993292c..4a348931 100644 --- a/.github/workflows/build_wii_sub.yml +++ b/.github/workflows/build_wii_sub.yml @@ -58,7 +58,6 @@ jobs: echo "$DEVKITPPC/bin" >> $GITHUB_PATH - name: (2) Install dependencies - if: run: | echo "Installing dependencies .." echo "Using devkitpro/devkitppc image" diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml index 3a03777b..92e092dd 100644 --- a/.github/workflows/build_windows.yml +++ b/.github/workflows/build_windows.yml @@ -2,7 +2,7 @@ name: Fuse App For Windows run-name: Build Fuse App for Windows / ${{ github.actor }} / # Executed upon each commit pushed, merge commit in PR -on: [push, pull_request] +on: [pull_request] jobs: libspectrum: @@ -24,6 +24,7 @@ jobs: needs: [libspectrum] uses: ./.github/workflows/build_windows_sub.yml with: + key: "win32-ui-default" dependencies: "mingw64-i686-libxml2" configure_params: "--with-win32" verify_ui: "win32" @@ -36,6 +37,7 @@ jobs: needs: [libspectrum] uses: ./.github/workflows/build_windows_sub.yml with: + key: "win32-ui-no-libxml2" dependencies: "" configure_params: "--with-win32 --without-libxml2" verify_ui: "win32" @@ -48,6 +50,7 @@ jobs: needs: [libspectrum] uses: ./.github/workflows/build_windows_sub.yml with: + key: "win32-ui-win32-sound" dependencies: "" configure_params: "--with-win32 --with-audio-driver=win32sound" verify_ui: "win32" @@ -60,6 +63,7 @@ jobs: needs: [libspectrum] uses: ./.github/workflows/build_windows_sub.yml with: + key: "win32-ui-null-sound" dependencies: "" configure_params: "--with-win32 --with-audio-driver=null" verify_ui: "win32" @@ -72,6 +76,7 @@ jobs: needs: [libspectrum] uses: ./.github/workflows/build_windows_sub.yml with: + key: "sdl1-ui-sdl1-sound" dependencies: "mingw64-i686-SDL" configure_params: "--without-win32 --with-sdl --disable-sdl2 --with-audio-driver=sdl" verify_ui: "sdl" diff --git a/.github/workflows/build_windows_sub.yml b/.github/workflows/build_windows_sub.yml index 2b476082..c895f5f2 100644 --- a/.github/workflows/build_windows_sub.yml +++ b/.github/workflows/build_windows_sub.yml @@ -5,6 +5,10 @@ run-name: Build Fuse App for windows / ${{ github.actor }} / on: workflow_call: inputs: + # Name this setup (no spaces please) + key: + type: string + required: true dependencies: type: string required: false @@ -13,6 +17,10 @@ on: type: string required: false default: "" + fuse_version: + type: string + required: false + default: "" verify_ui: type: string required: true @@ -28,6 +36,10 @@ on: type: string required: false default: "" + upload_artifacts: + type: boolean + required: false + default: true jobs: build: @@ -41,6 +53,10 @@ jobs: CPPFLAGS: "-I/usr/local/i686-w64-mingw32/include" LDFLAGS: "-L/usr/local/i686-w64-mingw32/lib" PKG_CONFIG_LIBDIR: "/usr/local/i686-w64-mingw32/lib/pkgconfig:/usr/i686-w64-mingw32/sys-root/mingw/lib/pkgconfig" + + # Small help when copying dlls + CYGWIN_LIBDIR: "/usr/i686-w64-mingw32/sys-root/mingw/bin/" + # In case of SDL SDL_CONFIG: "/usr/i686-w64-mingw32/sys-root/mingw/bin/sdl-config" steps: @@ -73,6 +89,7 @@ jobs: gettext-devel \ libtool \ make \ + zip \ mingw64-i686-bzip2 \ mingw64-i686-gcc-core \ mingw64-i686-gcc-g++ \ @@ -80,7 +97,7 @@ jobs: mingw64-i686-libgpg-error \ mingw64-i686-libpng \ mingw64-i686-win-iconv \ - mingw64-i686-winpthread \ + mingw64-i686-winpthreads \ mingw64-i686-zlib \ mingw64-i686-audiofile \ pkg-config \ @@ -92,7 +109,7 @@ jobs: name: libspectrum-installed-windows-fuse-app path: libspectrum - - name: (5) Install libspectrum from artefact + - name: (4b) Install libspectrum from artefact run: | cd ${GITHUB_WORKSPACE} # Extract (-x) files into /usr/local (cannot work with root /) @@ -101,14 +118,26 @@ jobs: echo "Done" shell: C:\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' - - name: (6) Autogen.sh + - name: (5a) Adjust fuse_version + if: ${{ inputs.fuse_version }} + run: | + cd ${GITHUB_WORKSPACE} + file="configure.ac" + replace="${{ inputs.fuse_version }}" + content=`cat $file` + content2=${content//m4_define(\[fuse_version\], \[[0-9].[0-9].[0-9]\])/m4_define(\[fuse_version\], \[$replace\])} + echo "$content2" > $file + shell: C:\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' + + - name: (5b) Autogen.sh run: | cd ${GITHUB_WORKSPACE} echo "Running autogen.sh .." ./autogen.sh shell: C:\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' - - name: (7) Configure for Windows + - name: (6) Configure for Windows + id: run-configure run: | cd ${GITHUB_WORKSPACE} echo "Running configure .." @@ -121,7 +150,16 @@ jobs: |& tee ./configure.out shell: C:\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' - - name: (8) Verify output from configure + - name: (6b) Check config.log (on failure) + if: failure() && steps.run-configure.outcome != 'success' + run: | + cd ${GITHUB_WORKSPACE} + + echo "Reading config.log file .." + cat config.log + shell: C:\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' + + - name: (6c) Verify output from configure # Most of the tested strings are common for all Windows builds # Only the strings related to UI selection differ run: | @@ -139,14 +177,16 @@ jobs: .github/scripts/in_config.sh "libxml2 support: ${{ inputs.verify_libxml2 }}" .github/scripts/in_config.sh "Selected audio driver: ${{ inputs.verify_audio }}" shell: C:\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' - - if: ${{ inputs.verify_other }} + + - name: (6d) Verify optional parameter + if: ${{ inputs.verify_other }} run: | cd ${GITHUB_WORKSPACE} .github/scripts/in_config.sh "${{ inputs.verify_other }}" shell: C:\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' - - name: (9) Make + - name: (7) Make run: | cd ${GITHUB_WORKSPACE} @@ -154,14 +194,123 @@ jobs: make shell: C:\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' - - name: (10) Install + - name: (8) Copy dependency dlls + id: copy-dlls run: | cd ${GITHUB_WORKSPACE} + echo "Create distrib folder if missing .." + + FUSE_VERSION=`./configure --version | grep -Eo "fuse configure (.+)"` + FUSE_VERSION=${FUSE_VERSION//fuse configure /} + echo "Fuse version: $FUSE_VERSION" + + DEST_DIR="fuse-${FUSE_VERSION}-${{ inputs.verify_ui }}" + echo "Dest dir: $DEST_DIR" + if [[ ! -d "$DEST_DIR" ]]; then + mkdir $DEST_DIR + fi + + echo "Copying mandatory dependency dlls .." + cp ${CYGWIN_LIBDIR}libgcc_s_sjlj-1.dll $DEST_DIR + cp ${CYGWIN_LIBDIR}libwinpthread-1.dll $DEST_DIR + cp ${CYGWIN_LIBDIR}libgpg-error-0.dll $DEST_DIR + cp ${CYGWIN_LIBDIR}libstdc++-6.dll $DEST_DIR + cp ${CYGWIN_LIBDIR}libpng16-16.dll $DEST_DIR + + echo "Copying optional dependency dlls .." + # Don't have logic to check what was enabled, so copying all + + # SDL dlls + cp ${CYGWIN_LIBDIR}SDL.dll $DEST_DIR || true + + # Zlib dlls + cp ${CYGWIN_LIBDIR}zlib1.dll $DEST_DIR || true + + # Bzip2 dlls + cp ${CYGWIN_LIBDIR}libbz2-1.dll $DEST_DIR || true + + # libgcrypt dlls + cp ${CYGWIN_LIBDIR}libgcrypt-20.dll $DEST_DIR || true + + # Audiofile dlls + cp ${CYGWIN_LIBDIR}libaudiofile-1.dll $DEST_DIR || true + cp ${CYGWIN_LIBDIR}libFLAC-8.dll $DEST_DIR || true + cp ${CYGWIN_LIBDIR}libOGG-0.dll $DEST_DIR || true + + # LibXML2 dlls + cp ${CYGWIN_LIBDIR}libxml2-2.dll $DEST_DIR || true + cp ${CYGWIN_LIBDIR}iconv.dll $DEST_DIR || true + cp ${CYGWIN_LIBDIR}liblzma-5.dll $DEST_DIR || true + + echo "Copying libspectrum dll .." + cp /usr/local/i686-w64-mingw32/bin/libspectrum-9.dll $DEST_DIR + + # Copy them to z80 folder as well + cp -r $DEST_DIR/*.dll z80/ + + echo "Remember distribution path .." + echo "FUSE_DISTR_DIR=${DEST_DIR}" >> "$GITHUB_OUTPUT" + + echo "Done." + + shell: C:\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' + + - name: (9) Run tests + id: run-tests + run: | + cd ${GITHUB_WORKSPACE} + + echo "Bulding and running tests .." + #cd z80 + #./coretest.exe + echo "(skipped)" - echo "Running make dist-win32-dir .." - make install dist-win32-dir shell: C:\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' - - name: (11) Finish + - name: (10) Create distribution file(s) + run: | + cd ${GITHUB_WORKSPACE} + + echo "Running make dist-win32-zip .." + make dist-win32-zip + shell: C:\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' + + - name: (10b) Rename distribution files, patch SHA1 file + id: rename-files + run: | + cd ${GITHUB_WORKSPACE} + + base_name="fuse-windows-${{ inputs.key }}" + + zip_from=${{ steps.copy-dlls.outputs.FUSE_DISTR_DIR }}.zip + zip_to="${base_name}.zip" + + echo "Renaming ZIP file from $zip_from to $zip_to" + mv $zip_from $zip_to + + sha1_from=${{ steps.copy-dlls.outputs.FUSE_DISTR_DIR }}.zip.sha1 + sha1_to="${base_name}.zip.sha1" + + echo "Renaming SHA1 file from $sha1_from to $sha1_to" + mv $sha1_from $sha1_to + + echo "Remember new file names" + echo "FUSE_DISTR_BASE=${base_name}" >> "$GITHUB_OUTPUT" + echo "FUSE_DISTR_ZIP=${zip_to}" >> "$GITHUB_OUTPUT" + echo "FUSE_DISTR_SHA1=${sha1_to}" >> "$GITHUB_OUTPUT" + + shell: C:\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' + + - name: (11) Upload generated artifact(s) + if: ${{ inputs.upload_artifacts }} + uses: actions/upload-artifact@v3 + with: + name: ${{ steps.rename-files.outputs.FUSE_DISTR_BASE }} + if-no-files-found: error + path: | + ${{ steps.rename-files.outputs.FUSE_DISTR_ZIP }} + ${{ steps.rename-files.outputs.FUSE_DISTR_SHA1 }} + + - name: (12) Finish run: | echo "🍏 Finishing with status ${{ job.status }}." diff --git a/.github/workflows/deploy_build_sub.yml b/.github/workflows/deploy_build_sub.yml new file mode 100644 index 00000000..e94ade4e --- /dev/null +++ b/.github/workflows/deploy_build_sub.yml @@ -0,0 +1,119 @@ +# Reusable workflow for deploying build file(s) via FTP +name: Upload to FTP +run-name: Upload build file(s) to FTP / ${{ github.actor }} / + +on: + workflow_call: + inputs: + # Name this setup (no spaces please) + artefact: + type: string + required: true + deploy_zip: + type: boolean + required: true + deploy_sha1: + type: boolean + required: false + default: false + secrets: + DEPLOY_ZIP_PATH: + description: "Relative path that prefixes uploaded ZIP file on FTP server" + required: true + DEPLOY_ZIP_HOST: + description: "Hostname of FTP server where ZIP package will be uploaded" + required: true + DEPLOY_ZIP_USER: + description: "Username that will be used for uploading ZIP file to FTP server" + required: true + DEPLOY_ZIP_PASS: + description: "Password for user that will be used for uploading ZIP package to FTP server" + required: true + +jobs: + upload: + name: Upload to FTP + runs-on: ubuntu-latest + timeout-minutes: 5 + env: + file_path_artefact: ${{ inputs.artefact }} + file_path_zip: ${{ inputs.artefact }}.zip + file_path_sha1: ${{ inputs.artefact }}.zip.sha1 + + deploy_zip_path: ${{ secrets.DEPLOY_ZIP_PATH }} + deploy_zip_host: ${{ secrets.DEPLOY_ZIP_HOST }} + deploy_zip_user: ${{ secrets.DEPLOY_ZIP_USER }} + deploy_zip_pass: ${{ secrets.DEPLOY_ZIP_PASS }} + steps: + - name: (1) Download build artefact + uses: actions/download-artifact@v3 + with: + name: ${{ env.file_path_artefact }} + + - name: (2) Verify FTP/DEPLOY secrets are set + if: ${{ inputs.deploy_zip }} + run: | + error=0 + if [[ -z "${{ env.deploy_zip_path }}" ]]; then + echo "::error::DEPLOY_ZIP_PATH secret missing" + error=1 + fi + + if [[ -z "${{ env.deploy_zip_host }}" ]]; then + echo "::error::DEPLOY_ZIP_HOST secret missing" + error=1 + fi + + if [[ -z "${{ env.deploy_zip_user }}" ]]; then + echo "::error::DEPLOY_ZIP_USER secret missing" + error=1 + fi + + if [[ -z "${{ env.deploy_zip_pass }}" ]]; then + echo "::error::DEPLOY_ZIP_PASS secret missing" + error=1 + fi + + if [[ $error -eq 1 ]]; then + exit 1 + fi + + echo "All FTP/DEPLOY parameters set" + + - name: (3a) Prepare data before deploy (zip) + id: deploy-zip + if: ${{ inputs.deploy_zip }} + run: | + cd ${GITHUB_WORKSPACE} + echo "Content of directory:" + ls -laR + + echo "Deploying file ${{ env.file_path_zip }}" + + src="${GITHUB_WORKSPACE}/${{ env.file_path_zip }}" + dest="${{ env.deploy_zip_path }}/${{ github.ref_name }}/${{ env.file_path_zip }}" + + echo "Source file: $src" + echo "Destination file: $dest" + + echo "src=${src}" >> "$GITHUB_OUTPUT" + echo "dest=${dest}" >> "$GITHUB_OUTPUT" + + - name: (3b) 📂 Send zip file + uses: bayssmekanique/action-simple-file-upload@v1.1.3 + with: + host: "${{ env.deploy_zip_host }}" + user: "${{ env.deploy_zip_user }}" + password: "${{ env.deploy_zip_pass }}" + src: "${{ steps.deploy-zip.outputs.src }}" + dest: "${{ steps.deploy-zip.outputs.dest }}" + + - name: (3) Deploy SHA1 file (different location) + if: ${{ inputs.deploy_sha1 }} + run: | + echo "Deploying file ${{ env.file_path_sha1 }}" + echo "Not implemented yet" + + - name: (4) Finish + run: | + echo "🍏 Finishing with status ${{ job.status }}." diff --git a/.github/workflows/nightly_build.yml b/.github/workflows/nightly_build.yml new file mode 100755 index 00000000..af63e72e --- /dev/null +++ b/.github/workflows/nightly_build.yml @@ -0,0 +1,42 @@ +name: Nightly build +run-name: Automated nightly build and pre-release + +# Executed every night (1 AM) + button +on: + schedule: + - cron: '0 1 * * *' + workflow_dispatch: + +jobs: + # Merge master from defined repo (usually official fuse repo) + catchup: + name: "Merge foreign master" + runs-on: ubuntu-latest + if: ${{ vars.PARENT_FUSE_BRANCH }} && ${{ vars.PARENT_FUSE_REPO }} + permissions: + contents: write + steps: + - name: "Checkout code" + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: "Merge fresh ${{ vars.PARENT_FUSE_BRANCH }} from ${{ vars.PARENT_FUSE_REPO }}" + run: | + git fetch --prune + git remote add repo ${{ vars.PARENT_FUSE_REPO }} + git fetch repo + git merge repo/${{ vars.PARENT_FUSE_BRANCH }} + git push + + # Build and release nightly prerelease version from master (no draft) + master: + needs: [catchup] + name: "Nightly build from master" + uses: ./.github/workflows/test_release.yml + with: + reason: "Nightly master build" + draft: false + generateReleaseNotes: true + libspectrum_branch: "master" + secrets: + RELEASE_TOKEN: "${{ secrets.RELEASE_TOKEN }}" diff --git a/.github/workflows/test_release.yml b/.github/workflows/test_release.yml new file mode 100644 index 00000000..fbcd136f --- /dev/null +++ b/.github/workflows/test_release.yml @@ -0,0 +1,145 @@ +name: Test version of Fuse App +run-name: Build & Deploy Test version of Fuse App / ${{ github.actor }} / + +on: + # Executed upon manual request + workflow_dispatch: + inputs: + reason: + type: string + required: true + default: "Test some feature" + description: "Describe reason or content of new test release" + draft: + type: boolean + required: true + default: true + description: "If checked, will be marked as draft, needs to be manually released in UI." + generateReleaseNotes: + type: boolean + required: false + default: false + description: "Indicates if release notes should be automatically generated" + libspectrum_branch: + type: string + required: true + default: "master" + description: "Libspectrum's branch to use" + + # Reused also from nightly build workflow + workflow_call: + inputs: + reason: + type: string + required: true + default: "Test some feature" + description: "Describe reason or content of new test release" + draft: + type: boolean + required: true + description: "If checked, will be marked as draft, needs to be manually released in UI." + generateReleaseNotes: + type: boolean + required: false + default: false + description: "Indicates if release notes should be automatically generated" + libspectrum_branch: + type: string + required: false + default: "master" + description: "Libspectrum's branch to use" + secrets: + RELEASE_TOKEN: + required: true + +jobs: + + ######################################## + ### Make dependecies (Libspectrum) ### + ######################################## + + libspectrum-windows: + # Reuse libspectrum's build wokflow and artefact (all libs enabled, fake glib) + name: "Libspectrum lib" + uses: arki55/fuse-libspectrum/.github/workflows/build_windows_sub.yml@master + with: + branch: ${{ inputs.libspectrum_branch }} + key: fuse-app + # repo name is taken from var.LIBSPECTRUM_REPO + + ######################################## + ### Make Testing builds for Windows ### + ######################################## + + # Win32 UI + build-win32-ui-default: + name: "Fuse Win32 UI" + needs: [libspectrum-windows] + uses: ./.github/workflows/test_release_windows_sub.yml + with: + reason: ${{ inputs.reason }} + key: "win32-ui-default" + dependencies: "" + configure_params: "--with-win32" + verify_ui: "win32" + verify_audio: "directsound" + + # SDL1 UI+sound + build-sdl-ui-sdl-sound: + name: "Fuse SDL1 (UI + sound)" + needs: [libspectrum-windows] + uses: ./.github/workflows/test_release_windows_sub.yml + with: + reason: ${{ inputs.reason }} + key: "sdl1-ui-sdl1-sound" + dependencies: "mingw64-i686-SDL" + configure_params: "--without-win32 --with-sdl --disable-sdl2 --with-audio-driver=sdl" + verify_ui: "sdl" + verify_audio: "sdl" + verify_other: "Using SDL 2: no" + + ######################################## + ### Create release, attach ZIP files ### + ######################################## + + release: + name: "Create Testing release" + needs: + - build-win32-ui-default + - build-sdl-ui-sdl-sound + runs-on: ubuntu-latest + steps: + # Prepare friendly tag name ( slashes => _ ) + - name: (1) Prepare variables + id: prep + run: | + ref_name="${{ github.ref_name }}" + use_tag="test_${ref_name//\//_}" + echo "Tag name: ${use_tag}" + echo "use_tag=${use_tag}" >> "$GITHUB_OUTPUT" + + - name: (2) Download all generated files + uses: actions/download-artifact@v3 + + - name: (3) Created release with zip files + uses: ncipollo/release-action@v1 + with: + name: "Test build for ${{ github.ref_name }}" + # Attach all generated build zips + artifacts: "*/*.zip" + # determines structure of files in Source Forge + tag: "${{ steps.prep.outputs.use_tag }}" + # Is not an official release + prerelease: true + # Needs to be published manually? + draft: ${{ inputs.draft }} + # linked to a branch/pull request + commit: ${{ github.ref_name }} + # Special permissions needed + token: "${{ secrets.RELEASE_TOKEN }}" + # Allow updating releases + allowUpdates: true + # Generate release note? + generateReleaseNotes: ${{ inputs.generateReleaseNotes }} + # Any error should fail the build + artifactErrorsFailBuild: true diff --git a/.github/workflows/test_release_windows_sub.yml b/.github/workflows/test_release_windows_sub.yml new file mode 100644 index 00000000..3f2c0637 --- /dev/null +++ b/.github/workflows/test_release_windows_sub.yml @@ -0,0 +1,45 @@ +# Reusable workflow for creating test release (Windows builds) +name: Test version of Fuse App (Windows) +run-name: Build & Deploy Test version of Fuse App For Windows / ${{ github.actor }} / + +on: + workflow_call: + inputs: + # Description of this test build + reason: + type: string + required: true + # Build parameters (forwarded) + key: + type: string + required: true + dependencies: + type: string + required: false + configure_params: + type: string + required: true + verify_ui: + type: string + required: true + verify_audio: + type: string + required: true + verify_other: + type: string + required: false + +jobs: + + # Build Fuse App + build: + name: "Build Fuse" + uses: ./.github/workflows/build_windows_sub.yml + with: + key: "${{ inputs.key }}" + dependencies: "${{ inputs.dependencies }}" + configure_params: "${{ inputs.configure_params }} --with-test-build='Reason: ${{ inputs.reason }}\\nTriggered by: ${{ github.actor }}\\nBranch: ${{ github.ref_name }}\\nDate: #NOW#'" + fuse_version: "TEST-BUILD" + verify_ui: "${{ inputs.verify_ui }}" + verify_audio: "${{ inputs.verify_audio }}" + upload_artifacts: true diff --git a/configure.ac b/configure.ac index 84f53989..317a2e0f 100644 --- a/configure.ac +++ b/configure.ac @@ -30,7 +30,7 @@ m4_define([fuse_full_version], [fuse_major_version.fuse_minor_version.fuse_micro m4_define([fuse_rc_version], [fuse_major_version,fuse_minor_version,fuse_micro_version,fuse_nano_version]) dnl Package info -m4_define([fuse_copyright], ["(c) 1999-2021 Philip Kendall and others"]) +m4_define([fuse_copyright], ["(c) 1999-2023 Philip Kendall and others"]) m4_define([fuse_url], [http://fuse-emulator.sourceforge.net/]) m4_define([fuse_bugreport], [http://sourceforge.net/p/fuse-emulator/bugs/]) @@ -57,6 +57,23 @@ AC_DEFINE([FUSE_RC_VERSION], [fuse_rc_version], [Define version information for win32 executables]) AC_DEFINE([FUSE_COPYRIGHT], [fuse_copyright], [Define copyright of Fuse]) +dnl Configure option to specify testing build info +AC_MSG_CHECKING(testing build information) +AC_ARG_WITH(test-build, +[ --with-test-build=INFO specify testing build information], + , + unset withval +) +if test "$withval" = ""; then + echo 'not a testing build' +else + withval=${withval//#NOW#/`date -u`} + echo "$withval" + AC_DEFINE_UNQUOTED([FUSE_TEST_LINE], ["This is a special build for testing purposes:"], [Testing warning line]) + AC_DEFINE_UNQUOTED([FUSE_TEST_BUILD], ["$withval"], [Testing build information]) + test_build="$withval" +fi + dnl Checks for programs. AC_PROG_CC AM_PROG_CC_C_O @@ -1074,6 +1091,17 @@ echo "Spectranet support: ${build_spectranet}" echo "SpeccyBoot support: ${linux_tap:-no}" echo "TTX2000 S support: ${build_ttx2000s}" echo "Desktop integration: ${desktopintegration}" + +if test "${test_build}" != ""; then + echo "" + echo "*********************" + echo "*** Testing build ***" + echo "*********************" + echo "This build will display the following information" + echo " to distinguish it from official version:" + echo -e $test_build +fi + echo "" echo "Type 'make' to compile Fuse" echo "" diff --git a/fuse.c b/fuse.c index 9f67a7db..f1d181ec 100644 --- a/fuse.c +++ b/fuse.c @@ -162,6 +162,7 @@ static void creator_register_startup( void ); static void fuse_show_copyright(void); static void fuse_show_version( void ); +static void fuse_show_test_build_info( void ); static void fuse_show_help( void ); static int setup_start_files( start_files_t *start_files ); @@ -410,6 +411,14 @@ static int fuse_init(int argc, char **argv) fuse_emulation_paused = 0; movie_init(); +#ifdef FUSE_TEST_BUILD + /* Show warning in case of test build */ + ui_error( UI_ERROR_WARNING, + FUSE_TEST_LINE "\n" + FUSE_TEST_BUILD + ); +#endif + return 0; } @@ -501,6 +510,20 @@ static void fuse_show_copyright(void) static void fuse_show_version( void ) { printf( "The Free Unix Spectrum Emulator (Fuse) version " VERSION ".\n" ); + + fuse_show_test_build_info(); +} + +static void fuse_show_test_build_info( void ) +{ +#ifdef FUSE_TEST_BUILD + printf( + "\n" + FUSE_TEST_LINE "\n" + FUSE_TEST_BUILD "\n" + "\n" + ); +#endif } static void fuse_show_help( void ) diff --git a/ui/widget/error.c b/ui/widget/error.c index 23847b20..e8c610d1 100644 --- a/ui/widget/error.c +++ b/ui/widget/error.c @@ -94,6 +94,7 @@ split_message( const char *message, char ***lines, size_t *count, { const char *ptr = message; int position; + int next_line = 0; line_length *= 8; @@ -103,8 +104,14 @@ split_message( const char *message, char ***lines, size_t *count, while( *ptr ) { + /* Detect new lines */ + while( *ptr && ( *ptr ) == '\n' ) { + ptr++; + next_line=1; + } /* Skip any whitespace */ while( *ptr && isspace( *ptr ) ) ptr++; + /* End of message? */ if( *ptr == '\0' ) break; message = ptr; @@ -118,10 +125,11 @@ split_message( const char *message, char ***lines, size_t *count, message++; /* Check we've got room for the word, plus some prefixing space */ - if( position + widget_substringwidth( message, ptr - message ) + 4 - >= line_length ) { + if( (position + widget_substringwidth( message, ptr - message ) + 4 + >= line_length) || (next_line==1) ) { char **new_lines; size_t i; + next_line=0; /* If we've filled the screen, stop */ if( *count == 18 ) return 0; |
From: <sba...@us...> - 2023-08-21 17:12:52
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a change to branch master in repository fuse. from 81efcbce Reset machine when enabling/disabling a sound peripheral new 165e303c CI: TEST-BUILD and Nightly Build GitHub workflows new 06039b51 ci: Remove unused workflow file new 4b1a7e6f ci: Daily test (pre)release as new release with date+time, dropping older releases (#42) new 7718c3a4 Merge request #25: GitHub test and nightly builds The 4 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "add" were already present in the repository and have only been added to this reference. Summary of changes: .github/workflows/build_linux.yml | 2 +- .github/workflows/build_macos.yml | 2 +- .github/workflows/build_wii.yml | 2 +- .github/workflows/build_wii_sub.yml | 1 - .github/workflows/build_windows.yml | 7 +- .github/workflows/build_windows_sub.yml | 171 +++++++++++++++-- .github/workflows/nightly_build.yml | 45 +++++ .github/workflows/test_release.yml | 249 +++++++++++++++++++++++++ .github/workflows/test_release_windows_sub.yml | 45 +++++ configure.ac | 30 ++- fuse.c | 23 +++ ui/widget/error.c | 12 +- 12 files changed, 570 insertions(+), 19 deletions(-) create mode 100755 .github/workflows/nightly_build.yml create mode 100644 .github/workflows/test_release.yml create mode 100644 .github/workflows/test_release_windows_sub.yml |
From: <sba...@us...> - 2023-08-05 22:39:16
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch patches-142-currah-uspeech in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/2324c3dd2a251fd6d07cf5cae226e4840357d67d/ The following commit(s) were added to refs/heads/patches-142-currah-uspeech by this push: new 2324c3dd Add memory address mirroring and more I/O ports to uSpeech 2324c3dd is described below commit 2324c3dd2a251fd6d07cf5cae226e4840357d67d Author: Sergio Baldoví <ser...@gm...> AuthorDate: Sun Aug 6 00:34:22 2023 +0200 Add memory address mirroring and more I/O ports to uSpeech According to Thomas Busse tests, some memory addresses are mirrored when reading (0x1000) or writing to (0x1000, 0x3000 and 0x3001). Also adds input port on 0x1000 and output ports on 0x1000, 0x3000 and 0x3001, as /MREQ is not decoded. --- memory_pages.c | 28 +++++++++++++++------ peripherals/sound/uspeech.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 7 deletions(-) diff --git a/memory_pages.c b/memory_pages.c index e1e638aa..5c3f07ab 100644 --- a/memory_pages.c +++ b/memory_pages.c @@ -409,7 +409,7 @@ readbyte( libspectrum_word address ) if( uspeech_available ) { if( address == 0x0038 ) uspeech_toggle(); /* and return whatever is the "normal" value later */ - else if( uspeech_active && ( address == 0x1000 ) ) + else if( uspeech_active && ( address & 0xf000 ) == 0x1000 ) return uspeech_busy(); } } @@ -515,9 +515,12 @@ writebyte_internal( libspectrum_word address, libspectrum_byte b ) if( opus_active && address >= 0x2800 && address < 0x3800 ) { opus_write( address, b ); - } else if( mapping->writable || - (mapping->source != memory_source_none && - settings_current.writable_roms) ) { + return; + } + + if( mapping->writable || + ( mapping->source != memory_source_none && + settings_current.writable_roms ) ) { libspectrum_word offset = address & MEMORY_PAGE_SIZE_MASK; libspectrum_byte *memory = mapping->page; @@ -525,11 +528,22 @@ writebyte_internal( libspectrum_word address, libspectrum_byte b ) memory[ offset ] = b; } else if( uspeech_available ) { + /* TODO: check if we can move this check above memory writes. + uSpeech is not compatible with +2A/+3 all RAM modes */ + if( uspeech_active ) { + if( ( address & 0xf000 ) == 0x1000 ) { + uspeech_write( address & 0xf000, b ); + return; + } + + if( ( address & 0xf000 ) == 0x3000 ) { + uspeech_write( address & 0xf001, b ); + return; + } + } + if( address == 0x0038 ) uspeech_toggle(); - else if( uspeech_active && ( address == 0x1000 || ( address & 0xfffe ) == 0x3000 ) ) { - uspeech_write( address, b ); - } } } diff --git a/peripherals/sound/uspeech.c b/peripherals/sound/uspeech.c index bab48b72..5ba725d5 100644 --- a/peripherals/sound/uspeech.c +++ b/peripherals/sound/uspeech.c @@ -59,6 +59,14 @@ static void uspeech_toggle_write( libspectrum_word port, libspectrum_byte val ); static libspectrum_byte uspeech_toggle_read( libspectrum_word port, libspectrum_byte *attached ); +static libspectrum_byte uspeech_port_play_read( libspectrum_word port, + libspectrum_byte *attached ); +static void uspeech_port_play_write( libspectrum_word port, + libspectrum_byte data ); +static void uspeech_port_intonation_normal( libspectrum_word port, + libspectrum_byte data ); +static void uspeech_port_intonation_high( libspectrum_word port, + libspectrum_byte data ); static void uspeech_reset( int hard_reset ); static void uspeech_memory_map( void ); @@ -81,6 +89,9 @@ static const periph_port_t uspeech_ports[] = { /* Really?! This conflicts with the ULA! */ /* ---- ---- 0111 1000 */ { 0xffff, 0x0038, uspeech_toggle_read, uspeech_toggle_write }, + { 0xffff, 0x1000, uspeech_port_play_read, uspeech_port_play_write }, + { 0xffff, 0x3000, NULL, uspeech_port_intonation_normal }, + { 0xffff, 0x3001, NULL, uspeech_port_intonation_high }, { 0, 0, NULL, NULL } }; @@ -92,6 +103,44 @@ static const periph_t uspeech_periph = { /* .activate = */ NULL }; +static libspectrum_byte +uspeech_port_play_read( libspectrum_word port, libspectrum_byte *attached ) +{ + if( !uspeech_active ) return 0xff; + + /* TODO: check if this value should be set to 0xff */ + *attached = 0xff; + + return sp0256_busy(); +} + +static void +uspeech_port_play_write( libspectrum_word port, libspectrum_byte data ) +{ + if( !uspeech_active ) return; + + /* Address 0x1000 can also be accessed via I/O (read and write) */ + sp0256_play( data & 0x3f ); +} + +static void +uspeech_port_intonation_normal( libspectrum_word port, libspectrum_byte data ) +{ + if( !uspeech_active ) return; + + /* Address 0x3000 can also be accessed via I/O (only write) */ + sp0256_set_intonation( 0 ); +} + +static void +uspeech_port_intonation_high( libspectrum_word port, libspectrum_byte data ) +{ + if( !uspeech_active ) return; + + /* Address 0x3001 can also be accessed via I/O (only write) */ + sp0256_set_intonation( 1 ); +} + static void ensure_empty_mapping( void ) { @@ -286,12 +335,15 @@ uspeech_write( libspectrum_word address, libspectrum_byte b ) { switch( address ) { case 0x1000: + /* This address is mirrored at 0011XXXX XXXXXXXX */ sp0256_play( b & 0x3f ); break; case 0x3000: + /* This address is mirrored at 0011XXXX XXXXXXX0 */ sp0256_set_intonation( 0 ); break; case 0x3001: + /* This address is mirrored at 0011XXXX XXXXXXX1 */ sp0256_set_intonation( 1 ); break; } @@ -300,6 +352,13 @@ uspeech_write( libspectrum_word address, libspectrum_byte b ) libspectrum_byte uspeech_busy( void ) { + /* Thomas Busse tests claims: + - The bits are not floating, there seems to be some deterministic behaviour. + - Bits 0, 1 and 5 contain different values. + - Bits 2, 3 and 4 might be equal and bit 6 and 7 might be equal. + We only return/known bit 0 (busy), though. + */ + return sp0256_busy(); } |
From: <sba...@us...> - 2023-07-21 19:33:41
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch patches-142-currah-uspeech in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/47275accb9d2e729b86c50bbce6d52c477942c27/ The following commit(s) were added to refs/heads/patches-142-currah-uspeech by this push: new 47275acc Do ZX Spectrum ROM inaccessible while uSpeech is paged 47275acc is described below commit 47275accb9d2e729b86c50bbce6d52c477942c27 Author: Sergio Baldoví <ser...@gm...> AuthorDate: Fri Jul 21 21:32:59 2023 +0200 Do ZX Spectrum ROM inaccessible while uSpeech is paged and add missing unit test. --- peripherals/sound/uspeech.c | 57 ++++++++++++++++++++++++++++----------------- peripherals/sound/uspeech.h | 4 ++-- unittests/unittests.c | 2 ++ 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/peripherals/sound/uspeech.c b/peripherals/sound/uspeech.c index 86a2d3f4..bab48b72 100644 --- a/peripherals/sound/uspeech.c +++ b/peripherals/sound/uspeech.c @@ -1,8 +1,6 @@ /* uspeech.c: Routines for handling the Currah uSpeech interface Copyright (c) 2007-2011 Stuart Brady - $Id$ - 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 2 of the License, or @@ -47,6 +45,9 @@ /* A 2 KiB memory chunk accessible by the Z80 when /ROMCS is low * (mirrored when active) */ static memory_page uspeech_memory_map_romcs[ MEMORY_PAGES_IN_2K ]; +static memory_page uspeech_empty_mapping[ MEMORY_PAGES_IN_12K ]; +static int empty_mapping_allocated = 0; + static int uspeech_memory_source; static uint8_t *sp0256rom = NULL; @@ -91,17 +92,41 @@ static const periph_t uspeech_periph = { /* .activate = */ NULL }; +static void +ensure_empty_mapping( void ) +{ + int i; + libspectrum_byte *empty_chunk; + + if( empty_mapping_allocated ) return; + + empty_chunk = memory_pool_allocate_persistent( 0x3000, 1 ); + memset( empty_chunk, 0xff, 0x3000 ); + + for( i = 0; i < MEMORY_PAGES_IN_12K; i++ ) { + memory_page *page = &uspeech_empty_mapping[i]; + page->page = empty_chunk + i * MEMORY_PAGE_SIZE; + page->offset = i * MEMORY_PAGE_SIZE; + page->writable = 0; + page->contended = 0; + page->source = memory_source_none; + } + + empty_mapping_allocated = 1; +} + static int uspeech_init( void *context ) { - int uspeech_source; int i; module_register( &uspeech_module_info ); - uspeech_source = memory_source_register( "uSpeech" ); + uspeech_memory_source = memory_source_register( "uSpeech" ); for( i = 0; i < MEMORY_PAGES_IN_2K; i++ ) - uspeech_memory_map_romcs[ i ].source = uspeech_source; + uspeech_memory_map_romcs[ i ].source = uspeech_memory_source; + + ensure_empty_mapping(); periph_register( PERIPH_TYPE_USPEECH, &uspeech_periph ); @@ -229,18 +254,12 @@ uspeech_memory_map( void ) if( !uspeech_active ) return; /* https://maziac.github.io/currah_uspeech_tests/ - says only the lower 4k should be mapped - "mem holes test" yields strange results, though */ + says only the lower 4k should be mapped. 0x1000-0x3fff do not contain + ZX Spectrum ROM when read */ memory_map_romcs_2k( 0x0000, uspeech_memory_map_romcs ); memory_map_romcs_2k( 0x0800, uspeech_memory_map_romcs ); - /* - memory_map_romcs_2k( 0x1000, uspeech_memory_map_romcs ); - memory_map_romcs_2k( 0x1800, uspeech_memory_map_romcs ); - memory_map_romcs_2k( 0x2000, uspeech_memory_map_romcs ); - memory_map_romcs_2k( 0x2800, uspeech_memory_map_romcs ); - memory_map_romcs_2k( 0x3000, uspeech_memory_map_romcs ); - memory_map_romcs_2k( 0x3800, uspeech_memory_map_romcs ); - */ + memory_map_romcs_4k( 0x1000, uspeech_empty_mapping ); + memory_map_romcs_8k( 0x2000, uspeech_empty_mapping + MEMORY_PAGES_IN_4K ); } static libspectrum_byte @@ -294,12 +313,8 @@ uspeech_unittest( void ) r += unittests_assert_2k_page( 0x0000, uspeech_memory_source, 0 ); r += unittests_assert_2k_page( 0x0800, uspeech_memory_source, 0 ); - r += unittests_assert_2k_page( 0x1000, uspeech_memory_source, 0 ); - r += unittests_assert_2k_page( 0x1800, uspeech_memory_source, 0 ); - r += unittests_assert_2k_page( 0x2000, uspeech_memory_source, 0 ); - r += unittests_assert_2k_page( 0x2800, uspeech_memory_source, 0 ); - r += unittests_assert_2k_page( 0x3000, uspeech_memory_source, 0 ); - r += unittests_assert_2k_page( 0x3800, uspeech_memory_source, 0 ); + r += unittests_assert_4k_page( 0x1000, memory_source_none, 0 ); + r += unittests_assert_8k_page( 0x2000, memory_source_none, 0 ); r += unittests_assert_16k_ram_page( 0x4000, 5 ); r += unittests_assert_16k_ram_page( 0x8000, 2 ); r += unittests_assert_16k_ram_page( 0xc000, 0 ); diff --git a/peripherals/sound/uspeech.h b/peripherals/sound/uspeech.h index d1eff7db..e2750c70 100644 --- a/peripherals/sound/uspeech.h +++ b/peripherals/sound/uspeech.h @@ -1,8 +1,6 @@ /* uspeech.h: Routines for handling the Currah uSpeech interface Copyright (c) 2007 Stuart Brady - $Id$ - 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 2 of the License, or @@ -43,4 +41,6 @@ libspectrum_byte uspeech_busy( void ); void uspeech_write( libspectrum_word address, libspectrum_byte b ); +int uspeech_unittest( void ); + #endif /* #ifndef FUSE_USPEECH_H */ diff --git a/unittests/unittests.c b/unittests/unittests.c index a42c13ac..dfccdd70 100644 --- a/unittests/unittests.c +++ b/unittests/unittests.c @@ -43,6 +43,7 @@ #include "peripherals/if1.h" #include "peripherals/if2.h" #include "peripherals/multiface.h" +#include "peripherals/sound/uspeech.h" #include "peripherals/speccyboot.h" #include "peripherals/ttx2000s.h" #include "peripherals/ula.h" @@ -761,6 +762,7 @@ paging_test( void ) r += speccyboot_unittest(); r += ttx2000s_unittest(); r += usource_unittest(); + r += uspeech_unittest(); r += beta_unittest(); r += didaktik80_unittest(); |
From: <sba...@us...> - 2023-07-21 04:58:55
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch patches-142-currah-uspeech in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/4ac12898e70327a236c00a8f4c61894dc4ffca4e/ The following commit(s) were added to refs/heads/patches-142-currah-uspeech by this push: new 4ac12898 Fix ROM entries order in menu.c 4ac12898 is described below commit 4ac12898e70327a236c00a8f4c61894dc4ffca4e Author: Vic Chwe <ch...@us...> AuthorDate: Fri Jul 21 06:18:47 2023 +0200 Fix ROM entries order in menu.c --- menu.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/menu.c b/menu.c index 99835be7..b42e3adb 100644 --- a/menu.c +++ b/menu.c @@ -291,11 +291,11 @@ MENU_CALLBACK_WITH_ACTION( menu_options_selectroms_peripheral_select ) case 7: menu_select_peripheral_roms( "Multiface 128", 6, 1 ); return; case 8: menu_select_peripheral_roms( "Multiface 3", 7, 1 ); return; case 9: menu_select_peripheral_roms( "Opus Discovery", 8, 1 ); return; - case 14: menu_select_peripheral_roms( "SP0256", 9, 1 ); return; - case 10: menu_select_peripheral_roms( "SpeccyBoot", 10, 1 ); return; - case 11: menu_select_peripheral_roms( "TTX2000S", 11, 1 ); return; - case 12: menu_select_peripheral_roms( "uSource", 12, 1 ); return; - case 13: menu_select_peripheral_roms( "uSpeech", 13, 1 ); return; + case 10: menu_select_peripheral_roms( "SP0256", 9, 1 ); return; + case 11: menu_select_peripheral_roms( "SpeccyBoot", 10, 1 ); return; + case 12: menu_select_peripheral_roms( "TTX2000S", 11, 1 ); return; + case 13: menu_select_peripheral_roms( "uSource", 12, 1 ); return; + case 14: menu_select_peripheral_roms( "uSpeech", 13, 1 ); return; } |
From: <sba...@us...> - 2023-07-19 17:46:30
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch patches-142-currah-uspeech in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/b5830f37fef7a8e0a91ddf5235966dc3a9e1d772/ commit b5830f37fef7a8e0a91ddf5235966dc3a9e1d772 Author: Sergio Baldoví <ser...@gm...> AuthorDate: Wed Jul 19 19:40:12 2023 +0200 Document SP0256 ROM option and uSpeech memory source --- man/fuse.1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/man/fuse.1 b/man/fuse.1 index 2d627f84..af4a14e7 100644 --- a/man/fuse.1 +++ b/man/fuse.1 @@ -1268,6 +1268,9 @@ are not. .B \-\-rom\-opus .I file .br +.B \-\-rom\-sp0256 +.I file +.br .B \-\-rom\-speccyboot .I file .br @@ -1302,6 +1305,8 @@ the Opus Discovery ROM .RI ( opus.rom ), the SpeccyBoot ROM .RI ( speccyboot\-1.4.rom ), +the SP0256 ROM +.RI ( sp0256-al2.rom ), the TTX2000S ROM .RI ( ttx2000s.rom ), and the \(mcSource ROM @@ -5141,6 +5146,7 @@ Other available sources are: .RI ` "Timex Dock" "'," .RI ` "Timex EXROM" "'," .RI ` uSource "'," +.RI ` uSpeech "'," .RI ` ZXATASP ' and .RI ` ZXCF "'." |
From: <sba...@us...> - 2023-07-19 17:46:28
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch patches-142-currah-uspeech in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/a263ed4ddfc115476d21c25195c50eabd88f77cc/ commit a263ed4ddfc115476d21c25195c50eabd88f77cc Author: Vic Chwe <ch...@us...> AuthorDate: Wed Jul 19 19:06:27 2023 +0200 Enable snapshot support for Currah uSpeech --- peripherals/sound/uspeech.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/peripherals/sound/uspeech.c b/peripherals/sound/uspeech.c index 9f334487..86a2d3f4 100644 --- a/peripherals/sound/uspeech.c +++ b/peripherals/sound/uspeech.c @@ -62,13 +62,17 @@ static libspectrum_byte uspeech_toggle_read( libspectrum_word port, static void uspeech_reset( int hard_reset ); static void uspeech_memory_map( void ); +static void uspeech_enabled_snapshot( libspectrum_snap *snap ); +static void uspeech_from_snapshot( libspectrum_snap *snap ); +static void uspeech_to_snapshot( libspectrum_snap *snap ); + static module_info_t uspeech_module_info = { uspeech_reset, uspeech_memory_map, - NULL, /* enabled_snapshot */ - NULL, /* from_snapshot */ - NULL, /* to_snapshot */ + uspeech_enabled_snapshot, + uspeech_from_snapshot, + uspeech_to_snapshot, }; @@ -307,3 +311,29 @@ uspeech_unittest( void ) return r; } + +static void +uspeech_enabled_snapshot( libspectrum_snap *snap ) +{ + settings_current.uspeech = libspectrum_snap_uspeech_active( snap ); +} + +static void +uspeech_from_snapshot( libspectrum_snap *snap ) +{ + if( !libspectrum_snap_uspeech_active( snap ) ) return; + + if( libspectrum_snap_uspeech_paged( snap ) ) { + uspeech_active = 0; /* Will be toggled to active next */ + uspeech_toggle(); + } +} + +static void +uspeech_to_snapshot( libspectrum_snap *snap ) +{ + if( !periph_is_active( PERIPH_TYPE_USPEECH ) ) return; + + libspectrum_snap_set_uspeech_active( snap, 1 ); + libspectrum_snap_set_uspeech_paged ( snap, uspeech_active ); +} |
From: <sba...@us...> - 2023-07-19 17:46:28
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch patches-142-currah-uspeech in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/327688086c344d382dec20c8a96c7da3f9e852ad/ commit 327688086c344d382dec20c8a96c7da3f9e852ad Author: Vic Chwe <ch...@us...> AuthorDate: Wed Jul 19 18:52:13 2023 +0200 Enhanced Currah uSpeech paging logic: - Memory read/write at 0x38 should page the ROM in/out - ROM is mapped to the first 4 Kb only Thanks to Tim Busse tests tape. Now Booty launches the hidden "diving" game. --- memory_pages.c | 12 +++++++++--- peripherals/sound/uspeech.c | 5 +++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/memory_pages.c b/memory_pages.c index c2f51c20..e1e638aa 100644 --- a/memory_pages.c +++ b/memory_pages.c @@ -406,8 +406,12 @@ readbyte( libspectrum_word address ) if( ttx2000s_paged && address >= 0x2000 ) return ttx2000s_sram_read( address ); - if( uspeech_available && address == 0x1000 ) - return uspeech_busy(); + if( uspeech_available ) { + if( address == 0x0038 ) + uspeech_toggle(); /* and return whatever is the "normal" value later */ + else if( uspeech_active && ( address == 0x1000 ) ) + return uspeech_busy(); + } } return mapping->page[ address & MEMORY_PAGE_SIZE_MASK ]; @@ -521,7 +525,9 @@ writebyte_internal( libspectrum_word address, libspectrum_byte b ) memory[ offset ] = b; } else if( uspeech_available ) { - if( address == 0x1000 || ( address & 0xfffe ) == 0x3000 ) { + if( address == 0x0038 ) + uspeech_toggle(); + else if( uspeech_active && ( address == 0x1000 || ( address & 0xfffe ) == 0x3000 ) ) { uspeech_write( address, b ); } } diff --git a/peripherals/sound/uspeech.c b/peripherals/sound/uspeech.c index f10b26f1..9f334487 100644 --- a/peripherals/sound/uspeech.c +++ b/peripherals/sound/uspeech.c @@ -224,14 +224,19 @@ uspeech_memory_map( void ) { if( !uspeech_active ) return; + /* https://maziac.github.io/currah_uspeech_tests/ + says only the lower 4k should be mapped + "mem holes test" yields strange results, though */ memory_map_romcs_2k( 0x0000, uspeech_memory_map_romcs ); memory_map_romcs_2k( 0x0800, uspeech_memory_map_romcs ); + /* memory_map_romcs_2k( 0x1000, uspeech_memory_map_romcs ); memory_map_romcs_2k( 0x1800, uspeech_memory_map_romcs ); memory_map_romcs_2k( 0x2000, uspeech_memory_map_romcs ); memory_map_romcs_2k( 0x2800, uspeech_memory_map_romcs ); memory_map_romcs_2k( 0x3000, uspeech_memory_map_romcs ); memory_map_romcs_2k( 0x3800, uspeech_memory_map_romcs ); + */ } static libspectrum_byte |
From: <sba...@us...> - 2023-07-19 17:46:25
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch patches-142-currah-uspeech in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/8fd745102caa85f49b9f2bcb7135bf4d3d751b97/ commit 8fd745102caa85f49b9f2bcb7135bf4d3d751b97 Author: Vic Chwe <ch...@us...> AuthorDate: Wed Jul 19 18:47:01 2023 +0200 Add UI elements to manage SP0256 ROM file location SP0256 ROM initialisation moved to the uspeech.c and produces meaningful error messages if something goes wrong. --- menu.c | 9 ++-- menu_data.dat | 9 ++-- peripherals/sound/sp0256.c | 105 ++++++++++++++++---------------------------- peripherals/sound/sp0256.h | 5 ++- peripherals/sound/uspeech.c | 76 ++++++++++++++++++++++++++++++-- settings.dat | 1 + settings.pl | 9 ++-- ui/options.dat | 1 + 8 files changed, 129 insertions(+), 86 deletions(-) diff --git a/menu.c b/menu.c index 77608c16..99835be7 100644 --- a/menu.c +++ b/menu.c @@ -291,10 +291,11 @@ MENU_CALLBACK_WITH_ACTION( menu_options_selectroms_peripheral_select ) case 7: menu_select_peripheral_roms( "Multiface 128", 6, 1 ); return; case 8: menu_select_peripheral_roms( "Multiface 3", 7, 1 ); return; case 9: menu_select_peripheral_roms( "Opus Discovery", 8, 1 ); return; - case 10: menu_select_peripheral_roms( "SpeccyBoot", 9, 1 ); return; - case 11: menu_select_peripheral_roms( "TTX2000S", 10, 1 ); return; - case 12: menu_select_peripheral_roms( "uSource", 11, 1 ); return; - case 13: menu_select_peripheral_roms( "uSpeech", 12, 1 ); return; + case 14: menu_select_peripheral_roms( "SP0256", 9, 1 ); return; + case 10: menu_select_peripheral_roms( "SpeccyBoot", 10, 1 ); return; + case 11: menu_select_peripheral_roms( "TTX2000S", 11, 1 ); return; + case 12: menu_select_peripheral_roms( "uSource", 12, 1 ); return; + case 13: menu_select_peripheral_roms( "uSpeech", 13, 1 ); return; } diff --git a/menu_data.dat b/menu_data.dat index 55f2f02c..dc126bd6 100644 --- a/menu_data.dat +++ b/menu_data.dat @@ -123,10 +123,11 @@ Options/Select ROMs/Peripheral ROMs/Mu_ltiface One..., Item,, menu_options_selec Options/Select ROMs/Peripheral ROMs/Multiface _128..., Item,, menu_options_selectroms_peripheral_select,, 7 Options/Select ROMs/Peripheral ROMs/Multiface _3..., Item,, menu_options_selectroms_peripheral_select,, 8 Options/Select ROMs/Peripheral ROMs/_Opus Discovery..., Item,, menu_options_selectroms_peripheral_select,, 9 -Options/Select ROMs/Peripheral ROMs/Specc_yBoot..., Item,, menu_options_selectroms_peripheral_select,, 10 -Options/Select ROMs/Peripheral ROMs/TT_X2000S..., Item,, menu_options_selectroms_peripheral_select,, 11 -Options/Select ROMs/Peripheral ROMs/_uSource..., Item,, menu_options_selectroms_peripheral_select,, 12 -Options/Select ROMs/Peripheral ROMs/_uSpeech..., Item,, menu_options_selectroms_peripheral_select,, 13 +Options/Select ROMs/Peripheral ROMs/_SP0256..., Item,,menu_options_selectroms_peripheral_select,, 10 +Options/Select ROMs/Peripheral ROMs/Specc_yBoot..., Item,, menu_options_selectroms_peripheral_select,, 11 +Options/Select ROMs/Peripheral ROMs/TT_X2000S..., Item,, menu_options_selectroms_peripheral_select,, 12 +Options/Select ROMs/Peripheral ROMs/_uSource..., Item,, menu_options_selectroms_peripheral_select,, 13 +Options/Select ROMs/Peripheral ROMs/uS_peech..., Item,, menu_options_selectroms_peripheral_select,, 14 Options/_Filter..., Item,,, menu_filter_detail diff --git a/peripherals/sound/sp0256.c b/peripherals/sound/sp0256.c index 8ad75edd..6094eb9b 100644 --- a/peripherals/sound/sp0256.c +++ b/peripherals/sound/sp0256.c @@ -70,6 +70,7 @@ #define debug_printf(x) #define jzp_printf(x, ...) +#define DEBUG_USPEECH_ALLOPHONE #define HIGH_QUALITY #define SCBUF_SIZE (4096) /* Must be power of 2 */ #define SCBUF_MASK (SCBUF_SIZE - 1) @@ -142,7 +143,7 @@ static void sp0256_write_ald(sp0256_t *s, uint32_t data); /* ======================================================================== */ /* sp0256_do_init -- Makes a new SP0256. */ /* ======================================================================== */ -static int sp0256_do_init( sp0256_t *s ); +static int sp0256_do_init( sp0256_t *s, uint8_t *sp0256rom ); static int factor = 358; @@ -1115,60 +1116,6 @@ sp0256_micro(sp0256_t *s) } } -/* ======================================================================== */ -/* sp0256_rdrom -- Tries to read a ROM file in the current directory. */ -/* ======================================================================== */ -static int -sp0256_rdrom(sp0256_t *s, int page) -{ - uint8_t *rom; - char buf[32]; - FILE *f; - - /* -------------------------------------------------------------------- */ - /* Generate a file name, and then see if it exists. */ - /* -------------------------------------------------------------------- */ - sprintf(buf, "sp0256_%.1X.bin", page); - - f = fopen(buf, "rb"); - if (!f) return 0; - - printf("SDB: sp0256_rdrom() %.1X\n", page); - - /* -------------------------------------------------------------------- */ - /* Allocate 4K worth of space to the ROM image. */ - /* -------------------------------------------------------------------- */ - rom = calloc(4096, 1); - if (!rom) { - fprintf(stderr, "SP0256: Out of memory in rdrom\n"); - return -1; - } - - /* -------------------------------------------------------------------- */ - /* Read in the ROM image and then bit-reverse it. */ - /* -------------------------------------------------------------------- */ - int l=fread(rom, 1, 4096, f); // FIXME: check length - fclose(f); - - if( l == 2048 ) { - memcpy( rom + 2048, rom, 2048); - } else { - free(rom); - fprintf(stderr, "SP0256 %.1X ROM has %d bytes, expected 2048\n", page, l); - return -1; - } - - /* -------------------------------------------------------------------- */ - /* Set this as our ROM page, and we're all set. */ - /* -------------------------------------------------------------------- */ - s->rom[page] = rom; - - jzp_printf("SP0256: added %s at SP0256 address $%.4X.0\n", buf, page << 12); - - return 0; -} - - /* ======================================================================== */ /* sp0256_run -- Where the magic happens. Generate voice data for */ /* our good friend, the SP0256. */ @@ -1326,10 +1273,8 @@ sp0256_do_reset(sp0256_t *s) /* sp0256_do_init -- Makes a new SP0256. */ /* ======================================================================== */ static int -sp0256_do_init( sp0256_t *s ) +sp0256_do_init( sp0256_t *s, uint8_t *sp0256rom ) { - int i; - /* -------------------------------------------------------------------- */ /* First, lets zero out the structure to be safe. */ /* -------------------------------------------------------------------- */ @@ -1363,15 +1308,17 @@ sp0256_do_init( sp0256_t *s ) /* you're going to have multiple SP0256's in a system, or use ROMs */ /* from various places, but it'll do for the moment. */ /* -------------------------------------------------------------------- */ - for (i = 0; i < 16; i++) - if (sp0256_rdrom(s, i)) - return -1; + + /* Original code was iterating over 16 "pages", but we always provided + ROM for "page" 1 only */ + s->rom[1] = sp0256rom; return 0; } static int current_intonation = 0; +#ifdef DEBUG_USPEECH_ALLOPHONE struct allophone_t { const char *name; int length; @@ -1448,20 +1395,38 @@ static const struct allophone_t al2_allophones[ 64 ] = { { "/BB2/", 50 }, /* (bb) */ }; +#endif /* #ifdef DEBUG_USPEECH_ALLOPHONE */ static sp0256_t sp0256; -void -sp0256_init( void ) +int +sp0256_init( uint8_t *sp0256rom ) { - sp0256_do_init(&sp0256); + return sp0256_do_init(&sp0256, sp0256rom); +} + +int +sp0256_reset( uint8_t *sp0256rom ) +{ + debug_printf("sp0256_reset\n"); + /* Lazy init, if necessary */ + if( !sp0256.scratch ) { + if( sp0256_do_init( &sp0256, sp0256rom ) ) { + return -1; + } + } else { + sp0256_do_reset( &sp0256 ); + } + return 0; } void -sp0256_reset( void ) +sp0256_end() { - printf("sp0256_reset\n"); - sp0256_do_reset(&sp0256); + if( sp0256.scratch ) { + free( sp0256.scratch ); + } + memset( &sp0256, 0, sizeof(sp0256) ); } static void @@ -1485,6 +1450,8 @@ sp0256_run_to(sp0256_t *s, uint64_t t ) void sp0256_do_frame( void ) { + /* No op if it wasn't initialised yet */ + if( !sp0256.scratch ) return; sp0256_run_to( &sp0256, machine_current->timings.tstates_per_frame ); sp0256_tstates -= machine_current->timings.tstates_per_frame; } @@ -1492,6 +1459,7 @@ sp0256_do_frame( void ) void sp0256_play( int a ) { +#ifdef DEBUG_USPEECH_ALLOPHONE if( a >= 5 && a < 64 ) { if( al2_allophones[ a ].name ) { printf( "sp0256: allophone written: 0x%02x, %s\n", a, al2_allophones[ a ].name ); @@ -1500,6 +1468,7 @@ sp0256_play( int a ) } fflush( stdout ); } +#endif /* #ifdef DEBUG_USPEECH_ALLOPHONE */ sp0256_run_to(&sp0256, tstates); sp0256_write_ald(&sp0256, a); @@ -1510,7 +1479,7 @@ sp0256_set_intonation( int intonation ) { if( intonation != current_intonation ) { sp0256_run_to(&sp0256, tstates); - printf("sp0256: intonation %s\n", intonation ? "high" : "normal" ); + debug_printf( ("sp0256: intonation %s\n", intonation ? "high" : "normal") ); current_intonation = intonation; /* 358 - 1/8th = 314 */ factor = intonation ? 314 : 358; diff --git a/peripherals/sound/sp0256.h b/peripherals/sound/sp0256.h index 5564d9c0..4fcac101 100644 --- a/peripherals/sound/sp0256.h +++ b/peripherals/sound/sp0256.h @@ -29,8 +29,9 @@ #ifndef FUSE_SP0256_H #define FUSE_SP0256_H -void sp0256_init( void ); -void sp0256_reset( void ); +int sp0256_init( uint8_t *sp0256rom ); +int sp0256_reset( uint8_t *sp0256rom ); +void sp0256_end( void ); void sp0256_play( int allophone ); void sp0256_set_intonation( int intonation ); diff --git a/peripherals/sound/uspeech.c b/peripherals/sound/uspeech.c index b9e90948..f10b26f1 100644 --- a/peripherals/sound/uspeech.c +++ b/peripherals/sound/uspeech.c @@ -37,14 +37,20 @@ #include "periph.h" #include "settings.h" #include "sp0256.h" +#include "ui/ui.h" #include "unittests/unittests.h" #include "uspeech.h" +#include "utils.h" + +#define SP0256_ROM_SIZE 2048 /* A 2 KiB memory chunk accessible by the Z80 when /ROMCS is low * (mirrored when active) */ static memory_page uspeech_memory_map_romcs[ MEMORY_PAGES_IN_2K ]; static int uspeech_memory_source; +static uint8_t *sp0256rom = NULL; + int uspeech_active = 0; int uspeech_available = 0; @@ -87,8 +93,6 @@ uspeech_init( void *context ) int uspeech_source; int i; - sp0256_init(); - module_register( &uspeech_module_info ); uspeech_source = memory_source_register( "uSpeech" ); @@ -104,6 +108,10 @@ static void uspeech_end( void ) { uspeech_available = 0; + sp0256_end(); + if( sp0256rom ) { + libspectrum_free( sp0256rom ); + } } void @@ -118,6 +126,62 @@ uspeech_register_startup( void ) uspeech_end ); } +static int +uspeech_load_sp0256_rom() +{ + int error; + char *filename; + utils_file rom; + + filename = settings_current.rom_sp0256; + error = utils_read_auxiliary_file( filename, &rom, UTILS_AUXILIARY_ROM ); + if( error ) { + filename = settings_default.rom_sp0256; + error = utils_read_auxiliary_file( filename, &rom, UTILS_AUXILIARY_ROM ); + if( error ) { + ui_error( UI_ERROR_ERROR, "couldn't find ROM '%s'", filename ); + return -1; + } + } + + if( rom.length != SP0256_ROM_SIZE ) { + ui_error( UI_ERROR_ERROR, + "ROM '%s' is %ld bytes long; expected %ld bytes", + filename, (unsigned long)rom.length, + (unsigned long)SP0256_ROM_SIZE ); + utils_close_file( &rom ); + return -1; + } + + sp0256rom = libspectrum_new( uint8_t, SP0256_ROM_SIZE * 2 ); + + if( !sp0256rom ) { + utils_close_file( &rom ); + ui_error( UI_ERROR_ERROR, "SP0256: Out of memory in rdrom" ); + return -1; + } + + memcpy( sp0256rom, rom.buffer, SP0256_ROM_SIZE ); + memcpy( sp0256rom + SP0256_ROM_SIZE, rom.buffer, SP0256_ROM_SIZE ); + + utils_close_file( &rom ); + + return 0; +} + +static int +uspeech_sp0256_reset() +{ + if( !sp0256rom && uspeech_load_sp0256_rom() ) { + return -1; + } + + if( sp0256_reset( sp0256rom ) ) { + return -1; + } + + return 0; +} static void uspeech_reset( int hard_reset GCC_UNUSED ) @@ -125,8 +189,6 @@ uspeech_reset( int hard_reset GCC_UNUSED ) uspeech_active = 0; uspeech_available = 0; - sp0256_reset(); - if( !periph_is_active( PERIPH_TYPE_USPEECH ) ) return; @@ -138,6 +200,12 @@ uspeech_reset( int hard_reset GCC_UNUSED ) return; } + if( uspeech_sp0256_reset()) { + settings_current.uspeech = 0; + periph_activate_type( PERIPH_TYPE_USPEECH, 0 ); + return; + } + machine_current->ram.romcs = 0; uspeech_available = 1; diff --git a/settings.dat b/settings.dat index fcfa0416..d0007066 100644 --- a/settings.dat +++ b/settings.dat @@ -260,6 +260,7 @@ rom_multiface1, string, "mf1.rom", rom_multiface128, string, "mf128.rom", rom_multiface3, string, "mf3.rom", rom_opus, string, "opus.rom", +rom_sp0256, string, "sp0256-al2.rom", rom_speccyboot, string, "speccyboot-1.4.rom", rom_ttx2000s, string, "ttx2000s.rom", rom_usource, string, "usource.rom", diff --git a/settings.pl b/settings.pl index 651b2da4..bac46f00 100644 --- a/settings.pl +++ b/settings.pl @@ -768,10 +768,11 @@ settings_get_rom_setting( settings_info *settings, size_t which, case 6: return &( settings->rom_multiface128 ); case 7: return &( settings->rom_multiface3 ); case 8: return &( settings->rom_opus ); - case 9: return &( settings->rom_speccyboot ); - case 10: return &( settings->rom_ttx2000s ); - case 11: return &( settings->rom_usource ); - case 12: return &( settings->rom_uspeech ); + case 9: return &( settings->rom_sp0256 ); + case 10: return &( settings->rom_speccyboot ); + case 11: return &( settings->rom_ttx2000s ); + case 12: return &( settings->rom_usource ); + case 13: return &( settings->rom_uspeech ); default: return NULL; } } diff --git a/ui/options.dat b/ui/options.dat index 20d807b2..41940414 100644 --- a/ui/options.dat +++ b/ui/options.dat @@ -161,6 +161,7 @@ Entry, A(Y) volume, volume_ay, INPUT_KEY_y, 3, % Entry, B(e)eper volume, volume_beeper, INPUT_KEY_e, 3, % Entry, Spec(D)rum volume, volume_specdrum, INPUT_KEY_d, 3, % Entry, (C)ovox volume, volume_covox, INPUT_KEY_c, 3, % +Entry, (u)Speech volume, volume_uspeech, INPUT_KEY_u, 3, % diskoptions Drives Setup |
From: <sba...@us...> - 2023-07-19 17:46:24
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch patches-142-currah-uspeech in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/e09eeec1094fefe8e6f75ad901e9d4a22aa466e9/ commit e09eeec1094fefe8e6f75ad901e9d4a22aa466e9 Author: Stuart Brady <sd...@zu...> AuthorDate: Tue Jul 11 19:31:02 2023 +0200 Initial support for Currah uSpeech peripheral (patches #142) --- fuse.c | 2 + infrastructure/startup_manager.h | 1 + machines/machines_periph.c | 1 + man/fuse.1 | 27 +- memory_pages.c | 8 + menu.c | 1 + menu_data.dat | 1 + periph.h | 1 + peripherals/Makefile.am | 2 + peripherals/sound/sp0256.c | 1525 ++++++++++++++++++++++++++++++++++++++ peripherals/sound/sp0256.h | 40 + peripherals/sound/uspeech.c | 236 ++++++ peripherals/sound/uspeech.h | 46 ++ settings.dat | 3 + settings.pl | 1 + sound.c | 36 + sound.h | 1 + ui/options.dat | 1 + z80/coretest.c | 9 + z80/z80_checks.h | 1 + z80/z80_ops.c | 9 + 21 files changed, 1951 insertions(+), 1 deletion(-) diff --git a/fuse.c b/fuse.c index 9f67a7db..5ae8c6cd 100644 --- a/fuse.c +++ b/fuse.c @@ -86,6 +86,7 @@ #include "peripherals/multiface.h" #include "peripherals/printer.h" #include "peripherals/scld.h" +#include "peripherals/sound/uspeech.h" #include "peripherals/speccyboot.h" #include "peripherals/spectranet.h" #include "peripherals/ttx2000s.h" @@ -344,6 +345,7 @@ run_startup_manager( int *argc, char ***argv ) timer_register_startup(); ula_register_startup(); usource_register_startup(); + uspeech_register_startup(); z80_register_startup(); zxatasp_register_startup(); zxcf_register_startup(); diff --git a/infrastructure/startup_manager.h b/infrastructure/startup_manager.h index aecd1168..5dda9526 100644 --- a/infrastructure/startup_manager.h +++ b/infrastructure/startup_manager.h @@ -76,6 +76,7 @@ typedef enum startup_manager_module { STARTUP_MANAGER_MODULE_TIMER, STARTUP_MANAGER_MODULE_ULA, STARTUP_MANAGER_MODULE_USOURCE, + STARTUP_MANAGER_MODULE_USPEECH, STARTUP_MANAGER_MODULE_Z80, STARTUP_MANAGER_MODULE_ZXATASP, STARTUP_MANAGER_MODULE_ZXCF, diff --git a/machines/machines_periph.c b/machines/machines_periph.c index d84d1bcd..2533c409 100644 --- a/machines/machines_periph.c +++ b/machines/machines_periph.c @@ -205,6 +205,7 @@ base_peripherals_48_128( void ) periph_set_present( PERIPH_TYPE_PLUSD, PERIPH_PRESENT_OPTIONAL ); periph_set_present( PERIPH_TYPE_SPECDRUM, PERIPH_PRESENT_OPTIONAL ); periph_set_present( PERIPH_TYPE_USOURCE, PERIPH_PRESENT_OPTIONAL ); + periph_set_present( PERIPH_TYPE_USPEECH, PERIPH_PRESENT_OPTIONAL ); } /* The set of peripherals available on the 48K and similar machines */ diff --git a/man/fuse.1 b/man/fuse.1 index 952aaeb2..2d627f84 100644 --- a/man/fuse.1 +++ b/man/fuse.1 @@ -1276,6 +1276,9 @@ are not. .br .B \-\-rom\-usource .I file +.br +.B \-\-rom\-uspeech +.I file .RS Specify the file to be used for ROM(s) used for each peripheral. The options respectively refer to @@ -1302,7 +1305,9 @@ the SpeccyBoot ROM the TTX2000S ROM .RI ( ttx2000s.rom ), and the \(mcSource ROM -.RI ( usource.rom ). +.RI ( usource.rom ), +the \(mcSpeech ROM +.RI ( uspeech.rom ). .PP The names in brackets denote the defaults. Note that not all these ROMs are supplied with Fuse \(em you must supply your own copies of those which @@ -1919,6 +1924,13 @@ Emulate a \(mcSource interface. Same as the General Peripherals Options dialog's option. .RE .PP +.B \-\-uspeech +.RS +Emulate a \(mcSpeech interface. Same as the Sound Peripherals Options dialog's +.I "\(mcSpeech" +option. +.RE +.PP .B \-V .br .B \-\-version @@ -2669,6 +2681,11 @@ Sets the relative volume of the Covox from a range of 0\(en100%. .RS Sets the relative volume of the SpecDrum from a range of 0\(en100%. .RE +.PP +.I "uSpeech volume" +.RS +Sets the relative volume of the \(mcSpeech from a range of 0\(en100%. +.RE .RE .PP .I "Options, Peripherals, General..." @@ -2866,6 +2883,14 @@ interface. See the World of Spectrum Infoseek web page at for manuals, software and more. This emulation is only available for the 48k, 128k and TC2048 machines. .RE +.PP +.I "\(mcSpeech" +.RS +If this option is selected, Fuse will emulate a Currah \(mcSpeech interface. +See the World of Spectrum Infoseek web page at +.I http://www.worldofspectrum.org/infoseekid.cgi?id=1000081 +for the manual, software and more. +.RE .RE .PP .I "Options, Peripherals, Disk..." diff --git a/memory_pages.c b/memory_pages.c index cafc4574..c2f51c20 100644 --- a/memory_pages.c +++ b/memory_pages.c @@ -42,6 +42,7 @@ #include "memory_pages.h" #include "module.h" #include "peripherals/disk/opus.h" +#include "peripherals/sound/uspeech.h" #include "peripherals/spectranet.h" #include "peripherals/ttx2000s.h" #include "peripherals/ula.h" @@ -404,6 +405,9 @@ readbyte( libspectrum_word address ) if( ttx2000s_paged && address >= 0x2000 ) return ttx2000s_sram_read( address ); + + if( uspeech_available && address == 0x1000 ) + return uspeech_busy(); } return mapping->page[ address & MEMORY_PAGE_SIZE_MASK ]; @@ -516,6 +520,10 @@ writebyte_internal( libspectrum_word address, libspectrum_byte b ) memory_display_dirty( address, b ); memory[ offset ] = b; + } else if( uspeech_available ) { + if( address == 0x1000 || ( address & 0xfffe ) == 0x3000 ) { + uspeech_write( address, b ); + } } } diff --git a/menu.c b/menu.c index 7168ed3b..77608c16 100644 --- a/menu.c +++ b/menu.c @@ -294,6 +294,7 @@ MENU_CALLBACK_WITH_ACTION( menu_options_selectroms_peripheral_select ) case 10: menu_select_peripheral_roms( "SpeccyBoot", 9, 1 ); return; case 11: menu_select_peripheral_roms( "TTX2000S", 10, 1 ); return; case 12: menu_select_peripheral_roms( "uSource", 11, 1 ); return; + case 13: menu_select_peripheral_roms( "uSpeech", 12, 1 ); return; } diff --git a/menu_data.dat b/menu_data.dat index 42bebe10..55f2f02c 100644 --- a/menu_data.dat +++ b/menu_data.dat @@ -126,6 +126,7 @@ Options/Select ROMs/Peripheral ROMs/_Opus Discovery..., Item,, menu_options_sele Options/Select ROMs/Peripheral ROMs/Specc_yBoot..., Item,, menu_options_selectroms_peripheral_select,, 10 Options/Select ROMs/Peripheral ROMs/TT_X2000S..., Item,, menu_options_selectroms_peripheral_select,, 11 Options/Select ROMs/Peripheral ROMs/_uSource..., Item,, menu_options_selectroms_peripheral_select,, 12 +Options/Select ROMs/Peripheral ROMs/_uSpeech..., Item,, menu_options_selectroms_peripheral_select,, 13 Options/_Filter..., Item,,, menu_filter_detail diff --git a/periph.h b/periph.h index 8f82fa28..3aa7327a 100644 --- a/periph.h +++ b/periph.h @@ -76,6 +76,7 @@ typedef enum periph_type { PERIPH_TYPE_ULA_FULL_DECODE,/* Standard ULA responding only to 0xfe */ PERIPH_TYPE_UPD765, /* +3 uPD765 FDC */ PERIPH_TYPE_USOURCE, /* Currah uSource interface */ + PERIPH_TYPE_USPEECH, /* Currah uSpeech interface */ PERIPH_TYPE_ZXATASP, /* ZXATASP IDE interface */ PERIPH_TYPE_ZXCF, /* ZXCF IDE interface */ PERIPH_TYPE_ZXMMC, /* ZXMMC interface */ diff --git a/peripherals/Makefile.am b/peripherals/Makefile.am index cf9e1325..336123a3 100644 --- a/peripherals/Makefile.am +++ b/peripherals/Makefile.am @@ -38,7 +38,9 @@ fuse_SOURCES += \ peripherals/sound/covox.c \ peripherals/sound/fuller.c \ peripherals/sound/melodik.c \ + peripherals/sound/sp0256.c \ peripherals/sound/specdrum.c \ + peripherals/sound/uspeech.c \ peripherals/disk/beta.c \ peripherals/disk/crc.c \ peripherals/disk/didaktik.c \ diff --git a/peripherals/sound/sp0256.c b/peripherals/sound/sp0256.c new file mode 100644 index 00000000..8ad75edd --- /dev/null +++ b/peripherals/sound/sp0256.c @@ -0,0 +1,1525 @@ +/* sp0256.c: SP0256 speech synthesis emulation + Copyright (c) 1998-2000 Jospeh Zbicaik, 2007-2015 Stuart Brady + + $Id$ + + 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 2 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, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + Philip: phi...@sh... + + Stuart: stu...@gm... + +*/ + +/* Based on the SP0256 emulation in jzIntv (an Intellivision emulator), + * where it is used for Intellivoice emulation. + * + * For information about the SP0256: + * * http://en.wikipedia.org/wiki/General_Instrument_SP0256-AL2 + * * http://www.cpcwiki.eu/index.php/SP0256 + */ + +#include "config.h" + +#include <stdio.h> + +#include "libspectrum.h" + +#include <assert.h> + +// from jzintv-config.h +#include <stdarg.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include "compat.h" +#include "event.h" +#include "machine.h" +#include "sp0256.h" +#include "sound.h" + +/* + * SP0256-based peripherals for the ZX Spectrum seem limited to using the + * interface to the "Address LoaD" (ALD) mechanism on the SP0256, and the + * "Load ReQuest" (LRQ) state in bit 15. When LRQ is 1, the SP0256 is + * ready to receive a new command. A new command address may then be + * written to using the Address LoaD mechanism to trigger the playback of + * a sound. Note that command address register is actually a 1-deep FIFO, + * and so LRQ will go to 1 before the SP0256 is finished speaking. + * + * The exact format of the SP0256 speech data, as well as the overall + * system view from the SP0256's perspective is documented elsewhere. + */ + +#define dfprintf(x) +#define debug_printf(x) +#define jzp_printf(x, ...) + +#define HIGH_QUALITY +#define SCBUF_SIZE (4096) /* Must be power of 2 */ +#define SCBUF_MASK (SCBUF_SIZE - 1) +#define PER_PAUSE (64) /* Equiv timing period for pauses. */ +#define PER_NOISE (64) /* Equiv timing period for noise. */ + +#define FIFO_ADDR (0x1800 << 3) /* SP0256 address of speech FIFO. */ + +uint64_t sp0256_tstates; +uint64_t sp0256_now; + +typedef struct lpc12_t +{ + int rpt, cnt; /* Repeat counter, Period down-counter. */ + uint32_t per, rng; /* Period, Amplitude, Random Number Generator */ + int amp; + int16_t f_coef[6]; /* F0 through F5. */ + int16_t b_coef[6]; /* B0 through B5. */ + int16_t z_data[6][2]; /* Time-delay data for the */ + /* filter stages. */ + uint8_t r[16]; /* The encoded register set. */ + int interp; +} lpc12_t; + + +typedef struct sp0256_t +{ + int silent; /* Flag: SP0256 is silent. */ + + int16_t *scratch; /* Scratch buffer for audio. */ + uint32_t sc_head; /* Head/Tail pointer into scratch circular buf */ + uint32_t sc_tail; /* Head/Tail pointer into scratch circular buf */ + uint64_t sound_current; + + lpc12_t filt; /* 12-pole filter */ + int lrq; /* Load ReQuest. == 0 if we can accept a load */ + int ald; /* Address LoaD. < 0 if no command pending. */ + int pc; /* Microcontroller's PC value. */ + int stack; /* Microcontroller's PC stack. */ + int fifo_sel; /* True when executing from FIFO. */ + int halted; /* True when CPU is halted. */ + uint32_t mode; /* Mode register. */ + uint32_t page; /* Page set by SETPAGE */ + + uint32_t fifo_head; /* FIFO head pointer (where new data goes). */ + uint32_t fifo_tail; /* FIFO tail pointer (where data comes from). */ + uint32_t fifo_bitp; /* FIFO bit-pointer (for partial decles). */ + uint16_t fifo[64]; /* The 64-decle FIFO. */ + + const uint8_t *rom[16]; /* 4K ROM pages. */ +} sp0256_t; + + +/* ======================================================================== */ +/* sp0256_run -- Where the magic happens. Generate voice data for */ +/* our good friend, the SP0256. */ +/* ======================================================================== */ +static uint32_t sp0256_run(sp0256_t *s, uint32_t len); + +/* ======================================================================== */ +/* sp0256_read_lrq -- Handle reads of the SP0256 LRQ line. */ +/* ======================================================================== */ +static uint32_t sp0256_read_lrq(sp0256_t *s); + +/* ======================================================================== */ +/* sp0256_write_ald -- Handle writes to the SP0256's Address Load FIFO. */ +/* ======================================================================== */ +static void sp0256_write_ald(sp0256_t *s, uint32_t data); + +/* ======================================================================== */ +/* sp0256_do_init -- Makes a new SP0256. */ +/* ======================================================================== */ +static int sp0256_do_init( sp0256_t *s ); + +static int factor = 358; + +/* ======================================================================== */ +/* Internal function prototypes. */ +/* ======================================================================== */ +static inline int16_t limit (int16_t s); +static inline uint32_t bitrev(uint32_t val); +static int lpc12_update(lpc12_t *f, int, int16_t *, uint32_t *); +static void lpc12_regdec(lpc12_t *f); +static uint32_t sp0256_getb(sp0256_t *s, int len); +static void sp0256_micro(sp0256_t *s); + +/* ======================================================================== */ +/* qtbl -- Coefficient Quantization Table. This comes from a */ +/* SP0250 data sheet, and should be correct for SP0256. */ +/* ======================================================================== */ +static const int16_t qtbl[128] = { + 0, 9, 17, 25, 33, 41, 49, 57, + 65, 73, 81, 89, 97, 105, 113, 121, + 129, 137, 145, 153, 161, 169, 177, 185, + 193, 201, 209, 217, 225, 233, 241, 249, + 257, 265, 273, 281, 289, 297, 301, 305, + 309, 313, 317, 321, 325, 329, 333, 337, + 341, 345, 349, 353, 357, 361, 365, 369, + 373, 377, 381, 385, 389, 393, 397, 401, + 405, 409, 413, 417, 421, 425, 427, 429, + 431, 433, 435, 437, 439, 441, 443, 445, + 447, 449, 451, 453, 455, 457, 459, 461, + 463, 465, 467, 469, 471, 473, 475, 477, + 479, 481, 482, 483, 484, 485, 486, 487, + 488, 489, 490, 491, 492, 493, 494, 495, + 496, 497, 498, 499, 500, 501, 502, 503, + 504, 505, 506, 507, 508, 509, 510, 511 +}; + +/* ======================================================================== */ +/* limit -- Limiter function for digital sample output. */ +/* ======================================================================== */ +static inline int16_t +limit(int16_t s) +{ +#ifdef HIGH_QUALITY /* Higher quality than the original, but who cares? */ + if (s > 8191) return 8191; + if (s < -8192) return -8192; +#else + if (s > 127) return 127; + if (s < -128) return -128; +#endif + return s; +} + +/* ======================================================================== */ +/* amp_decode -- Decode amplitude register */ +/* ======================================================================== */ +static int +amp_decode(uint8_t a) +{ + /* -------------------------------------------------------------------- */ + /* Amplitude has 3 bits of exponent and 5 bits of mantissa. This */ + /* contradicts USP 4,296,269 but matches the SP0250 Apps Manual. */ + /* -------------------------------------------------------------------- */ + int expn = (a & 0xe0) >> 5; + int mant = (a & 0x1f); + int ampl = mant << expn; + + /* -------------------------------------------------------------------- */ + /* Careful reading of USP 4,296,279, around line 60 in column 14 on */ + /* page 16 of the scan suggests the LSB might be held and injected */ + /* into the output while the exponent gets counted down, although */ + /* this seems dubious. */ + /* -------------------------------------------------------------------- */ +#if 0 + if (mant & 1) + ampl |= (1 << expn) - 1; +#endif + + return ampl; +} + +/* ======================================================================== */ +/* lpc12_update -- Update the 12-pole filter, outputting samples. */ +/* ======================================================================== */ +static int +lpc12_update(lpc12_t *f, int num_samp, int16_t *out, uint32_t *optr) +{ + int i, j; + int16_t samp; + int do_int, bit; + int oidx = *optr; + + /* -------------------------------------------------------------------- */ + /* Iterate up to the desired number of samples. We actually may */ + /* break out early if our repeat count expires. */ + /* -------------------------------------------------------------------- */ + for (i = 0; i < num_samp; i++) { + /* ---------------------------------------------------------------- */ + /* Generate a series of periodic impulses, or random noise. */ + /* ---------------------------------------------------------------- */ + do_int = 0; + samp = 0; + bit = f->rng & 1; + f->rng = (f->rng >> 1) ^ (bit ? 0x4001 : 0); + + if (--f->cnt <= 0) { + if (f->rpt-- <= 0) { /* Stop if we expire the repeat counter */ + f->cnt = f->rpt = 0; + break; + } + + f->cnt = f->per ? f->per : PER_NOISE; + samp = f->amp; + do_int = f->interp; + } + + if (!f->per) + samp = bit ? -f->amp : f->amp; + + /* ---------------------------------------------------------------- */ + /* If we need to, process the interpolation registers. */ + /* ---------------------------------------------------------------- */ + if (do_int) { + f->r[0] += f->r[14]; + f->r[1] += f->r[15]; + + f->amp = amp_decode(f->r[0]); + f->per = f->r[1]; + + do_int = 0; + } + + /* ---------------------------------------------------------------- */ + /* Each 2nd order stage looks like one of these. The App. Manual */ + /* gives the first form, the patent gives the second form. */ + /* They're equivalent except for time delay. I implement the */ + /* first form. (Note: 1/Z == 1 unit of time delay.) */ + /* */ + /* ---->(+)-------->(+)----------+-------> */ + /* ^ ^ | */ + /* | | | */ + /* | | | */ + /* [B] [2*F] | */ + /* ^ ^ | */ + /* | | | */ + /* | | | */ + /* +---[1/Z]<--+---[1/Z]<--+ */ + /* */ + /* */ + /* +---[2*F]<---+ */ + /* | | */ + /* | | */ + /* v | */ + /* ---->(+)-->[1/Z]-->+-->[1/Z]---+------> */ + /* ^ | */ + /* | | */ + /* | | */ + /* +-----------[B]<---------+ */ + /* */ + /* ---------------------------------------------------------------- */ + for (j = 0; j < 6; j++) { + samp += (((int)f->b_coef[j] * (int)f->z_data[j][1]) >> 9); + samp += (((int)f->f_coef[j] * (int)f->z_data[j][0]) >> 8); + + f->z_data[j][1] = f->z_data[j][0]; + f->z_data[j][0] = samp; + } + +#ifdef HIGH_QUALITY /* Higher quality than the original, but who cares? */ + out[oidx++ & SCBUF_MASK] = limit(samp) << 2; +#else + out[oidx++ & SCBUF_MASK] = (limit(samp >> 4) << 8); +#endif + } + + *optr = oidx; + + return i; +} + +/*static int stage_map[6] = { 4, 2, 0, 5, 3, 1 };*/ +/*static int stage_map[6] = { 3, 0, 4, 1, 5, 2 };*/ +/*static int stage_map[6] = { 3, 0, 1, 4, 2, 5 };*/ +static const int stage_map[6] = { 0, 1, 2, 3, 4, 5 }; + +/* ======================================================================== */ +/* lpc12_regdec -- Decode the register set in the filter bank. */ +/* ======================================================================== */ +static void +lpc12_regdec(lpc12_t *f) +{ + int i; + + /* -------------------------------------------------------------------- */ + /* Decode the Amplitude and Period registers. Force cnt to 0 to get */ + /* the initial impulse. (Redundant?) */ + /* -------------------------------------------------------------------- */ + f->amp = amp_decode(f->r[0]); + f->cnt = 0; + f->per = f->r[1]; + + /* -------------------------------------------------------------------- */ + /* Decode the filter coefficients from the quant table. */ + /* -------------------------------------------------------------------- */ + for (i = 0; i < 6; i++) { + #define IQ(x) (((x) & 0x80) ? qtbl[0x7f & -(x)] : -qtbl[(x)]) + + f->b_coef[stage_map[i]] = IQ(f->r[2 + 2*i]); + f->f_coef[stage_map[i]] = IQ(f->r[3 + 2*i]); + } + + /* -------------------------------------------------------------------- */ + /* Set the Interp flag based on whether we have interpolation parms */ + /* -------------------------------------------------------------------- */ + f->interp = f->r[14] || f->r[15]; + + return; +} + +/* ======================================================================== */ +/* sp0256_datafmt -- Data format table for the SP0256's microsequencer */ +/* */ +/* len 4 bits Length of field to extract */ +/* lshift 4 bits Left-shift amount on field */ +/* param 4 bits Parameter number being updated */ +/* delta 1 bit This is a delta-update. (Implies sign-extend) */ +/* field 1 bit This is a field replace. */ +/* clr5 1 bit Clear F5, B5. */ +/* clrall 1 bit Clear all before doing this update */ +/* ======================================================================== */ + +#define CR(l,s,p,d,f,c5,ca) \ + ( \ + (((l) & 15) << 0) | \ + (((s) & 15) << 4) | \ + (((p) & 15) << 8) | \ + (((d) & 1) << 12) | \ + (((f) & 1) << 13) | \ + (((c5) & 1) << 14) | \ + (((ca) & 1) << 15) \ + ) + +#define CR_DELTA CR(0,0,0,1,0,0,0) +#define CR_FIELD CR(0,0,0,0,1,0,0) +#define CR_CLR5 CR(0,0,0,0,0,1,0) +#define CR_CLRL CR(0,0,0,0,0,0,1) +#define CR_LEN(x) ((x) & 15) +#define CR_SHF(x) (((x) >> 4) & 15) +#define CR_PRM(x) (((x) >> 8) & 15) + +enum { AM = 0, PR, B0, F0, B1, F1, B2, F2, B3, F3, B4, F4, B5, F5, IA, IP }; + +static const uint16_t sp0256_datafmt[] = { + /* -------------------------------------------------------------------- */ + /* OPCODE 1111: PAUSE */ + /* -------------------------------------------------------------------- */ + /* 0 */ CR( 0, 0, 0, 0, 0, 0, 0), /* Clear all */ + + /* -------------------------------------------------------------------- */ + /* Opcode 0001: LOADALL */ + /* -------------------------------------------------------------------- */ + /* All modes */ + /* 1 */ CR( 8, 0, AM, 0, 0, 0, 0), /* Amplitude */ + /* 2 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */ + /* 3 */ CR( 8, 0, B0, 0, 0, 0, 0), /* B0 */ + /* 4 */ CR( 8, 0, F0, 0, 0, 0, 0), /* F0 */ + /* 5 */ CR( 8, 0, B1, 0, 0, 0, 0), /* B1 */ + /* 6 */ CR( 8, 0, F1, 0, 0, 0, 0), /* F1 */ + /* 7 */ CR( 8, 0, B2, 0, 0, 0, 0), /* B2 */ + /* 8 */ CR( 8, 0, F2, 0, 0, 0, 0), /* F2 */ + /* 9 */ CR( 8, 0, B3, 0, 0, 0, 0), /* B3 */ + /* 10 */ CR( 8, 0, F3, 0, 0, 0, 0), /* F3 */ + /* 11 */ CR( 8, 0, B4, 0, 0, 0, 0), /* B4 */ + /* 12 */ CR( 8, 0, F4, 0, 0, 0, 0), /* F4 */ + /* 13 */ CR( 8, 0, B5, 0, 0, 0, 0), /* B5 */ + /* 14 */ CR( 8, 0, F5, 0, 0, 0, 0), /* F5 */ + /* Mode 01 and 11 only */ + /* 15 */ CR( 8, 0, IA, 0, 0, 0, 0), /* Amp Interp */ + /* 16 */ CR( 8, 0, IP, 0, 0, 0, 0), /* Pit Interp */ + + /* -------------------------------------------------------------------- */ + /* Opcode 0100: LOAD_4 */ + /* -------------------------------------------------------------------- */ + /* Mode 00 and 01 */ + /* 17 */ CR( 6, 2, AM, 0, 0, 0, 1), /* Amplitude */ + /* 18 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */ + /* 19 */ CR( 4, 3, B3, 0, 0, 0, 0), /* B3 (S=0) */ + /* 20 */ CR( 6, 2, F3, 0, 0, 0, 0), /* F3 */ + /* 21 */ CR( 7, 1, B4, 0, 0, 0, 0), /* B4 */ + /* 22 */ CR( 6, 2, F4, 0, 0, 0, 0), /* F4 */ + /* Mode 01 only */ + /* 23 */ CR( 8, 0, B5, 0, 0, 0, 0), /* B5 */ + /* 24 */ CR( 8, 0, F5, 0, 0, 0, 0), /* F5 */ + + /* Mode 10 and 11 */ + /* 25 */ CR( 6, 2, AM, 0, 0, 0, 1), /* Amplitude */ + /* 26 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */ + /* 27 */ CR( 6, 1, B3, 0, 0, 0, 0), /* B3 (S=0) */ + /* 28 */ CR( 7, 1, F3, 0, 0, 0, 0), /* F3 */ + /* 29 */ CR( 8, 0, B4, 0, 0, 0, 0), /* B4 */ + /* 30 */ CR( 8, 0, F4, 0, 0, 0, 0), /* F4 */ + /* Mode 11 only */ + /* 31 */ CR( 8, 0, B5, 0, 0, 0, 0), /* B5 */ + /* 32 */ CR( 8, 0, F5, 0, 0, 0, 0), /* F5 */ + + /* -------------------------------------------------------------------- */ + /* Opcode 0110: SETMSB_6 */ + /* -------------------------------------------------------------------- */ + /* Mode 00 only */ + /* 33 */ CR( 0, 0, 0, 0, 0, 0, 0), + /* Mode 00 and 01 */ + /* 34 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */ + /* 35 */ CR( 6, 2, F3, 0, 1, 0, 0), /* F3 (5 MSBs) */ + /* 36 */ CR( 6, 2, F4, 0, 1, 0, 0), /* F4 (5 MSBs) */ + /* Mode 01 only */ + /* 37 */ CR( 8, 0, F5, 0, 1, 0, 0), /* F5 (5 MSBs) */ + + /* Mode 10 only */ + /* 38 */ CR( 0, 0, 0, 0, 0, 0, 0), + /* Mode 10 and 11 */ + /* 39 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */ + /* 40 */ CR( 7, 1, F3, 0, 1, 0, 0), /* F3 (6 MSBs) */ + /* 41 */ CR( 8, 0, F4, 0, 1, 0, 0), /* F4 (6 MSBs) */ + /* Mode 11 only */ + /* 42 */ CR( 8, 0, F5, 0, 1, 0, 0), /* F5 (6 MSBs) */ + + /* 43 */ 0, + /* 44 */ 0, + + /* -------------------------------------------------------------------- */ + /* Opcode 1001: DELTA_9 */ + /* -------------------------------------------------------------------- */ + /* Mode 00 and 01 */ + /* 45 */ CR( 4, 2, AM, 1, 0, 0, 0), /* Amplitude */ + /* 46 */ CR( 5, 0, PR, 1, 0, 0, 0), /* Period */ + /* 47 */ CR( 3, 4, B0, 1, 0, 0, 0), /* B0 4 MSBs */ + /* 48 */ CR( 3, 3, F0, 1, 0, 0, 0), /* F0 5 MSBs */ + /* 49 */ CR( 3, 4, B1, 1, 0, 0, 0), /* B1 4 MSBs */ + /* 50 */ CR( 3, 3, F1, 1, 0, 0, 0), /* F1 5 MSBs */ + /* 51 */ CR( 3, 4, B2, 1, 0, 0, 0), /* B2 4 MSBs */ + /* 52 */ CR( 3, 3, F2, 1, 0, 0, 0), /* F2 5 MSBs */ + /* 53 */ CR( 3, 3, B3, 1, 0, 0, 0), /* B3 5 MSBs */ + /* 54 */ CR( 4, 2, F3, 1, 0, 0, 0), /* F3 6 MSBs */ + /* 55 */ CR( 4, 1, B4, 1, 0, 0, 0), /* B4 7 MSBs */ + /* 56 */ CR( 4, 2, F4, 1, 0, 0, 0), /* F4 6 MSBs */ + /* Mode 01 only */ + /* 57 */ CR( 5, 0, B5, 1, 0, 0, 0), /* B5 8 MSBs */ + /* 58 */ CR( 5, 0, F5, 1, 0, 0, 0), /* F5 8 MSBs */ + + /* Mode 10 and 11 */ + /* 59 */ CR( 4, 2, AM, 1, 0, 0, 0), /* Amplitude */ + /* 60 */ CR( 5, 0, PR, 1, 0, 0, 0), /* Period */ + /* 61 */ CR( 4, 1, B0, 1, 0, 0, 0), /* B0 7 MSBs */ + /* 62 */ CR( 4, 2, F0, 1, 0, 0, 0), /* F0 6 MSBs */ + /* 63 */ CR( 4, 1, B1, 1, 0, 0, 0), /* B1 7 MSBs */ + /* 64 */ CR( 4, 2, F1, 1, 0, 0, 0), /* F1 6 MSBs */ + /* 65 */ CR( 4, 1, B2, 1, 0, 0, 0), /* B2 7 MSBs */ + /* 66 */ CR( 4, 2, F2, 1, 0, 0, 0), /* F2 6 MSBs */ + /* 67 */ CR( 4, 1, B3, 1, 0, 0, 0), /* B3 7 MSBs */ + /* 68 */ CR( 5, 1, F3, 1, 0, 0, 0), /* F3 7 MSBs */ + /* 69 */ CR( 5, 0, B4, 1, 0, 0, 0), /* B4 8 MSBs */ + /* 70 */ CR( 5, 0, F4, 1, 0, 0, 0), /* F4 8 MSBs */ + /* Mode 11 only */ + /* 71 */ CR( 5, 0, B5, 1, 0, 0, 0), /* B5 8 MSBs */ + /* 72 */ CR( 5, 0, F5, 1, 0, 0, 0), /* F5 8 MSBs */ + + /* -------------------------------------------------------------------- */ + /* Opcode 1010: SETMSB_A */ + /* -------------------------------------------------------------------- */ + /* Mode 00 only */ + /* 73 */ CR( 0, 0, 0, 0, 0, 0, 0), + /* Mode 00 and 01 */ + /* 74 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */ + /* 75 */ CR( 5, 3, F0, 0, 1, 0, 0), /* F0 (5 MSBs) */ + /* 76 */ CR( 5, 3, F1, 0, 1, 0, 0), /* F1 (5 MSBs) */ + /* 77 */ CR( 5, 3, F2, 0, 1, 0, 0), /* F2 (5 MSBs) */ + + /* Mode 10 only */ + /* 78 */ CR( 0, 0, 0, 0, 0, 0, 0), + /* Mode 10 and 11 */ + /* 79 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */ + /* 80 */ CR( 6, 2, F0, 0, 1, 0, 0), /* F0 (6 MSBs) */ + /* 81 */ CR( 6, 2, F1, 0, 1, 0, 0), /* F1 (6 MSBs) */ + /* 82 */ CR( 6, 2, F2, 0, 1, 0, 0), /* F2 (6 MSBs) */ + + /* -------------------------------------------------------------------- */ + /* Opcode 0010: LOAD_2 Mode 00 and 10 */ + /* Opcode 1100: LOAD_C Mode 00 and 10 */ + /* -------------------------------------------------------------------- */ + /* LOAD_2, LOAD_C Mode 00 */ + /* 83 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */ + /* 84 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */ + /* 85 */ CR( 3, 4, B0, 0, 0, 0, 0), /* B0 (S=0) */ + /* 86 */ CR( 5, 3, F0, 0, 0, 0, 0), /* F0 */ + /* 87 */ CR( 3, 4, B1, 0, 0, 0, 0), /* B1 (S=0) */ + /* 88 */ CR( 5, 3, F1, 0, 0, 0, 0), /* F1 */ + /* 89 */ CR( 3, 4, B2, 0, 0, 0, 0), /* B2 (S=0) */ + /* 90 */ CR( 5, 3, F2, 0, 0, 0, 0), /* F2 */ + /* 91 */ CR( 4, 3, B3, 0, 0, 0, 0), /* B3 (S=0) */ + /* 92 */ CR( 6, 2, F3, 0, 0, 0, 0), /* F3 */ + /* 93 */ CR( 7, 1, B4, 0, 0, 0, 0), /* B4 */ + /* 94 */ CR( 6, 2, F4, 0, 0, 0, 0), /* F4 */ + /* LOAD_2 only */ + /* 95 */ CR( 5, 0, IA, 0, 0, 0, 0), /* Ampl. Intr. */ + /* 96 */ CR( 5, 0, IP, 0, 0, 0, 0), /* Per. Intr. */ + + /* LOAD_2, LOAD_C Mode 10 */ + /* 97 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */ + /* 98 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */ + /* 99 */ CR( 6, 1, B0, 0, 0, 0, 0), /* B0 (S=0) */ + /* 100 */ CR( 6, 2, F0, 0, 0, 0, 0), /* F0 */ + /* 101 */ CR( 6, 1, B1, 0, 0, 0, 0), /* B1 (S=0) */ + /* 102 */ CR( 6, 2, F1, 0, 0, 0, 0), /* F1 */ + /* 103 */ CR( 6, 1, B2, 0, 0, 0, 0), /* B2 (S=0) */ + /* 104 */ CR( 6, 2, F2, 0, 0, 0, 0), /* F2 */ + /* 105 */ CR( 6, 1, B3, 0, 0, 0, 0), /* B3 (S=0) */ + /* 106 */ CR( 7, 1, F3, 0, 0, 0, 0), /* F3 */ + /* 107 */ CR( 8, 0, B4, 0, 0, 0, 0), /* B4 */ + /* 108 */ CR( 8, 0, F4, 0, 0, 0, 0), /* F4 */ + /* LOAD_2 only */ + /* 109 */ CR( 5, 0, IA, 0, 0, 0, 0), /* Ampl. Intr. */ + /* 110 */ CR( 5, 0, IP, 0, 0, 0, 0), /* Per. Intr. */ + + /* -------------------------------------------------------------------- */ + /* OPCODE 1101: DELTA_D */ + /* -------------------------------------------------------------------- */ + /* Mode 00 and 01 */ + /* 111 */ CR( 4, 2, AM, 1, 0, 0, 1), /* Amplitude */ + /* 112 */ CR( 5, 0, PR, 1, 0, 0, 0), /* Period */ + /* 113 */ CR( 3, 3, B3, 1, 0, 0, 0), /* B3 5 MSBs */ + /* 114 */ CR( 4, 2, F3, 1, 0, 0, 0), /* F3 6 MSBs */ + /* 115 */ CR( 4, 1, B4, 1, 0, 0, 0), /* B4 7 MSBs */ + /* 116 */ CR( 4, 2, F4, 1, 0, 0, 0), /* F4 6 MSBs */ + /* Mode 01 only */ + /* 117 */ CR( 5, 0, B5, 1, 0, 0, 0), /* B5 8 MSBs */ + /* 118 */ CR( 5, 0, F5, 1, 0, 0, 0), /* F5 8 MSBs */ + + /* Mode 10 and 11 */ + /* 119 */ CR( 4, 2, AM, 1, 0, 0, 0), /* Amplitude */ + /* 120 */ CR( 5, 0, PR, 1, 0, 0, 0), /* Period */ + /* 121 */ CR( 4, 1, B3, 1, 0, 0, 0), /* B3 7 MSBs */ + /* 122 */ CR( 5, 1, F3, 1, 0, 0, 0), /* F3 7 MSBs */ + /* 123 */ CR( 5, 0, B4, 1, 0, 0, 0), /* B4 8 MSBs */ + /* 124 */ CR( 5, 0, F4, 1, 0, 0, 0), /* F4 8 MSBs */ + /* Mode 11 only */ + /* 125 */ CR( 5, 0, B5, 1, 0, 0, 0), /* B5 8 MSBs */ + /* 126 */ CR( 5, 0, F5, 1, 0, 0, 0), /* F5 8 MSBs */ + + /* -------------------------------------------------------------------- */ + /* OPCODE 1110: LOAD_E */ + /* -------------------------------------------------------------------- */ + /* 127 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */ + /* 128 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */ + + /* -------------------------------------------------------------------- */ + /* Opcode 0010: LOAD_2 Mode 01 and 11 */ + /* Opcode 1100: LOAD_C Mode 01 and 11 */ + /* -------------------------------------------------------------------- */ + /* LOAD_2, LOAD_C Mode 01 */ + /* 129 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */ + /* 130 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */ + /* 131 */ CR( 3, 4, B0, 0, 0, 0, 0), /* B0 (S=0) */ + /* 132 */ CR( 5, 3, F0, 0, 0, 0, 0), /* F0 */ + /* 133 */ CR( 3, 4, B1, 0, 0, 0, 0), /* B1 (S=0) */ + /* 134 */ CR( 5, 3, F1, 0, 0, 0, 0), /* F1 */ + /* 135 */ CR( 3, 4, B2, 0, 0, 0, 0), /* B2 (S=0) */ + /* 136 */ CR( 5, 3, F2, 0, 0, 0, 0), /* F2 */ + /* 137 */ CR( 4, 3, B3, 0, 0, 0, 0), /* B3 (S=0) */ + /* 138 */ CR( 6, 2, F3, 0, 0, 0, 0), /* F3 */ + /* 139 */ CR( 7, 1, B4, 0, 0, 0, 0), /* B4 */ + /* 140 */ CR( 6, 2, F4, 0, 0, 0, 0), /* F4 */ + /* 141 */ CR( 8, 0, B5, 0, 0, 0, 0), /* B5 */ + /* 142 */ CR( 8, 0, F5, 0, 0, 0, 0), /* F5 */ + /* LOAD_2 only */ + /* 143 */ CR( 5, 0, IA, 0, 0, 0, 0), /* Ampl. Intr. */ + /* 144 */ CR( 5, 0, IP, 0, 0, 0, 0), /* Per. Intr. */ + + /* LOAD_2, LOAD_C Mode 11 */ + /* 145 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */ + /* 146 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */ + /* 147 */ CR( 6, 1, B0, 0, 0, 0, 0), /* B0 (S=0) */ + /* 148 */ CR( 6, 2, F0, 0, 0, 0, 0), /* F0 */ + /* 149 */ CR( 6, 1, B1, 0, 0, 0, 0), /* B1 (S=0) */ + /* 150 */ CR( 6, 2, F1, 0, 0, 0, 0), /* F1 */ + /* 151 */ CR( 6, 1, B2, 0, 0, 0, 0), /* B2 (S=0) */ + /* 152 */ CR( 6, 2, F2, 0, 0, 0, 0), /* F2 */ + /* 153 */ CR( 6, 1, B3, 0, 0, 0, 0), /* B3 (S=0) */ + /* 154 */ CR( 7, 1, F3, 0, 0, 0, 0), /* F3 */ + /* 155 */ CR( 8, 0, B4, 0, 0, 0, 0), /* B4 */ + /* 156 */ CR( 8, 0, F4, 0, 0, 0, 0), /* F4 */ + /* 157 */ CR( 8, 0, B5, 0, 0, 0, 0), /* B5 */ + /* 158 */ CR( 8, 0, F5, 0, 0, 0, 0), /* F5 */ + /* LOAD_2 only */ + /* 159 */ CR( 5, 0, IA, 0, 0, 0, 0), /* Ampl. Intr. */ + /* 160 */ CR( 5, 0, IP, 0, 0, 0, 0), /* Per. Intr. */ + + /* -------------------------------------------------------------------- */ + /* Opcode 0011: SETMSB_3 */ + /* Opcode 0101: SETMSB_5 */ + /* -------------------------------------------------------------------- */ + /* Mode 00 only */ + /* 161 */ CR( 0, 0, 0, 0, 0, 0, 0), + /* Mode 00 and 01 */ + /* 162 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */ + /* 163 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */ + /* 164 */ CR( 5, 3, F0, 0, 1, 0, 0), /* F0 (5 MSBs) */ + /* 165 */ CR( 5, 3, F1, 0, 1, 0, 0), /* F1 (5 MSBs) */ + /* 166 */ CR( 5, 3, F2, 0, 1, 0, 0), /* F2 (5 MSBs) */ + /* SETMSB_3 only */ + /* 167 */ CR( 5, 0, IA, 0, 0, 0, 0), /* Ampl. Intr. */ + /* 168 */ CR( 5, 0, IP, 0, 0, 0, 0), /* Per. Intr. */ + + /* Mode 10 only */ + /* 169 */ CR( 0, 0, 0, 0, 0, 0, 0), + /* Mode 10 and 11 */ + /* 170 */ CR( 6, 2, AM, 0, 0, 0, 0), /* Amplitude */ + /* 171 */ CR( 8, 0, PR, 0, 0, 0, 0), /* Period */ + /* 172 */ CR( 6, 2, F0, 0, 1, 0, 0), /* F0 (6 MSBs) */ + /* 173 */ CR( 6, 2, F1, 0, 1, 0, 0), /* F1 (6 MSBs) */ + /* 174 */ CR( 6, 2, F2, 0, 1, 0, 0), /* F2 (6 MSBs) */ + /* SETMSB_3 only */ + /* 175 */ CR( 5, 0, IA, 0, 0, 0, 0), /* Ampl. Intr. */ + /* 176 */ CR( 5, 0, IP, 0, 0, 0, 0), /* Per. Intr. */ +}; + + + +static const int16_t sp0256_df_idx[16 * 8] = { + /* OPCODE 0000 */ -1, -1, -1, -1, -1, -1, -1, -1, + /* OPCODE 1000 */ -1, -1, -1, -1, -1, -1, -1, -1, + /* OPCODE 0100 */ 17, 22, 17, 24, 25, 30, 25, 32, + /* OPCODE 1100 */ 83, 94, 129,142, 97, 108, 145,158, + /* OPCODE 0010 */ 83, 96, 129,144, 97, 110, 145,160, + /* OPCODE 1010 */ 73, 77, 74, 77, 78, 82, 79, 82, + /* OPCODE 0110 */ 33, 36, 34, 37, 38, 41, 39, 42, + /* OPCODE 1110 */ 127,128, 127,128, 127,128, 127,128, + /* OPCODE 0001 */ 1, 14, 1, 16, 1, 14, 1, 16, + /* OPCODE 1001 */ 45, 56, 45, 58, 59, 70, 59, 72, + /* OPCODE 0101 */ 161,166, 162,166, 169,174, 170,174, + /* OPCODE 1101 */ 111,116, 111,118, 119,124, 119,126, + /* OPCODE 0011 */ 161,168, 162,168, 169,176, 170,176, + /* OPCODE 1011 */ -1, -1, -1, -1, -1, -1, -1, -1, + /* OPCODE 0111 */ -1, -1, -1, -1, -1, -1, -1, -1, + /* OPCODE 1111 */ 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* ======================================================================== */ +/* bitrev -- Bit-reverse a 32-bit number. */ +/* ======================================================================== */ +static inline uint32_t +bitrev(uint32_t val) +{ + val = ((val & 0xffff0000) >> 16) | ((val & 0x0000ffff) << 16); + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + val = ((val & 0xf0f0f0f0) >> 4) | ((val & 0x0f0f0f0f) << 4); + val = ((val & 0xcccccccc) >> 2) | ((val & 0x33333333) << 2); + val = ((val & 0xaaaaaaaa) >> 1) | ((val & 0x55555555) << 1); + + return val; +} + +/* ======================================================================== */ +/* sp0256_getb -- Get up to 8 bits at the current PC. */ +/* ======================================================================== */ +static uint32_t +sp0256_getb(sp0256_t *s, int len) +{ + uint32_t data = 0; + uint32_t d0, d1; + + /* -------------------------------------------------------------------- */ + /* Fetch data from the FIFO or from the MASK */ + /* -------------------------------------------------------------------- */ + if (s->fifo_sel) { + d0 = s->fifo[(s->fifo_tail ) & 63]; + d1 = s->fifo[(s->fifo_tail + 1) & 63]; + + data = ((d1 << 10) | d0) >> s->fifo_bitp; + +#ifdef DEBUG_FIFO + dfprintf(("SP0256: RD_FIFO %.3X %d.%d %d\n", data & ((1 << len) - 1), + s->fifo_tail, s->fifo_bitp, s->fifo_head)); +#endif + + /* ---------------------------------------------------------------- */ + /* Note the PC doesn't advance when we execute from FIFO. */ + /* Just the FIFO's bit-pointer advances. (That's not REALLY */ + /* what happens, but that's roughly how it behaves.) */ + /* ---------------------------------------------------------------- */ + s->fifo_bitp += len; + if (s->fifo_bitp >= 10) { + s->fifo_tail++; + s->fifo_bitp -= 10; + } + } else { + /* ---------------------------------------------------------------- */ + /* Figure out which ROMs are being fetched into, and grab two */ + /* adjacent bytes. The byte we're interested in is extracted */ + /* from the appropriate bit-boundary between them. */ + /* ---------------------------------------------------------------- */ + int idx0 = (s->pc ) >> 3, page0 = idx0 >> 12; + int idx1 = (s->pc + 8) >> 3, page1 = idx1 >> 12; + + idx0 &= 0xfff; + idx1 &= 0xfff; + + d0 = d1 = 0; + + if (s->rom[page0]) d0 = s->rom[page0][idx0]; + if (s->rom[page1]) d1 = s->rom[page1][idx1]; + + data = ((d1 << 8) | d0) >> (s->pc & 7); + + s->pc += len; + } + + /* -------------------------------------------------------------------- */ + /* Mask data to the requested length. */ + /* -------------------------------------------------------------------- */ + data &= ((1 << len) - 1); + + return data; +} + +/* ======================================================================== */ +/* sp0256_micro -- Emulate the microsequencer in the SP0256. Executes */ +/* instructions either until the repeat count != 0 or */ +/* the sequencer gets halted by a RTS to 0. */ +/* ======================================================================== */ +static void +sp0256_micro(sp0256_t *s) +{ + uint8_t immed4; + uint8_t opcode; + uint16_t cr; + int ctrl_xfer = 0; + int repeat = 0; + int i, idx0, idx1; + + /* -------------------------------------------------------------------- */ + /* Only execute instructions while the filter is not busy. */ + /* -------------------------------------------------------------------- */ + while (s->filt.rpt <= 0 && s->filt.cnt <= 0) { + /* ---------------------------------------------------------------- */ + /* If the CPU is halted, see if we have a new command pending */ + /* in the Address LoaD buffer. */ + /* ---------------------------------------------------------------- */ + if (s->halted && !s->lrq) { + s->pc = s->ald | (0x1000 << 3); + s->fifo_sel = 0; + s->halted = 0; + s->lrq = 1; + s->ald = 0; +/* for (i = 0; i < 16; i++)*/ +/* s->filt.r[i] = 0;*/ + } + + /* ---------------------------------------------------------------- */ + /* If we're still halted, do nothing. */ + /* ---------------------------------------------------------------- */ + if (s->halted) { + s->filt.rpt = 1; + s->filt.cnt = 0; + s->lrq = 1; + s->ald = 0; +/* for (i = 0; i < 16; i++)*/ +/* s->filt.r[i] = 0;*/ + return; + } + + /* ---------------------------------------------------------------- */ + /* Fetch the first 8 bits of the opcode, which are always in the */ + /* same approximate format -- immed4 followed by opcode. */ + /* ---------------------------------------------------------------- */ + immed4 = sp0256_getb(s, 4); + opcode = sp0256_getb(s, 4); + repeat = 0; + ctrl_xfer = 0; + + debug_printf(("$%.4X.%.1X: OPCODE %d%d%d%d.%d%d\n", + (s->pc >> 3) - 1, s->pc & 7, + !!(opcode & 1), !!(opcode & 2), + !!(opcode & 4), !!(opcode & 8), + !!(s->mode&4), !!(s->mode&2))); + + /* ---------------------------------------------------------------- */ + /* Handle the special cases for specific opcodes. */ + /* ---------------------------------------------------------------- */ + switch (opcode) { + /* ------------------------------------------------------------ */ + /* OPCODE 0000: RTS / SETPAGE */ + /* ------------------------------------------------------------ */ + case 0x0: + /* -------------------------------------------------------- */ + /* If immed4 != 0, then this is a SETPAGE instruction. */ + /* -------------------------------------------------------- */ + if (immed4) { /* SETPAGE */ + s->page = bitrev(immed4) >> 13; + } else { + /* -------------------------------------------------------- */ + /* Otherwise, this is an RTS / HLT. */ + /* -------------------------------------------------------- */ + uint32_t btrg; + + /* ---------------------------------------------------- */ + /* Figure out our branch target. */ + /* ---------------------------------------------------- */ + btrg = s->stack; + + s->stack = 0; + + /* ---------------------------------------------------- */ + /* If the branch target is zero, this is a HLT. */ + /* Otherwise, it's an RTS, so set the PC. */ + /* ---------------------------------------------------- */ + if (!btrg) { + s->halted = 1; + s->pc = 0; + ctrl_xfer = 1; + } else { + s->pc = btrg; + ctrl_xfer = 1; + } + } + + break; + + /* ------------------------------------------------------------ */ + /* OPCODE 0111: JMP Jump to 12-bit/16-bit Abs Addr */ + /* OPCODE 1011: JSR Jump to Subroutine */ + /* ------------------------------------------------------------ */ + case 0xe: + case 0xd: + { + int btrg; + + /* -------------------------------------------------------- */ + /* Figure out our branch target. */ + /* -------------------------------------------------------- */ + btrg = s->page | + (bitrev(immed4) >> 17) | + (bitrev(sp0256_getb(s, 8)) >> 21); + ctrl_xfer = 1; + + /* -------------------------------------------------------- */ + /* If this is a JSR, push our return address on the */ + /* stack. Make sure it's byte aligned. */ + /* -------------------------------------------------------- */ + if (opcode == 0xd) + s->stack = (s->pc + 7) & ~7; + + /* -------------------------------------------------------- */ + /* Jump to the new location! */ + /* -------------------------------------------------------- */ + s->pc = btrg; + break; + } + + /* ------------------------------------------------------------ */ + /* OPCODE 1000: SETMODE Set the Mode and Repeat MSBs */ + /* ------------------------------------------------------------ */ + case 0x1: + s->mode = ((immed4 & 8) >> 2) | (immed4 & 4) | + ((immed4 & 3) << 4); + break; + + /* ------------------------------------------------------------ */ + /* OPCODE 0001: LOADALL Load All Parameters */ + /* OPCODE 0010: LOAD_2 Load Per, Ampl, Coefs, Interp. */ + /* OPCODE 0011: SETMSB_3 Load Pitch, Ampl, MSBs, & Intrp */ + /* OPCODE 0100: LOAD_4 Load Pitch, Ampl, Coeffs */ + /* OPCODE 0101: SETMSB_5 Load Pitch, Ampl, and Coeff MSBs */ + /* OPCODE 0110: SETMSB_6 Load Ampl, and Coeff MSBs. */ + /* OPCODE 1001: DELTA_9 Delta update Ampl, Pitch, Coeffs */ + /* OPCODE 1010: SETMSB_A Load Ampl and MSBs of 3 Coeffs */ + /* OPCODE 1100: LOAD_C Load Pitch, Ampl, Coeffs */ + /* OPCODE 1101: DELTA_D Delta update Ampl, Pitch, Coeffs */ + /* OPCODE 1110: LOAD_E Load Pitch, Amplitude */ + /* OPCODE 1111: PAUSE Silent pause */ + /* ------------------------------------------------------------ */ + default: + repeat = immed4 | (s->mode & 0x30); + break; + } + if (opcode != 1) s->mode &= 0xf; + + /* ---------------------------------------------------------------- */ + /* If this was a control transfer, handle setting "fifo_sel" */ + /* and all that ugliness. */ + /* ---------------------------------------------------------------- */ + if (ctrl_xfer) { + debug_printf(("jumping to $%.4X.%.1X: ", s->pc >> 3, s->pc & 7)); + + /* ------------------------------------------------------------ */ + /* Set our "FIFO Selected" flag based on whether we're going */ + /* to the FIFO's address. */ + /* ------------------------------------------------------------ */ + s->fifo_sel = s->pc == FIFO_ADDR; + + debug_printf(("%s ", s->fifo_sel ? "FIFO" : "ROM")); + + /* ------------------------------------------------------------ */ + /* Control transfers to the FIFO cause it to discard the */ + /* partial decle that's at the front of the FIFO. */ + /* ------------------------------------------------------------ */ + if (s->fifo_sel && s->fifo_bitp) { + debug_printf(("bitp = %d -> Flush", s->fifo_bitp)); + + /* Discard partially-read decle. */ + if (s->fifo_tail < s->fifo_head) s->fifo_tail++; + s->fifo_bitp = 0; + } + + debug_printf(("\n")); + + continue; + } + + /* ---------------------------------------------------------------- */ + /* Otherwise, if we have a repeat count, then go grab the data */ + /* block and feed it to the filter. */ + /* ---------------------------------------------------------------- */ + if (!repeat) continue; + + s->filt.rpt = repeat; + debug_printf(("repeat = %d\n", repeat)); + + /* clear delay line on new opcode */ + for (i = 0; i < 6; i++) + s->filt.z_data[i][0] = s->filt.z_data[i][1] = 0; + + i = (opcode << 3) | (s->mode & 6); + idx0 = sp0256_df_idx[i++]; + idx1 = sp0256_df_idx[i ]; + + assert(idx0 >= 0 && idx1 >= 0 && idx1 >= idx0); + + /* ---------------------------------------------------------------- */ + /* If we're in one of the 10-pole modes (x0), clear F5/B5. */ + /* ---------------------------------------------------------------- */ + if ((s->mode & 2) == 0) + s->filt.r[F5] = s->filt.r[B5] = 0; + + + /* ---------------------------------------------------------------- */ + /* Step through control words in the description for data block. */ + /* ---------------------------------------------------------------- */ + for (i = idx0; i <= idx1; i++) { + int len, shf, delta, field, prm, clrL; + libspectrum_signed_byte value; + + /* ------------------------------------------------------------ */ + /* Get the control word and pull out some important fields. */ + /* ------------------------------------------------------------ */ + cr = sp0256_datafmt[i]; + + len = CR_LEN(cr); + shf = CR_SHF(cr); + prm = CR_PRM(cr); + clrL = cr & CR_CLRL; + delta = cr & CR_DELTA; + field = cr & CR_FIELD; + value = 0; + + debug_printf(("$%.4X.%.1X: len=%2d shf=%2d prm=%2d d=%d f=%d ", + s->pc >> 3, s->pc & 7, len, shf, prm, !!delta, !!field)); + /* ------------------------------------------------------------ */ + /* Clear any registers that were requested to be cleared. */ + /* ------------------------------------------------------------ */ + if (clrL) + { + s->filt.r[F0] = s->filt.r[B0] = 0; + s->filt.r[F1] = s->filt.r[B1] = 0; + s->filt.r[F2] = s->filt.r[B2] = 0; + } + + /* ------------------------------------------------------------ */ + /* If this entry has a bitfield with it, grab the bitfield. */ + /* ------------------------------------------------------------ */ + if (len) { + value = sp0256_getb(s, len); + } else { + debug_printf((" (no update)\n")); + continue; + } + + /* ------------------------------------------------------------ */ + /* Sign extend if this is a delta update. */ + /* ------------------------------------------------------------ */ + if (delta) { /* Sign extend */ + if (value & (1 << (len - 1))) value |= -1 << len; + } + + /* ------------------------------------------------------------ */ + /* Shift the value to the appropriate precision. */ + /* ------------------------------------------------------------ */ + if (shf) { + value <<= shf; + } + + debug_printf(("v=%.2X (%c%.2X) ", value & 0xff, + value & 0x80 ? '-' : '+', + 0xff & (value & 0x80 ? -value : value))); + + s->silent = 0; + + /* ------------------------------------------------------------ */ + /* If this is a field-replace, insert the field. */ + /* ------------------------------------------------------------ */ + if (field) { + debug_printf(("--field-> r[%2d] = %.2X -> ", prm, + s->filt.r[prm])); + + s->filt.r[prm] &= ~(~0 << shf); /* Clear the old bits. */ + s->filt.r[prm] |= value; /* Merge in the new bits. */ + + debug_printf(("%.2X\n", s->filt.r[prm])); + + continue; + } + + /* ------------------------------------------------------------ */ + /* If this is a delta update, add to the appropriate field. */ + /* ------------------------------------------------------------ */ + if (delta) { + debug_printf(("--delta-> r[%2d] = %.2X -> ", prm, + s->filt.r[prm])); + + s->filt.r[prm] += value; + + debug_printf(("%.2X\n", s->filt.r[prm])); + + continue; + } + + /* ------------------------------------------------------------ */ + /* Otherwise, just write the new value. */ + /* ------------------------------------------------------------ */ + s->filt.r[prm] = value; + debug_printf(("--value-> r[%2d] = %.2X\n", prm, s->filt.r[prm])); + } + + /* ---------------------------------------------------------------- */ + /* Most opcodes clear IA, IP. */ + /* ---------------------------------------------------------------- */ + if (opcode != 0x1 && opcode != 0x2 && opcode != 0x3) + { + s->filt.r[IA] = 0; + s->filt.r[IP] = 0; + } + + /* ---------------------------------------------------------------- */ + /* Special case: Set PAUSE's equivalent period. */ + /* ---------------------------------------------------------------- */ + if (opcode == 0xf) + { + s->silent = 1; + s->filt.r[AM] = 0; + s->filt.r[PR] = PER_PAUSE; + } + + /* ---------------------------------------------------------------- */ + /* Now that we've updated the registers, go decode them. */ + /* ---------------------------------------------------------------- */ + lpc12_regdec(&s->filt); + + /* ---------------------------------------------------------------- */ + /* Break out since we now have a repeat count. */ + /* ---------------------------------------------------------------- */ + break; + } +} + +/* ======================================================================== */ +/* sp0256_rdrom -- Tries to read a ROM file in the current directory. */ +/* ======================================================================== */ +static int +sp0256_rdrom(sp0256_t *s, int page) +{ + uint8_t *rom; + char buf[32]; + FILE *f; + + /* -------------------------------------------------------------------- */ + /* Generate a file name, and then see if it exists. ... [truncated message content] |
From: <sba...@us...> - 2023-07-19 17:46:22
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a change to branch patches-142-currah-uspeech in repository fuse. at b5830f37 Document SP0256 ROM option and uSpeech memory source This branch includes the following new commits: new e09eeec1 Initial support for Currah uSpeech peripheral new 8fd74510 Add UI elements to manage SP0256 ROM file location new 32768808 Enhanced Currah uSpeech paging logic: - Memory read/write at 0x38 should page the ROM in/out - ROM is mapped to the first 4 Kb only new a263ed4d Enable snapshot support for Currah uSpeech new b5830f37 Document SP0256 ROM option and uSpeech memory source The 5 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "add" were already present in the repository and have only been added to this reference. |
From: <sba...@us...> - 2023-07-19 17:45:12
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch patches-142-currah-uspeech in repository libspectrum. View the commit online: https://sourceforge.net/p/fuse-emulator/libspectrum/ci/1ec4c7dab04bf9240e405258854bfec858be500f/ commit 1ec4c7dab04bf9240e405258854bfec858be500f Author: Sergio Baldoví <ser...@gm...> AuthorDate: Wed Jul 19 19:19:44 2023 +0200 Note info loss of uSpeech when writing dsnap, sna or z80 snapshots --- doc/libspectrum.txt | 3 +++ dsnap.c | 4 ++++ sna.c | 4 ++++ z80.c | 4 ++++ 4 files changed, 15 insertions(+) diff --git a/doc/libspectrum.txt b/doc/libspectrum.txt index adbe594..9c80a48 100644 --- a/doc/libspectrum.txt +++ b/doc/libspectrum.txt @@ -729,6 +729,9 @@ The available properties (along with their types) are: * libspectrum_byte* usource_rom[1] * size_t usource_rom_length[1] +* int uspeech_active +* int uspeech_paged + * int disciple_active * int disciple_paged * int disciple_inhibit_button diff --git a/dsnap.c b/dsnap.c index e7446bb..51f57eb 100644 --- a/dsnap.c +++ b/dsnap.c @@ -306,6 +306,10 @@ libspectrum_dsnap_write( libspectrum_buffer *buffer, int *out_flags, if( libspectrum_snap_usource_active( snap ) ) *out_flags |= LIBSPECTRUM_FLAG_SNAPSHOT_MAJOR_INFO_LOSS; + /* We don't save the uSpeech state at all */ + if( libspectrum_snap_uspeech_active( snap ) ) + *out_flags |= LIBSPECTRUM_FLAG_SNAPSHOT_MAJOR_INFO_LOSS; + /* We don't save the DISCiPLE state at all */ if( libspectrum_snap_disciple_active( snap ) ) *out_flags |= LIBSPECTRUM_FLAG_SNAPSHOT_MAJOR_INFO_LOSS; diff --git a/sna.c b/sna.c index 7a4b193..08b14cc 100644 --- a/sna.c +++ b/sna.c @@ -335,6 +335,10 @@ libspectrum_sna_write( libspectrum_buffer *buffer, int *out_flags, if( libspectrum_snap_usource_active( snap ) ) *out_flags |= LIBSPECTRUM_FLAG_SNAPSHOT_MAJOR_INFO_LOSS; + /* We don't save the uSpeech state at all */ + if( libspectrum_snap_uspeech_active( snap ) ) + *out_flags |= LIBSPECTRUM_FLAG_SNAPSHOT_MAJOR_INFO_LOSS; + /* We don't save the DISCiPLE state at all */ if( libspectrum_snap_disciple_active( snap ) ) *out_flags |= LIBSPECTRUM_FLAG_SNAPSHOT_MAJOR_INFO_LOSS; diff --git a/z80.c b/z80.c index f7985f1..5cce467 100644 --- a/z80.c +++ b/z80.c @@ -1179,6 +1179,10 @@ libspectrum_z80_write2( libspectrum_buffer *buffer, int *out_flags, if( libspectrum_snap_usource_active( snap ) ) *out_flags |= LIBSPECTRUM_FLAG_SNAPSHOT_MAJOR_INFO_LOSS; + /* .z80 format doesn't save the uSpeech state at all */ + if( libspectrum_snap_uspeech_active( snap ) ) + *out_flags |= LIBSPECTRUM_FLAG_SNAPSHOT_MAJOR_INFO_LOSS; + /* .z80 format doesn't save the DISCiPLE state well but we don't support what is there either */ if( libspectrum_snap_disciple_active( snap ) ) |
From: <sba...@us...> - 2023-07-19 17:45:10
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch patches-142-currah-uspeech in repository libspectrum. View the commit online: https://sourceforge.net/p/fuse-emulator/libspectrum/ci/88532dba809ca33611b726f854587f917cac6604/ commit 88532dba809ca33611b726f854587f917cac6604 Author: Vic Chwe <ch...@us...> AuthorDate: Wed Jul 19 19:04:49 2023 +0200 Enable SZX support for Currah uSpeech --- snap_accessors.txt | 4 ++++ szx.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/snap_accessors.txt b/snap_accessors.txt index fb1d2a0..5d0cf78 100644 --- a/snap_accessors.txt +++ b/snap_accessors.txt @@ -241,6 +241,10 @@ int usource_custom_rom libspectrum_byte* usource_rom 1 size_t usource_rom_length 1 /* Length of the ROM */ +/* uSpeech emulation */ +int uspeech_active +int uspeech_paged + /* DISCiPLE emulation */ int disciple_active int disciple_paged diff --git a/szx.c b/szx.c index 5889de8..761801d 100644 --- a/szx.c +++ b/szx.c @@ -338,6 +338,9 @@ write_mfce_chunk( libspectrum_buffer *buffer, libspectrum_buffer *data, static void write_zmmc_chunk( libspectrum_buffer *buffer, libspectrum_buffer *data, libspectrum_snap *snap ); +static void +write_uspeech_chunk( libspectrum_buffer *buffer, libspectrum_buffer *data, + libspectrum_snap *snap ); #ifdef HAVE_ZLIB_H @@ -2443,6 +2446,30 @@ read_zmmc_chunk( libspectrum_snap *snap, libspectrum_word version GCC_UNUSED, return LIBSPECTRUM_ERROR_NONE; } +static libspectrum_error +read_uspeech_chunk( libspectrum_snap *snap, libspectrum_word version GCC_UNUSED, + const libspectrum_byte **buffer, + const libspectrum_byte *end GCC_UNUSED, size_t data_length, + szx_context *ctx GCC_UNUSED ) +{ + libspectrum_byte paged; + + if( data_length != 1 ) { + libspectrum_print_error( LIBSPECTRUM_ERROR_UNKNOWN, + "%s:read_uspeech_chunk: unknown length %lu", + __FILE__, (unsigned long)data_length ); + return LIBSPECTRUM_ERROR_UNKNOWN; + } + + paged = *(*buffer)++; + + libspectrum_snap_set_uspeech_paged( snap, paged ); + + libspectrum_snap_set_uspeech_active( snap, 1 ); + + return LIBSPECTRUM_ERROR_NONE; +} + static libspectrum_error skip_chunk( libspectrum_snap *snap GCC_UNUSED, libspectrum_word version GCC_UNUSED, @@ -2501,7 +2528,7 @@ static struct read_chunk_t read_chunks[] = { { ZXSTBID_SPECTRANETFLASHPAGE, read_snef_chunk }, { ZXSTBID_SPECTRANETRAMPAGE, read_sner_chunk }, { ZXSTBID_TIMEXREGS, read_scld_chunk }, - { ZXSTBID_USPEECH, skip_chunk }, + { ZXSTBID_USPEECH, read_uspeech_chunk }, { ZXSTBID_Z80REGS, read_z80r_chunk }, { ZXSTBID_ZXATASPRAMPAGE, read_atrp_chunk }, { ZXSTBID_ZXATASP, read_zxat_chunk }, @@ -2920,6 +2947,10 @@ libspectrum_szx_write( libspectrum_buffer *buffer, int *out_flags, write_zmmc_chunk( buffer, block_data, snap ); } + if( libspectrum_snap_uspeech_active( snap ) ) { + write_uspeech_chunk( buffer, block_data, snap ); + } + libspectrum_buffer_free( block_data ); return LIBSPECTRUM_ERROR_NONE; @@ -4157,6 +4188,16 @@ write_zmmc_chunk( libspectrum_buffer *buffer, libspectrum_buffer *data, write_chunk( buffer, ZXSTBID_ZXMMC, NULL ); } +static void +write_uspeech_chunk( libspectrum_buffer *buffer, libspectrum_buffer *data, + libspectrum_snap *snap ) +{ + libspectrum_buffer_write_byte( data, + libspectrum_snap_uspeech_paged( snap ) ); + + write_chunk( buffer, ZXSTBID_USPEECH, data ); +} + static void write_chunk( libspectrum_buffer *buffer, const char *id, libspectrum_buffer *block_data ) |
From: <sba...@us...> - 2023-07-19 17:45:09
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a change to branch patches-142-currah-uspeech in repository libspectrum. at 1ec4c7d Note info loss of uSpeech when writing dsnap, sna or z80 snapshots This branch includes the following new commits: new 88532db Enable SZX support for Currah uSpeech new 1ec4c7d Note info loss of uSpeech when writing dsnap, sna or z80 snapshots The 2 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "add" were already present in the repository and have only been added to this reference. |
From: <sba...@us...> - 2023-06-11 19:43:11
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch master in repository libspectrum. View the commit online: https://sourceforge.net/p/fuse-emulator/libspectrum/ci/6510b05823d1468140f6a9ed8e353c9d3a823f44/ commit 6510b05823d1468140f6a9ed8e353c9d3a823f44 Author: Sergio Baldoví <ser...@gm...> AuthorDate: Sun Jun 11 21:42:04 2023 +0200 Fix RZX recording in competition mode libgcrypt since version 1.5 neeed to use unsigned format for gcry_sexp_nth_mpi() (bug #485) (thanks, crem). --- crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto.c b/crypto.c index 580a6cb..0441e2b 100644 --- a/crypto.c +++ b/crypto.c @@ -232,7 +232,7 @@ get_mpi( gcry_mpi_t *mpi, gcry_sexp_t sexp, const char *token ) return LIBSPECTRUM_ERROR_LOGIC; } - *mpi = gcry_sexp_nth_mpi( pair, 1, GCRYMPI_FMT_STD ); + *mpi = gcry_sexp_nth_mpi( pair, 1, GCRYMPI_FMT_USG ); if( !(*mpi) ) { libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC, "get_mpis: couldn't create MPI '%s'", token ); |
From: <sba...@us...> - 2023-06-11 19:43:09
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch master in repository libspectrum. View the commit online: https://sourceforge.net/p/fuse-emulator/libspectrum/ci/40115c72a5db73ececeeb97e956e8392eb68aee1/ commit 40115c72a5db73ececeeb97e956e8392eb68aee1 Author: Sergio Baldoví <ser...@gm...> AuthorDate: Sun Jun 11 21:21:32 2023 +0200 Fix function prototypes due to enum/integer mismatch --- internals.h | 5 +++-- zip.c | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/internals.h b/internals.h index 02957d4..8f799f7 100644 --- a/internals.h +++ b/internals.h @@ -150,8 +150,9 @@ extern const char * const libspectrum_tzx_signature; /* Convert a 48K memory dump into separate RAM pages */ -int libspectrum_split_to_48k_pages( libspectrum_snap *snap, - const libspectrum_byte* data ); +libspectrum_error +libspectrum_split_to_48k_pages( libspectrum_snap *snap, + const libspectrum_byte* data ); /* Sizes of some of the arrays in the snap structure */ #define SNAPSHOT_RAM_PAGES 16 diff --git a/zip.c b/zip.c index 826dfff..a98b779 100644 --- a/zip.c +++ b/zip.c @@ -355,16 +355,16 @@ dump_entry_stat( struct libspectrum_zip *z, zip_stat *info ) } /* Jump to next entry in the archive */ -int +libspectrum_error libspectrum_zip_next( struct libspectrum_zip *z, zip_stat *info ) { - if( !z || z->state == ARCHIVE_CLOSED ) return 1; + if( !z || z->state == ARCHIVE_CLOSED ) return LIBSPECTRUM_ERROR_UNKNOWN; - if( read_directory( z ) ) return 1; + if( read_directory( z ) ) return LIBSPECTRUM_ERROR_UNKNOWN; dump_entry_stat( z, info ); - return 0; + return LIBSPECTRUM_ERROR_NONE; } /* Locate a file in the archive (non-sequential acces) */ |
From: <sba...@us...> - 2023-06-11 19:43:08
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a change to branch master in repository libspectrum. from 97175c3 Move "for" loop initial declaration new 40115c7 Fix function prototypes due to enum/integer mismatch new 6510b05 Fix RZX recording in competition mode The 2 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "add" were already present in the repository and have only been added to this reference. Summary of changes: crypto.c | 2 +- internals.h | 5 +++-- zip.c | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) |
From: <sba...@us...> - 2023-06-11 18:56:25
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch master in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/81efcbce8fdc515c18faf1e854a78d77bb0f676f/ The following commit(s) were added to refs/heads/master by this push: new 81efcbce Reset machine when enabling/disabling a sound peripheral 81efcbce is described below commit 81efcbce8fdc515c18faf1e854a78d77bb0f676f Author: Sergio Baldoví <ser...@gm...> AuthorDate: Sun Jun 11 20:55:15 2023 +0200 Reset machine when enabling/disabling a sound peripheral that requires it --- ui/options.dat | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/options.dat b/ui/options.dat index 82f66925..d99a839f 100644 --- a/ui/options.dat +++ b/ui/options.dat @@ -116,6 +116,8 @@ Checkbox, (F)uller Box, fuller, INPUT_KEY_f Checkbox, M(e)lodik, melodik, INPUT_KEY_e Checkbox, Spec(D)rum interface, specdrum, INPUT_KEY_d Checkbox, C(o)vox interface, covox, INPUT_KEY_o +Postcheck, periph_postcheck +Posthook, periph_posthook peripherals_disk Disk Peripheral Options |
From: <sba...@us...> - 2023-06-10 04:21:46
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch master in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/2ff7ebb86858931f41d191a7cf9f54bfafa0ce9a/ commit 2ff7ebb86858931f41d191a7cf9f54bfafa0ce9a Author: Sergio Baldoví <ser...@gm...> AuthorDate: Sat Jun 10 06:20:07 2023 +0200 Document Sound Peripherals Options dialog --- man/fuse.1 | 70 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/man/fuse.1 b/man/fuse.1 index 1b5fbab9..952aaeb2 100644 --- a/man/fuse.1 +++ b/man/fuse.1 @@ -212,7 +212,7 @@ option. .B \-\-covox .RS Emulate a Covox sound interface for Pentagon/Scorpion. Same as the -General Peripherals Options dialog's +Sound Peripherals Options dialog's .I "Covox" option. .RE @@ -472,7 +472,7 @@ are `320' (which corresponds to a 320\(mu240\(mu256 mode), the default and .PP .B \-\-fuller .RS -Emulate a Fuller Box interface. Same as the General Peripherals Options dialog's +Emulate a Fuller Box interface. Same as the Sound Peripherals Options dialog's .I "Fuller Box" option. .RE @@ -838,7 +838,7 @@ and .B \-\-melodik .RS Emulate a Melodik AY\ interface for 16/48k\ Spectrums. Same as the -General Peripherals Options dialog's +Sound Peripherals Options dialog's .I "Melodik" option. .RE @@ -1775,7 +1775,7 @@ Specify the TAP device to use for SpeccyBoot emulation. .PP .B \-\-specdrum .RS -Emulate a SpecDrum interface. Same as the General Peripherals Options dialog's +Emulate a SpecDrum interface. Same as the Sound Peripherals Options dialog's .I "SpecDrum" option. See the World of Spectrum Infoseek web page at .I http://www.worldofspectrum.org/infoseekid.cgi?id=1000062 @@ -2721,21 +2721,6 @@ If this option is enabled, the left and right mouse buttons will be swapped when emulating a Kempston mouse. .RE .PP -.I "Fuller Box" -.RS -If this option is selected, Fuse will emulate a Fuller Box AY sound and -joystick interface. This emulation is only available for the 16k, 48k and -TC2048 machines. -.RE -.PP -.I "Melodik" -.RS -If this option is selected, Fuse will emulate a Melodik AY sound interface. -These interfaces and many similar ones were produced to make the 48K\ Spectrum -compatible with the same AY music as the 128K\ Spectrum. This emulation is only -available for the 16k, 48k and TC2048 machines. -.RE -.PP .I "Interface\ 1" .RS If this option is selected, Fuse will emulate the simple Sinclair @@ -2804,15 +2789,6 @@ web page at for more details. .RE .PP -.I "SpecDrum interface" -.RS -If this option is selected, Fuse will emulate a Cheetah SpecDrum sound -interface. See the World of Spectrum Infoseek web page at -.I http://www.worldofspectrum.org/infoseekid.cgi?id=1000062 -for manuals, software and more. This emulation is only available for -the 48k, 128k and TC2048 machines. -.RE -.PP .I "Spectranet" .RS If this option is selected, Fuse will emulate the Spectranet interface, @@ -2844,6 +2820,20 @@ See the World of Spectrum Infoseek web page at .I http://www.worldofspectrum.org/infoseekid.cgi?id=1000080 for the manual. .RE +.RE +.PP +.I "Options, Peripherals, Sound..." +.RS +Display the Sound Peripherals Options dialog, letting you configure the +sound interface peripherals which Fuse will consider to be attached to +the emulated machine. (With the widget UI, the keys shown in brackets +toggle the options, +.I Enter +confirms any changes, and +.I Esc +aborts). Note that any changed settings only apply to the +currently-running Fuse. Also note that any changes that enable and disable +peripherals may result in a hard reset of the emulated machine. .PP .I "Covox interface" .RS @@ -2852,6 +2842,30 @@ interface. This emulation is only available for the Pentagon, Pentagon 512k, Pentagon 1024k and Scorpion machines. The Pentagon variants use port 0xfb and the Scorpion version uses port 0xdd. .RE +.PP +.I "Fuller Box" +.RS +If this option is selected, Fuse will emulate a Fuller Box AY sound and +joystick interface. This emulation is only available for the 16k, 48k and +TC2048 machines. +.RE +.PP +.I "Melodik" +.RS +If this option is selected, Fuse will emulate a Melodik AY sound interface. +These interfaces and many similar ones were produced to make the 48K\ Spectrum +compatible with the same AY music as the 128K\ Spectrum. This emulation is only +available for the 16k, 48k and TC2048 machines. +.RE +.PP +.I "SpecDrum interface" +.RS +If this option is selected, Fuse will emulate a Cheetah SpecDrum sound +interface. See the World of Spectrum Infoseek web page at +.I http://www.worldofspectrum.org/infoseekid.cgi?id=1000062 +for manuals, software and more. This emulation is only available for +the 48k, 128k and TC2048 machines. +.RE .RE .PP .I "Options, Peripherals, Disk..." |
From: <sba...@us...> - 2023-06-10 04:21:45
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch master in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/69a847ad7f9be6b80355b735484f7af0f5c52d33/ commit 69a847ad7f9be6b80355b735484f7af0f5c52d33 Merge: adf05c4f 10d667dc Author: Sergio Baldoví <ser...@gm...> AuthorDate: Sat Jun 10 06:13:34 2023 +0200 Merge request #20: Move sound peripherals into its own menu fuse.c | 6 +++--- machine.h | 6 +++--- menu.h | 1 + menu_data.dat | 1 + peripherals/Makefile.am | 20 ++++++++++---------- peripherals/{ => sound}/ay.c | 2 +- peripherals/{ => sound}/ay.h | 0 peripherals/{ => sound}/covox.c | 0 peripherals/{ => sound}/covox.h | 0 peripherals/{ => sound}/fuller.c | 2 +- peripherals/{ => sound}/fuller.h | 0 peripherals/{ => sound}/melodik.c | 0 peripherals/{ => sound}/melodik.h | 0 peripherals/{ => sound}/specdrum.c | 0 peripherals/{ => sound}/specdrum.h | 0 ui/options.dat | 11 +++++++---- ui/widget/menu.c | 6 ++++++ ui/widget/widget.c | 1 + ui/widget/widget.h | 7 +++++++ 19 files changed, 41 insertions(+), 22 deletions(-) |
From: <sba...@us...> - 2023-06-10 04:21:44
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch master in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/10d667dc7e5b4f1b3f63b8f94ff724b6c81c8d85/ commit 10d667dc7e5b4f1b3f63b8f94ff724b6c81c8d85 Author: Miroslav Ďurčík <743...@us...> AuthorDate: Thu Apr 27 22:09:45 2023 +0200 feat: Move sound peripherals into its own menu "Peripherals/Sound" Created separate menu for sound peripherals, moved 4 devices there. Moved sound related peripherals' source files into standalone folder (like disk related stuff is in) See more https://sourceforge.net/u/arki55/tickets/4/ --- fuse.c | 6 +++--- machine.h | 6 +++--- menu.h | 1 + menu_data.dat | 1 + peripherals/Makefile.am | 20 ++++++++++---------- peripherals/{ => sound}/ay.c | 2 +- peripherals/{ => sound}/ay.h | 0 peripherals/{ => sound}/covox.c | 0 peripherals/{ => sound}/covox.h | 0 peripherals/{ => sound}/fuller.c | 2 +- peripherals/{ => sound}/fuller.h | 0 peripherals/{ => sound}/melodik.c | 0 peripherals/{ => sound}/melodik.h | 0 peripherals/{ => sound}/specdrum.c | 0 peripherals/{ => sound}/specdrum.h | 0 ui/options.dat | 11 +++++++---- ui/widget/menu.c | 6 ++++++ ui/widget/widget.c | 1 + ui/widget/widget.h | 7 +++++++ 19 files changed, 41 insertions(+), 22 deletions(-) diff --git a/fuse.c b/fuse.c index 8ecfb260..29b5e56c 100644 --- a/fuse.c +++ b/fuse.c @@ -65,12 +65,13 @@ #include "module.h" #include "movie.h" #include "mempool.h" -#include "peripherals/ay.h" #include "peripherals/dck.h" +#include "peripherals/sound/ay.h" +#include "peripherals/sound/fuller.h" +#include "peripherals/sound/melodik.h" #include "peripherals/disk/beta.h" #include "peripherals/disk/didaktik.h" #include "peripherals/disk/fdd.h" -#include "peripherals/fuller.h" #include "peripherals/ide/divide.h" #include "peripherals/ide/divmmc.h" #include "peripherals/ide/simpleide.h" @@ -81,7 +82,6 @@ #include "peripherals/if1.h" #include "peripherals/if2.h" #include "peripherals/kempmouse.h" -#include "peripherals/melodik.h" #include "peripherals/multiface.h" #include "peripherals/printer.h" #include "peripherals/scld.h" diff --git a/machine.h b/machine.h index 1afd4d4f..4cd1acc8 100644 --- a/machine.h +++ b/machine.h @@ -29,9 +29,9 @@ #include "libspectrum.h" #include "display.h" -#include "peripherals/ay.h" -#include "peripherals/covox.h" -#include "peripherals/specdrum.h" +#include "peripherals/sound/ay.h" +#include "peripherals/sound/covox.h" +#include "peripherals/sound/specdrum.h" #include "spectrum.h" typedef libspectrum_byte (*spectrum_unattached_port_fn)( void ); diff --git a/menu.h b/menu.h index cb14156f..4740a81e 100644 --- a/menu.h +++ b/menu.h @@ -139,6 +139,7 @@ MENU_CALLBACK( menu_options_general ); MENU_CALLBACK( menu_options_media ); MENU_CALLBACK( menu_options_sound ); MENU_CALLBACK( menu_options_peripherals_general ); +MENU_CALLBACK( menu_options_peripherals_sound ); MENU_CALLBACK( menu_options_peripherals_disk ); MENU_CALLBACK( menu_options_rzx ); MENU_CALLBACK( menu_options_movie ); diff --git a/menu_data.dat b/menu_data.dat index 0c0fa309..42bebe10 100644 --- a/menu_data.dat +++ b/menu_data.dat @@ -81,6 +81,7 @@ Options/_Sound..., Item Options/_Peripherals, Branch Options/Peripherals/_General..., Item +Options/Peripherals/_Sound..., Item Options/Peripherals/_Disk..., Item Options/_RZX..., Item diff --git a/peripherals/Makefile.am b/peripherals/Makefile.am index b9180290..cf9e1325 100644 --- a/peripherals/Makefile.am +++ b/peripherals/Makefile.am @@ -21,24 +21,24 @@ ## E-mail: phi...@sh... fuse_SOURCES += \ - peripherals/ay.c \ - peripherals/covox.c \ peripherals/dck.c \ - peripherals/fuller.c \ peripherals/if1.c \ peripherals/if2.c \ peripherals/joystick.c \ peripherals/kempmouse.c \ - peripherals/melodik.c \ peripherals/multiface.c \ peripherals/printer.c \ peripherals/scld.c \ peripherals/speccyboot.c \ - peripherals/specdrum.c \ peripherals/spectranet.c \ peripherals/ula.c \ peripherals/usource.c \ peripherals/ttx2000s.c \ + peripherals/sound/ay.c \ + peripherals/sound/covox.c \ + peripherals/sound/fuller.c \ + peripherals/sound/melodik.c \ + peripherals/sound/specdrum.c \ peripherals/disk/beta.c \ peripherals/disk/crc.c \ peripherals/disk/didaktik.c \ @@ -71,24 +71,24 @@ fuse_SOURCES += \ endif noinst_HEADERS += \ - peripherals/ay.h \ - peripherals/covox.h \ peripherals/dck.h \ - peripherals/fuller.h \ peripherals/if1.h \ peripherals/if2.h \ peripherals/joystick.h \ peripherals/kempmouse.h \ - peripherals/melodik.h \ peripherals/multiface.h \ peripherals/printer.h \ peripherals/scld.h \ peripherals/speccyboot.h \ - peripherals/specdrum.h \ peripherals/spectranet.h \ peripherals/ula.h \ peripherals/usource.h \ peripherals/ttx2000s.h \ + peripherals/sound/ay.h \ + peripherals/sound/covox.h \ + peripherals/sound/fuller.h \ + peripherals/sound/melodik.h \ + peripherals/sound/specdrum.h \ peripherals/disk/beta.h \ peripherals/disk/crc.h \ peripherals/disk/didaktik.h \ diff --git a/peripherals/ay.c b/peripherals/sound/ay.c similarity index 99% rename from peripherals/ay.c rename to peripherals/sound/ay.c index 7253ed63..04ac83b6 100644 --- a/peripherals/ay.c +++ b/peripherals/sound/ay.c @@ -32,7 +32,7 @@ #include "machine.h" #include "module.h" #include "periph.h" -#include "printer.h" +#include "peripherals/printer.h" #include "psg.h" #include "sound.h" diff --git a/peripherals/ay.h b/peripherals/sound/ay.h similarity index 100% rename from peripherals/ay.h rename to peripherals/sound/ay.h diff --git a/peripherals/covox.c b/peripherals/sound/covox.c similarity index 100% rename from peripherals/covox.c rename to peripherals/sound/covox.c diff --git a/peripherals/covox.h b/peripherals/sound/covox.h similarity index 100% rename from peripherals/covox.h rename to peripherals/sound/covox.h diff --git a/peripherals/fuller.c b/peripherals/sound/fuller.c similarity index 98% rename from peripherals/fuller.c rename to peripherals/sound/fuller.c index d9f8d8f5..6347c7c4 100644 --- a/peripherals/fuller.c +++ b/peripherals/sound/fuller.c @@ -29,7 +29,7 @@ #include "compat.h" #include "fuller.h" #include "infrastructure/startup_manager.h" -#include "joystick.h" +#include "peripherals/joystick.h" #include "module.h" #include "periph.h" #include "settings.h" diff --git a/peripherals/fuller.h b/peripherals/sound/fuller.h similarity index 100% rename from peripherals/fuller.h rename to peripherals/sound/fuller.h diff --git a/peripherals/melodik.c b/peripherals/sound/melodik.c similarity index 100% rename from peripherals/melodik.c rename to peripherals/sound/melodik.c diff --git a/peripherals/melodik.h b/peripherals/sound/melodik.h similarity index 100% rename from peripherals/melodik.h rename to peripherals/sound/melodik.h diff --git a/peripherals/specdrum.c b/peripherals/sound/specdrum.c similarity index 100% rename from peripherals/specdrum.c rename to peripherals/sound/specdrum.c diff --git a/peripherals/specdrum.h b/peripherals/sound/specdrum.h similarity index 100% rename from peripherals/specdrum.h rename to peripherals/sound/specdrum.h diff --git a/ui/options.dat b/ui/options.dat index 450e505d..82f66925 100644 --- a/ui/options.dat +++ b/ui/options.dat @@ -88,8 +88,6 @@ General Peripheral Options Checkbox, (K)empston joystick, joy_kempston, INPUT_KEY_k Checkbox, Kempston (m)ouse, kempston_mouse, INPUT_KEY_m Checkbox, (S)wap mouse buttons, mouse_swap_buttons, INPUT_KEY_s -Checkbox, (F)uller Box, fuller, INPUT_KEY_f -Checkbox, M(e)lodik, melodik, INPUT_KEY_e Checkbox, (I)nterface 1, interface1, INPUT_KEY_i Checkbox, In(t)erface 2, interface2, INPUT_KEY_t Checkbox, Mu(l)tiface One, multiface1, INPUT_KEY_l @@ -101,7 +99,6 @@ Checkbox, (Z)X Printer, zxprinter, INPUT_KEY_z #ifdef BUILD_SPECCYBOOT Checkbox, Speccy(B)oot interface, speccyboot, INPUT_KEY_b #endif -Checkbox, Spec(D)rum interface, specdrum, INPUT_KEY_d #ifdef BUILD_SPECTRANET Checkbox, Spectra(n)et, spectranet, INPUT_KEY_n Checkbox, Spe(c)tranet disable, spectranet_disable, INPUT_KEY_c @@ -110,10 +107,16 @@ Checkbox, Spe(c)tranet disable, spectranet_disable, INPUT_KEY_c Checkbox, TT(X)2000S, ttx2000s, INPUT_KEY_x #endif Checkbox, uSo(u)rce, usource, INPUT_KEY_u -Checkbox, C(o)vox interface, covox, INPUT_KEY_o Postcheck, periph_postcheck Posthook, periph_posthook +peripherals_sound +Sound Peripheral Options +Checkbox, (F)uller Box, fuller, INPUT_KEY_f +Checkbox, M(e)lodik, melodik, INPUT_KEY_e +Checkbox, Spec(D)rum interface, specdrum, INPUT_KEY_d +Checkbox, C(o)vox interface, covox, INPUT_KEY_o + peripherals_disk Disk Peripheral Options Checkbox, Simple (8)-bit IDE, simpleide_active, INPUT_KEY_8 diff --git a/ui/widget/menu.c b/ui/widget/menu.c index ba22a2c1..b32d6ca4 100644 --- a/ui/widget/menu.c +++ b/ui/widget/menu.c @@ -483,6 +483,12 @@ menu_options_peripherals_general( int action ) widget_do_peripherals_general(); } +void +menu_options_peripherals_sound( int action ) +{ + widget_do_peripherals_sound(); +} + void menu_options_peripherals_disk( int action ) { diff --git a/ui/widget/widget.c b/ui/widget/widget.c index 2689594d..90085eb0 100644 --- a/ui/widget/widget.c +++ b/ui/widget/widget.c @@ -689,6 +689,7 @@ widget_t widget_data[] = { { widget_memory_draw, NULL, widget_memory_keyhandler }, { widget_roms_draw, widget_roms_finish, widget_roms_keyhandler }, { widget_peripherals_general_draw, widget_options_finish, widget_peripherals_general_keyhandler }, + { widget_peripherals_sound_draw, widget_options_finish, widget_peripherals_sound_keyhandler }, { widget_peripherals_disk_draw, widget_options_finish, widget_peripherals_disk_keyhandler }, { widget_query_draw, widget_query_finish, widget_query_keyhandler }, { widget_query_save_draw,widget_query_finish, widget_query_save_keyhandler }, diff --git a/ui/widget/widget.h b/ui/widget/widget.h index 861e598b..63797cb2 100644 --- a/ui/widget/widget.h +++ b/ui/widget/widget.h @@ -56,6 +56,7 @@ typedef enum widget_type { WIDGET_TYPE_MEMORYBROWSER, /* Memory browser widget */ WIDGET_TYPE_ROM, /* ROM selector widget */ WIDGET_TYPE_PERIPHERALS_GENERAL, /* General peripherals options */ + WIDGET_TYPE_PERIPHERALS_SOUND, /* Sound peripherals options */ WIDGET_TYPE_PERIPHERALS_DISK, /* Disk peripherals options */ WIDGET_TYPE_QUERY, /* Query (yes/no) */ WIDGET_TYPE_QUERY_SAVE, /* Query (save/don't save/cancel) */ @@ -244,6 +245,12 @@ static inline int widget_do_peripherals_general( void ) return widget_do( WIDGET_TYPE_PERIPHERALS_GENERAL, NULL ); } +/* Sound peripherals options */ +static inline int widget_do_peripherals_sound( void ) +{ + return widget_do( WIDGET_TYPE_PERIPHERALS_SOUND, NULL ); +} + /* Disk peripherals options */ static inline int widget_do_peripherals_disk( void ) { |
From: <sba...@us...> - 2023-06-10 04:21:42
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a change to branch master in repository fuse. from adf05c4f Remove mime types for img/raw/rom files new 10d667dc feat: Move sound peripherals into its own menu "Peripherals/Sound" new 69a847ad Merge request #20: Move sound peripherals into its own menu new 2ff7ebb8 Document Sound Peripherals Options dialog The 3 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "add" were already present in the repository and have only been added to this reference. Summary of changes: fuse.c | 6 ++-- machine.h | 6 ++-- man/fuse.1 | 70 +++++++++++++++++++++++--------------- menu.h | 1 + menu_data.dat | 1 + peripherals/Makefile.am | 20 +++++------ peripherals/{ => sound}/ay.c | 2 +- peripherals/{ => sound}/ay.h | 0 peripherals/{ => sound}/covox.c | 0 peripherals/{ => sound}/covox.h | 0 peripherals/{ => sound}/fuller.c | 2 +- peripherals/{ => sound}/fuller.h | 0 peripherals/{ => sound}/melodik.c | 0 peripherals/{ => sound}/melodik.h | 0 peripherals/{ => sound}/specdrum.c | 0 peripherals/{ => sound}/specdrum.h | 0 ui/options.dat | 11 +++--- ui/widget/menu.c | 6 ++++ ui/widget/widget.c | 1 + ui/widget/widget.h | 7 ++++ 20 files changed, 83 insertions(+), 50 deletions(-) rename peripherals/{ => sound}/ay.c (99%) rename peripherals/{ => sound}/ay.h (100%) rename peripherals/{ => sound}/covox.c (100%) rename peripherals/{ => sound}/covox.h (100%) rename peripherals/{ => sound}/fuller.c (98%) rename peripherals/{ => sound}/fuller.h (100%) rename peripherals/{ => sound}/melodik.c (100%) rename peripherals/{ => sound}/melodik.h (100%) rename peripherals/{ => sound}/specdrum.c (100%) rename peripherals/{ => sound}/specdrum.h (100%) |
From: <sba...@us...> - 2023-06-10 04:08:28
|
This is an automated email from the git hooks/post-receive-user script. sbaldovi pushed a commit to branch master in repository fuse. View the commit online: https://sourceforge.net/p/fuse-emulator/fuse/ci/adf05c4f559df1caa02816022e3a6442764751d2/ The following commit(s) were added to refs/heads/master by this push: new adf05c4f Remove mime types for img/raw/rom files adf05c4f is described below commit adf05c4f559df1caa02816022e3a6442764751d2 Author: Sergio Baldoví <ser...@gm...> AuthorDate: Sat Jun 10 06:05:29 2023 +0200 Remove mime types for img/raw/rom files as are also commonly used for non ZX Spectrum content and is better to not associate as the preferred application. (more from bug #494) (thanks, Berto). --- data/fuse.xml.in | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/data/fuse.xml.in b/data/fuse.xml.in index e5acf207..14e566a7 100644 --- a/data/fuse.xml.in +++ b/data/fuse.xml.in @@ -44,11 +44,6 @@ <generic-icon name="application-x-spectrum"/> <glob pattern="*.hdf"/> </mime-type> - <mime-type type="application/x-spectrum-img"> - <comment>ZX Spectrum disk</comment> - <generic-icon name="application-x-spectrum"/> - <glob pattern="*.img"/> - </mime-type> <mime-type type="application/x-spectrum-ltp"> <comment>ZX Spectrum tape</comment> <generic-icon name="application-x-spectrum"/> @@ -87,19 +82,6 @@ <generic-icon name="application-x-spectrum"/> <glob pattern="*.pzx"/> </mime-type> - <mime-type type="application/x-spectrum-raw"> - <comment>ZX Spectrum tape</comment> - <magic> - <match type="string" offset="0" value="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0Raw tape sample"/> - </magic> - <generic-icon name="application-x-spectrum"/> - <glob pattern="*.raw"/> - </mime-type> - <mime-type type="application/x-spectrum-rom"> - <comment>ZX Spectrum cartridge</comment> - <generic-icon name="application-x-spectrum"/> - <glob pattern="*.rom"/> - </mime-type> <mime-type type="application/x-spectrum-rzx"> <comment>ZX Spectrum action replay</comment> <magic> |