diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1f2d3e9..83bf2bc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,37 +13,127 @@ on: workflow_dispatch: jobs: - build: + build-fw-hw-sw: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - with: - submodules: true + - name: Download SummerCart64 repository + uses: actions/checkout@v3 - - name: Build script + - name: Set SC64 version + uses: frabert/replace-string-action@v2 + id: sc64version + with: + pattern: '\/' + string: '-${{ github.ref_name }}' + replace-with: '-' + + - name: Build everything run: ./docker_build.sh release --force-clean + env: + SC64_VERSION: ${{ steps.sc64version.outputs.replaced }} - name: Upload artifact uses: actions/upload-artifact@v3 with: - name: SC64 - path: SC64.zip + name: sc64-pkg${{ steps.sc64version.outputs.replaced }} + path: | + sc64-extra${{ steps.sc64version.outputs.replaced }}.zip + sc64-firmware${{ steps.sc64version.outputs.replaced }}.bin - - name: Get release + - name: Upload release assets if: github.event_name == 'release' && github.event.action == 'created' - id: get_release - uses: bruceadams/get-release@v1.3.2 - env: - GITHUB_TOKEN: ${{ github.token }} - - - name: Upload release asset - if: github.event_name == 'release' && github.event.action == 'created' - uses: actions/upload-release-asset@v1 # This will start failing soon due to needing node 12! - env: - GITHUB_TOKEN: ${{ github.token }} + uses: softprops/action-gh-release@v0.1.15 with: - upload_url: ${{ steps.get_release.outputs.upload_url }} - asset_path: SC64.zip - asset_name: SC64.zip - asset_content_type: application/zip + files: | + sc64-extra${{ steps.sc64version.outputs.replaced }}.zip + sc64-firmware${{ steps.sc64version.outputs.replaced }}.bin + + build-sc64-py: + strategy: + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + include: + - os: windows-latest + pyinstaller-build-options: --target-arch=64bit + pyinstaller-options: --onefile --console --icon ../../assets/sc64_logo_256_256.png + package-name: sc64-windows + package-options: -c -a -f + package-extension: zip + + - os: ubuntu-latest + pyinstaller-options: --onefile + package-name: sc64-linux + package-options: -czf + package-extension: tar.gz + + - os: macos-latest + pyinstaller-options: --onedir --console --icon ../../assets/sc64_logo_256_256.png + package-name: sc64-macos + package-options: -czf + package-extension: tgz + + runs-on: ${{ matrix.os }} + + steps: + - name: Download SummerCart64 repository + uses: actions/checkout@v3 + + - name: Set SC64 version + uses: frabert/replace-string-action@v2 + id: sc64version + with: + pattern: '\/' + string: '-${{ github.ref_name }}' + replace-with: '-' + + - name: Setup python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + + - name: Download pyinstaller repository + uses: actions/checkout@v3 + with: + repository: 'pyinstaller/pyinstaller' + ref: 'v5.8.0' + path: pyinstaller + + - name: Compile and install pyinstaller + run: | + pip3 uninstall pyinstaller + pip3 install wheel + pushd bootloader + python3 ./waf all ${{ matrix.pyinstaller-build-options }} + popd + pip3 install . + working-directory: pyinstaller + + - name: Install sc64.py requirements + run: pip3 install -r requirements.txt + working-directory: sw/pc + + - name: Create sc64.py executable + run: python3 -m PyInstaller --clean ${{ matrix.pyinstaller-options }} sc64.py + working-directory: sw/pc + + - name: Package executable + run: | + mkdir package + pushd dist + tar ${{ matrix.package-options }} ../package/${{ matrix.package-name }}${{ steps.sc64version.outputs.replaced }}.${{ matrix.package-extension }} * + popd + working-directory: sw/pc + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.package-name }}${{ steps.sc64version.outputs.replaced }} + path: sw/pc/package/${{ matrix.package-name }}${{ steps.sc64version.outputs.replaced }}.${{ matrix.package-extension }} + + - name: Upload release assets + if: github.event_name == 'release' && github.event.action == 'created' + uses: softprops/action-gh-release@v0.1.15 + with: + files: | + sw/pc/package/${{ matrix.package-name }}${{ steps.sc64version.outputs.replaced }}.${{ matrix.package-extension }} diff --git a/.gitignore b/.gitignore index 68a54dd..e3d7486 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ **/.DS_Store **/.vscode/ **/*.bak +**/*.bin **/*.zip !**/.vscode/tasks.json diff --git a/assets/sc64_logo.blend b/assets/sc64_logo.blend index ecde59d..4bdd9f0 100644 Binary files a/assets/sc64_logo.blend and b/assets/sc64_logo.blend differ diff --git a/assets/sc64_logo_256_256.png b/assets/sc64_logo_256_256.png new file mode 100644 index 0000000..670d1df Binary files /dev/null and b/assets/sc64_logo_256_256.png differ diff --git a/build.sh b/build.sh index c3583d1..efc7260 100755 --- a/build.sh +++ b/build.sh @@ -2,13 +2,13 @@ set -e -PACKAGE_FILE_NAME="SC64" +PACKAGE_FILE_NAME="sc64-extra" TOP_FILES=( "./sw/pc/primer.py" "./sw/pc/requirements.txt" "./sw/pc/sc64.py" - "./sw/update/sc64_firmware.bin" + "./sw/update/sc64-firmware.bin" ) FILES=( @@ -86,7 +86,7 @@ build_update () { pushd sw/update > /dev/null if [ "$FORCE_CLEAN" = true ]; then - rm -f ./sc64_firmware.bin + rm -f ./sc64-firmware.bin fi GIT_INFO="" if [ ! -z "${GIT_BRANCH}" ]; then GIT_INFO+="branch: [$GIT_BRANCH] "; fi @@ -100,7 +100,7 @@ build_update () { --fpga ../../fw/project/lcmxo2/impl1/sc64_impl1.jed \ --boot ../bootloader/build/bootloader.bin \ --primer ../controller/build/primer/primer.bin \ - sc64_firmware.bin + sc64-firmware.bin popd > /dev/null BUILT_UPDATE=true @@ -114,10 +114,12 @@ build_release () { if [ -e "./${PACKAGE_FILE_NAME}.zip" ]; then rm -f "./${PACKAGE_FILE_NAME}.zip" fi - PACKAGE="./${PACKAGE_FILE_NAME}.zip" + PACKAGE="./${PACKAGE_FILE_NAME}${SC64_VERSION}.zip" zip -j -r $PACKAGE ${TOP_FILES[@]} zip -r $PACKAGE ${FILES[@]} + cp sw/update/sc64-firmware.bin ./sc64-firmware${SC64_VERSION}.bin + BUILT_RELEASE=true } diff --git a/docker_build.sh b/docker_build.sh index a8b4a2a..cc795e5 100755 --- a/docker_build.sh +++ b/docker_build.sh @@ -27,6 +27,7 @@ docker run \ -e GIT_TAG="$GIT_TAG" \ -e GIT_SHA="$GIT_SHA" \ -e GIT_MESSAGE="$GIT_MESSAGE" \ + -e SC64_VERSION=${SC64_VERSION:-""} \ $BUILDER_IMAGE \ ./build.sh $@ diff --git a/docs/00_quick_startup_guide.md b/docs/00_quick_startup_guide.md index 7276c02..5e09da6 100644 --- a/docs/00_quick_startup_guide.md +++ b/docs/00_quick_startup_guide.md @@ -12,45 +12,43 @@ ## First time setup -1. Make sure `python3` and `pip3` are installed in your system -2. Grab latest `SC64.zip` package from GitHub releases -3. Extract package contents to a folder -4. Install requirements: `pip3 install -r requirements.txt` -5. Run `python3 sc64.py --help` to check if requirements are installed -6. Run `python3 sc64.py --print-state` to check if SC64 is detected -7. Update firmware if `sc64.py` detects unsupported firmware version +**Windows platform: replace `./sc64` in examples below with `sc64.exe`** + +1. Download the latest `sc64-{os}-{version}.{ext}` (choose OS matching your system) and `sc64-firmware-{version}.bin` from GitHub releases page +2. Extract `sc64-{os}-{version}.{ext}` package contents to a folder and place `sc64-firmware-{version}.bin` inside it +3. Update SC64 firmware to the latest version with `./sc64 --update-firmware sc64-firmware-{version}.bin` +4. Run `./sc64 --print-state` to check if update process finished successfully and SC64 is detected correctly --- ## Firmware backup/update -Keeping SC64 firmware up to date is highly recommended. `sc64.py` script is tightly coupled with specific firmware versions and will error out when it detects unsupported firmware version. +Keeping SC64 firmware up to date is highly recommended. `sc64` executable is tightly coupled with specific firmware versions and will error out when it detects unsupported firmware version. -To download and backup current version of SC64 firmware run `python3 sc64.py --backup-firmware sc64_firmware_backup.bin` +To download and backup current version of SC64 firmware run `./sc64 --backup-firmware sc64-firmware-backup.bin` -To update SC64 firmware run `python3 sc64.py --update-firmware sc64_firmware.bin` +To update SC64 firmware run `./sc64 --update-firmware sc64-firmware-{version}.bin` --- ## Internal flashcart state -SC64 holds some configuration after script has exit. To reset it simply run: `python3 sc64.py --reset-state`. Internal flashcart state can be checked by running: `python3 sc64.py --print-state` +SC64 holds some internal configuration options after `sc64` executable finished running. To reset it simply run: `./sc64 --reset-state`. Internal flashcart state can be checked by running: `./sc64 --print-state` --- ## Uploading game/save -`python3 sc64.py path_to_rom.n64 --save-type eeprom-4k --save path_to_save.sav` +`./sc64 --boot rom --rom path_to_rom.n64 --save-type eeprom-4k --save path_to_save.sav` -Replace `path_to_rom.n64` / `eeprom-4k` / `path_to_save.sav` with appropriate values for desired game. -Script will try to autodetect used save type so explicitly setting save type usually isn't needed. Check included help in script to list available save types. +Replace `path_to_rom.n64` / `eeprom-4k` / `path_to_save.sav` with appropriate values for desired game. Script will try to autodetect used save type so explicitly setting save type usually isn't needed. Check included help in program to list available save types. Arguments `--save-type` and/or `--save` can be omitted if game doesn't require any save or you want to start fresh. --- ## Downloading save -`python3 sc64.py --backup-save path_to_save.sav` +`./sc64 --backup-save path_to_save.sav` Replace `path_to_save.sav` with appropriate value. Specifying save type isn't required when set correctly previously. @@ -58,7 +56,7 @@ Replace `path_to_save.sav` with appropriate value. Specifying save type isn't re ## Running 64DD games -64DD games require DDIPL ROM and disk images. To run disk game type `python3 sc64.py --ddipl path_to_ddipl.n64 --disk path_to_disk_1.ndd --disk path_to_disk_2.ndd`. +64DD games require DDIPL ROM and disk images. To run disk game type `./sc64 --boot ddipl --ddipl path_to_ddipl.n64 --disk path_to_disk_1.ndd --disk path_to_disk_2.ndd`. Replace `path_to_ddipl.n64` / `path_to_disk_x.ndd` with appropriate values. Argument `--disk` can be specified multiple times. Only `.ndd` disk format is supported currently. To change inserted disk press button on the back of SC64 flashcart. Make sure retail and development disks aren't mixed together. 64DD IPL can handle only one drive type at a time. @@ -67,13 +65,13 @@ Replace `path_to_ddipl.n64` / `path_to_disk_x.ndd` with appropriate values. Argu ## Direct boot option If booting game through included bootloader isn't a desired option then flashcart can be put in special mode that omits this step. -Run `python3 sc64.py --boot direct-rom path_to_rom.n64` to disable bootloader during boot and console reset. This option is useful only for very specific cases (e.g. testing custom IPL3 or running SC64 on top of GameShark). +Run `./sc64 --boot direct-rom --rom path_to_rom.n64` to disable bootloader during boot and console reset. This option is useful only for very specific cases (e.g. testing custom IPL3 or running SC64 on top of GameShark). --- ## Debug terminal -`sc64.py` supports UNFLoader protocol and has same functionality implemented as aforementioned program. Use argument `--debug` to activate it. +`sc64` executable supports UNFLoader protocol and has same functionality implemented as aforementioned program. Use argument `--debug` to activate it. --- @@ -91,4 +89,4 @@ LED on SC64 board can blink in certain situations. Most of them during normal us Nx means that blink count is varied. -LED blinking on SD card access can be disabled through `sc64.py` script. Please refer to included help for option to change the LED behavior. +LED blinking on SD card access can be disabled through `sc64` executable. Please refer to included help for option to change the LED behavior. diff --git a/docs/04_config_options.md b/docs/04_config_options.md index c9739ab..3c94e3c 100644 --- a/docs/04_config_options.md +++ b/docs/04_config_options.md @@ -174,7 +174,6 @@ type: *bool* | default: `0` - `1` - 64DD block requests are passed to SD card Use this setting to change where 64DD emulation will be passing incoming block R/W requests. -For more information about 64DD and USB request passing check [sc64.py](../sw/pc/sc64.py#L636) implementation. --- diff --git a/docs/06_manufacturing_guidelines.md b/docs/06_manufacturing_guidelines.md index 4bfbf2a..b287ee6 100644 --- a/docs/06_manufacturing_guidelines.md +++ b/docs/06_manufacturing_guidelines.md @@ -11,7 +11,7 @@ ## Step by step guide how to make SC64 -All necessary manufacturing files are packaged in every `SC64.zip` file in GitHub releases. Please download latest release before proceeding with the instructions. +All necessary manufacturing files are packaged in every `sc64-extra-{version}.zip` file in GitHub releases. Please download latest release before proceeding with the instructions. --- @@ -85,9 +85,9 @@ Second, program FPGA, microcontroller and Flash memory: 4. Check in device manager which port number `COMx` is assigned to serial adapter 5. Connect SC64 board to the PC with USB-C cable (***IMPORTANT:*** connect it to the same computer as serial adapter) 6. Locate `primer.py` script in root folder - 7. Make sure these files are located in the same folder as `primer.py` script: `requirements.txt`, `sc64.py`, `sc64_firmware.bin` + 7. Make sure these files are located in the same folder as `primer.py` script: `requirements.txt`, `sc64.py`, `sc64-firmware.bin` 8. Run `pip3 install -r requirements.txt` to install required python packages - 9. Run `python3 primer.py COMx sc64_firmware.bin` (replace `COMx` with port located in step **4**) + 9. Run `python3 primer.py COMx sc64-firmware.bin` (replace `COMx` with port located in step **4**) 10. Follow the instructions on the screen 11. Wait until programming process has finished (**DO NOT STOP PROGRAMMING PROCESS OR DISCONNECT SC64 BOARD FROM PC**, doing so might irrecoverably break programming through UART header and you would need to program microcontroller, FPGA and bootloader with separate dedicated programming interfaces through *Tag-Connect* connector on the PCB) @@ -99,4 +99,4 @@ Congratulations! Your SC64 flashcart should be ready for use! *`primer.py` threw error on `Bootloader -> SC64 FLASH` step* -This issue can be attributed to incorrectly programmed FT232H EEPROM in the first programming step. Check again in `FT_PROG` program if device was configured properly. Once FPGA and microcontroller has been programmed successfully `primer.py` script needs to be run in special mode. Please use command `python3 primer.py COMx sc64_firmware.bin --only-bootloader` to try programming bootloader again. +This issue can be attributed to incorrectly programmed FT232H EEPROM in the first programming step. Check again in `FT_PROG` program if device was configured properly. Once FPGA and microcontroller has been programmed successfully `primer.py` script needs to be run in special mode. Please use command `python3 primer.py COMx sc64-firmware.bin --only-bootloader` to try programming bootloader again. diff --git a/sw/pc/.gitignore b/sw/pc/.gitignore index 3c81bcf..0ad4956 100644 --- a/sw/pc/.gitignore +++ b/sw/pc/.gitignore @@ -1,8 +1,11 @@ -**/__pycache__ +/__pycache__ +/build +/dist *.bin *.eep *.fla *.n64 +*.spec *.srm *.v64 *.z64 diff --git a/sw/pc/primer.py b/sw/pc/primer.py index 67d1da1..e2be968 100644 --- a/sw/pc/primer.py +++ b/sw/pc/primer.py @@ -8,6 +8,7 @@ import sys import time from binascii import crc32 from sc64 import SC64 +from sys import exit from typing import Callable, Optional diff --git a/sw/pc/sc64.py b/sw/pc/sc64.py index bfb9f18..adc091d 100755 --- a/sw/pc/sc64.py +++ b/sw/pc/sc64.py @@ -1328,8 +1328,8 @@ if __name__ == '__main__': print(f'\x1b[32mSC64 firmware version: [{version}]\x1b[0m') if (script_outdated): print('\x1b[33m') - print('[ SC64 firmware is newer than last known version. ]') - print('[ Consider downloading latest script from ]') + print('[ SC64 firmware is newer than last known version ]') + print('[ Consider downloading latest sc64 executable from ]') print('[ https://github.com/Polprzewodnikowy/SummerCart64/releases ]') print('\x1b[0m')