diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..2af5748 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,181 @@ +name: release + +on: + push: + branches: [main] + pull_request: + branches: [main] + +env: + CARGO_TERM_COLOR: always + RUSTFLAGS: -D warnings + +jobs: + crate_metadata: + name: Extract crate metadata + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Extract crate information + id: crate_metadata + run: | + cargo metadata --no-deps --format-version 1 | jq -r '"name=" + .packages[0].name' | tee -a $GITHUB_OUTPUT + cargo metadata --no-deps --format-version 1 | jq -r '"version=" + .packages[0].version' | tee -a $GITHUB_OUTPUT + cargo metadata --no-deps --format-version 1 | jq -r '"maintainer=" + .packages[0].authors[0]' | tee -a $GITHUB_OUTPUT + cargo metadata --no-deps --format-version 1 | jq -r '"homepage=" + .packages[0].homepage' | tee -a $GITHUB_OUTPUT + cargo metadata --no-deps --format-version 1 | jq -r '"msrv=" + .packages[0].rust_version' | tee -a $GITHUB_OUTPUT + outputs: + name: ${{ steps.crate_metadata.outputs.name }} + version: ${{ steps.crate_metadata.outputs.version }} + maintainer: ${{ steps.crate_metadata.outputs.maintainer }} + homepage: ${{ steps.crate_metadata.outputs.homepage }} + msrv: ${{ steps.crate_metadata.outputs.msrv }} + release: + name: ${{ matrix.job.target }} (${{ matrix.job.os }}) + runs-on: ${{ matrix.job.os }} + needs: crate_metadata + strategy: + fail-fast: false + matrix: + job: + #- { target: aarch64-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true } + #- { target: arm-unknown-linux-gnueabihf , os: ubuntu-20.04, use-cross: true } + #- { target: arm-unknown-linux-musleabihf, os: ubuntu-20.04, use-cross: true } + #- { target: i686-pc-windows-msvc , os: windows-2019 } + #- { target: i686-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true } + #- { target: i686-unknown-linux-musl , os: ubuntu-20.04, use-cross: true } + #- { target: x86_64-apple-darwin , os: macos-12 } + #- { target: x86_64-pc-windows-gnu , os: windows-2019 } + #- { target: x86_64-pc-windows-msvc , os: windows-2019 } + - { target: x86_64-unknown-linux-gnu , os: ubuntu-latest, use-cross: true } + #- { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, use-cross: true } + env: + BUILD_CMD: cargo + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Install prerequisites + shell: bash + run: | + case ${{ matrix.job.target }} in + arm-unknown-linux-*) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;; + aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;; + esac + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.job.target }} + + - name: Install cross + if: matrix.job.use-cross + uses: taiki-e/install-action@v2 + with: + tool: cross + + - name: Overwrite build command env variable + if: matrix.job.use-cross + shell: bash + run: echo "BUILD_CMD=cross" >> $GITHUB_ENV + + - name: Show version information (Rust, cargo, GCC) + shell: bash + run: | + gcc --version || true + rustup -V + rustup toolchain list + rustup default + cargo -V + rustc -V + + - name: Build + shell: bash + run: $BUILD_CMD build --locked --release --target=${{ matrix.job.target }} + + - name: Set binary name & path + id: bin + shell: bash + run: | + # Figure out suffix of binary + EXE_suffix="" + case ${{ matrix.job.target }} in + *-pc-windows-*) EXE_suffix=".exe" ;; + esac; + + # Setup paths + BIN_NAME="${{ needs.crate_metadata.outputs.name }}${EXE_suffix}" + BIN_PATH="target/${{ matrix.job.target }}/release/${BIN_NAME}" + + # Let subsequent steps know where to find the binary + echo "BIN_PATH=${BIN_PATH}" >> $GITHUB_OUTPUT + echo "BIN_NAME=${BIN_NAME}" >> $GITHUB_OUTPUT + +#- name: Set testing options +# id: test-options +# shell: bash +# run: | +# # test only library unit tests and binary for arm-type targets +# unset CARGO_TEST_OPTIONS +# unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--lib --bin ${{ needs.crate_metadata.outputs.name }}" ;; esac; +# echo "CARGO_TEST_OPTIONS=${CARGO_TEST_OPTIONS}" >> $GITHUB_OUTPUT + +# - name: Run tests +# shell: bash +# run: $BUILD_CMD test --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}} + + - name: Create tarball + id: package + shell: bash + run: | + PKG_suffix=".tar.gz" ; case ${{ matrix.job.target }} in *-pc-windows-*) PKG_suffix=".zip" ;; esac; + PKG_BASENAME=${{ needs.crate_metadata.outputs.name }}-v${{ needs.crate_metadata.outputs.version }}-${{ matrix.job.target }} + PKG_NAME=${PKG_BASENAME}${PKG_suffix} + echo "PKG_NAME=${PKG_NAME}" >> $GITHUB_OUTPUT + + PKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/package" + ARCHIVE_DIR="${PKG_STAGING}/${PKG_BASENAME}/" + mkdir -p "${ARCHIVE_DIR}" + + # Binary + cp "${{ steps.bin.outputs.BIN_PATH }}" "$ARCHIVE_DIR" + + # README and LICENSE files + cp "README.md" "LICENSE-MIT" "LICENSE-APACHE" "$ARCHIVE_DIR" + + # Desktop file and icons + #mkdir "$ARCHIVE_DIR/assets" + #cp "assets/fpt.desktop" assets/numbat-*x*.png "assets/numbat.svg" "$ARCHIVE_DIR/assets" + + # base compressed package + pushd "${PKG_STAGING}/" >/dev/null + case ${{ matrix.job.target }} in + *-pc-windows-*) 7z -y a "${PKG_NAME}" "${PKG_BASENAME}"/* | tail -2 ;; + *) tar czf "${PKG_NAME}" "${PKG_BASENAME}"/* ;; + esac; + popd >/dev/null + + # Let subsequent steps know where to find the compressed package + echo "PKG_PATH=${PKG_STAGING}/${PKG_NAME}" >> $GITHUB_OUTPUT + + - name: "Artifact upload: tarball" + uses: actions/upload-artifact@master + with: + name: ${{ steps.package.outputs.PKG_NAME }} + path: ${{ steps.package.outputs.PKG_PATH }} + + - name: Check for release + id: is-release + shell: bash + run: | + unset IS_RELEASE ; if [[ $GITHUB_REF =~ ^refs/tags/v[0-9].* ]]; then IS_RELEASE='true' ; else IS_RELEASE='true'; fi + echo "IS_RELEASE=${IS_RELEASE}" >> $GITHUB_OUTPUT + + - name: Publish archives and packages + uses: softprops/action-gh-release@v1 + if: steps.is-release.outputs.IS_RELEASE + with: + files: | + ${{ steps.package.outputs.PKG_PATH }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Cargo.toml b/Cargo.toml index 441d500..e4ff9f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,6 @@ resolver = "2" members = [ "fpt", - "fpt-egui", + #"fpt-egui", "fpt-cli", ] diff --git a/fpt-cli/Cargo.toml b/fpt-cli/Cargo.toml index 9ff85da..12e544c 100644 --- a/fpt-cli/Cargo.toml +++ b/fpt-cli/Cargo.toml @@ -5,10 +5,9 @@ edition = "2021" default-run = "main" [dependencies] -clap = { version = "4.4.6", features = ["derive"] } +clap = { version = "4.0", features = ["derive"] } fpt = { path = "../fpt" } rustyline = "13.0.0" -hlua = { version = "0.4.1" } [[bin]] name = "main" diff --git a/fpt-cli/src/lib.rs b/fpt-cli/src/lib.rs index aa2bdf7..5c41a69 100644 --- a/fpt-cli/src/lib.rs +++ b/fpt-cli/src/lib.rs @@ -1,2 +1,2 @@ -#![feature(array_chunks)] -#![feature(iter_intersperse)] +//#![feature(array_chunks)] +//#![feature(iter_intersperse)] diff --git a/fpt-cli/src/main.rs b/fpt-cli/src/main.rs index fe46acc..9840210 100644 --- a/fpt-cli/src/main.rs +++ b/fpt-cli/src/main.rs @@ -1,5 +1,5 @@ -#![feature(array_chunks)] -#![feature(iter_intersperse)] +//#![feature(array_chunks)] +//#![feature(iter_intersperse)] use std::fs; diff --git a/fpt/src/lib.rs b/fpt/src/lib.rs index 6a956cd..dbcbef0 100644 --- a/fpt/src/lib.rs +++ b/fpt/src/lib.rs @@ -1,6 +1,6 @@ -#![feature(bigint_helper_methods)] -#![feature(array_chunks)] -#![feature(iter_intersperse)] +//#![feature(bigint_helper_methods)] +//#![feature(array_chunks)] +//#![feature(iter_intersperse)] use std::collections::VecDeque; diff --git a/fpt/src/lr35902.rs b/fpt/src/lr35902.rs index 7f5e34a..aaf44c2 100644 --- a/fpt/src/lr35902.rs +++ b/fpt/src/lr35902.rs @@ -11,6 +11,19 @@ use crate::{bw, memory}; pub mod instructions; +fn carrying_add(x:u8, y:u8, carry: bool) -> (u8, bool) { + let carry: u8 = carry as u8; + let half_adder = x ^ y ; + let sum = half_adder ^ carry; + let carry = (carry & half_adder) | (x & y); + (sum, carry == 1) +} + +// yolo +fn borrowing_sub(x:u8, y:u8, borrow:bool) -> (u8, bool) { + carrying_add(x, !y, !borrow) +} + #[derive(Clone, PartialEq)] pub struct LR35902 { af: u16, @@ -403,9 +416,9 @@ impl LR35902 { self.set_c_flag(overflow); result } - + fn addc8(&mut self, x: u8, y: u8) -> u8 { - let (result, overflow) = x.carrying_add(y, self.c_flag()); + let (result, overflow) = carrying_add(x, y, self.c_flag()); self.set_z_flag(result == 0); self.set_n_flag(false); self.set_h_flag(self.half_carryc8(x, y, self.c_flag() as u8)); @@ -424,10 +437,10 @@ impl LR35902 { } fn subc8(&mut self, x: u8, y: u8) -> u8 { - let (result, overflow) = x.borrowing_sub(y, self.c_flag()); + let (result, overflow) = borrowing_sub(x, y, self.c_flag()); self.set_z_flag(result == 0); self.set_n_flag(true); - self.set_h_flag((x & 0x0f).borrowing_sub(y & 0x0f, self.c_flag()).1); + self.set_h_flag(borrowing_sub(x & 0x0f, y & 0x0f, self.c_flag()).1); self.set_c_flag(overflow); result } diff --git a/fpt/src/ppu/tile.rs b/fpt/src/ppu/tile.rs index 39fe15a..cb9e8cd 100644 --- a/fpt/src/ppu/tile.rs +++ b/fpt/src/ppu/tile.rs @@ -103,11 +103,10 @@ pub fn write_pgm_screenshot(frame: &Frame, filename: &str) { write!(file, "P2\n# Game Boy screenshot: {filename}\n160 144\n3\n").unwrap(); // Our Game Boy's framebuffer seems to have a direct correspondence to this! - for line in frame.array_chunks::<160>() { + for line in frame.chunks(160) { let pgm_line = line .iter() - .map(|p| (b'3' - *p) as char) // ASCII from '0' to '3' - .intersperse(' ') + .map(|p| String::from((b'3' - *p) as char) + " ") // ASCII from '0' to '3' .collect::() + "\n"; diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 5ff21ea..fb2b8b0 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,5 @@ [toolchain] -channel = "nightly-2024-06-11" +#channel = "nightly-2024-01-01" +channel = "stable" components = [ "rustfmt", "rustc-dev" , "clippy"] profile = "minimal"