Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minimal ED64 support #44

Open
wants to merge 96 commits into
base: develop
Choose a base branch
from

Conversation

networkfusion
Copy link
Collaborator

@networkfusion networkfusion commented Aug 21, 2023

Description

Adds the basic needs to run ROMs on V series hardware (specifically the ED64P).

NOTE: this PR will not implement the ability to load the latest firmware and relies upon libCart for basic needs.
Improvements will be made in further PR's.

Motivation and Context

#15 but without all of the fat (needed for the future).

How Has This Been Tested?

Screenshots

Types of changes

  • Improvement (non-breaking change that adds a new feature)
  • Bug fix (fixes an issue)
  • Breaking change (breaking change)
  • Config and build (change in the configuration and build system, has no impact on code or features)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Signed-off-by: GITHUB_USER <GITHUB_USER_EMAIL>

Summary by CodeRabbit

  • New Features

    • Added support for the ED64 flashcart, enhancing gameplay for Nintendo 64 games.
    • New instructions for downloading and using ED64 and ED64P ROMs have been documented.
    • Introduced detailed guidelines for uploading ROMs via USB using UNFLoader.
  • Documentation

    • Expanded the README to clarify installation and usage steps for ED64 and ED64P.
    • New README file specific to the ED64 flashcart added, detailing compatibility and usage.
  • Bug Fixes

    • Improved initialization logic for different cartridge types to correctly support ED64 functionality.

Adds the basic needs to run ROMs on V series hardware.
@networkfusion networkfusion mentioned this pull request Aug 21, 2023
9 tasks
@networkfusion networkfusion added enhancement New feature or request help wanted Extra attention is needed labels Oct 14, 2023
@networkfusion networkfusion marked this pull request as draft October 14, 2023 19:14
Specifically for ED64 V3
Workaround for need of F/W 3.06 and UNFLoader.
Fixes ability to run ROM's
change function name to match main branch.
fix further function that was renamed.
@evilgenius31
Copy link

https://github.com/networkfusion/N64FlashcartMenu/tree/ed64p-refactor

How far should loading roms get with new builds for the ed64p? Menus look great

Add all current features to switch.
@networkfusion
Copy link
Collaborator Author

networkfusion commented May 1, 2024

https://github.com/networkfusion/N64FlashcartMenu/tree/ed64p-refactor

How far should loading roms get with new builds for the ed64p? Menus look great

At minimum, loads clays (oss rom) and SM64 and blues brothers 2000. Saves are probably broken now. Just tested on my ED64 V3.

@networkfusion networkfusion changed the base branch from main to develop May 21, 2024 17:24
@Matsilagi
Copy link

Matsilagi commented Jun 8, 2024

As of right now, the writebacks for ED64P are completely broken.
It writes the initial one, but sometimes fails even to return to the main directory. It also will only read (not write) existing ones and not touch any changes.
The last working version from my tests was dated December 24th 2023.
EDIT: welp, just saw above saves are indeed broken and the entire thing is basically in a very WIP / reverted state nowadays, nvm.

Copy link

coderabbitai bot commented Aug 4, 2024

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The recent changes enhance support for the ED64 flashcart within the project, introducing new source files that manage its functionality. Documentation updates clarify setup instructions for ED64 and ED64P ROMs, improving user guidance. The overall changes implement robust features for game state management, memory operations, and user interactions with the flashcart.

Changes

Files Change Summary
Makefile Added support for ED64 with three new source files in SRCS.
README.md Updated instructions for ED64/ED64P ROMs, clarified documentation, and added a section for using UNFLoader.
src/flashcart/ed64/.c, src/flashcart/ed64/.h Introduced files for managing ED64 functionality, including initialization, state management, and memory operations.
src/flashcart/flashcart.c Modified to include ED64 functionality and updated initialization logic for cartridge types.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ED64
    participant Memory
    participant State

    User->>ED64: Start Game
    ED64->>Memory: Load ROM
    Memory-->>ED64: ROM Data
    ED64->>State: Initialize Game State
    State-->>ED64: State Initialized
    ED64-->>User: Game Ready
Loading

🐇 In the meadow where flashcarts play,
New features bloom, bright as the day.
Documentation crisp, guides to delight,
With ROMs in hand, we hop into the night.
So let’s cheer for the code, oh what a treat,
For every game loaded, our joy is complete! 🐾✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Save corrections
@networkfusion
Copy link
Collaborator Author

@coderabbitai review

Copy link

coderabbitai bot commented Aug 4, 2024

Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

Outside diff range, codebase verification and nitpick comments (7)
src/flashcart/ed64/ed64_ll.h (4)

16-16: Clarify the purpose of the PI_SAVE_ADDR macro.

Consider adding a comment to explain the purpose and usage of PI_SAVE_ADDR for better readability.


56-65: Consider adding more descriptive comments for save types.

Adding comments to each save type in the ed64_save_type_t enumeration can improve readability and maintainability.

typedef enum {
    SAVE_TYPE_NONE = 0,        // No save type
    SAVE_TYPE_SRAM = 1,        // SRAM save type
    SAVE_TYPE_SRAM_128K = 2,   // 128K SRAM save type
    SAVE_TYPE_EEPROM_4K = 3,   // 4K EEPROM save type
    SAVE_TYPE_EEPROM_16K = 4,  // 16K EEPROM save type
    SAVE_TYPE_FLASHRAM = 5,    // FlashRAM save type
    SAVE_TYPE_CPAK = 8,        // Controller Pak save type
    SAVE_TYPE_DD64_CART_PORT = 16, // 64DD cart port save type
} ed64_save_type_t;

69-82: Consider adding comments to function declarations.

Adding comments to each function declaration can improve readability and provide context for their usage.

/* Save functions */

/**
 * @brief Initialize SRAM.
 */
void pi_initialize_sram (void);

/**
 * @brief Invalidate all data caches.
 */
void _data_cache_invalidate_all (void);

/**
 * @brief Set the SRAM bank.
 * @param bank The SRAM bank to set.
 */
void ed64_ll_set_sram_bank (uint8_t bank);

/**
 * @brief Get the current save type.
 * @return The current save type.
 */
ed64_save_type_t ed64_ll_get_save_type (void);

/**
 * @brief Set the save type.
 * @param type The save type to set.
 */
void ed64_ll_set_save_type (ed64_save_type_t type);

/**
 * @brief Get SRAM data.
 * @param buffer The buffer to store the data.
 * @param size The size of the buffer.
 */
void ed64_ll_get_sram (uint8_t *buffer, int size);

/**
 * @brief Get EEPROM data.
 * @param buffer The buffer to store the data.
 * @param size The size of the buffer.
 */
void ed64_ll_get_eeprom (uint8_t *buffer, int size);

/**
 * @brief Get FRAM data.
 * @param buffer The buffer to store the data.
 * @param size The size of the buffer.
 */
void ed64_ll_get_fram (uint8_t *buffer, int size);

/**
 * @brief Set SRAM data.
 * @param buffer The buffer containing the data.
 * @param size The size of the buffer.
 */
void ed64_ll_set_sram (uint8_t *buffer, int size);

/**
 * @brief Set EEPROM data.
 * @param buffer The buffer containing the data.
 * @param size The size of the buffer.
 */
void ed64_ll_set_eeprom (uint8_t *buffer, int size);

/**
 * @brief Set FRAM data.
 * @param buffer The buffer containing the data.
 * @param size The size of the buffer.
 */
void ed64_ll_set_fram (uint8_t *buffer, int size);

7-8: Use a more descriptive include guard name.

Consider using a more descriptive name for the include guard to avoid potential conflicts with other files.

#ifndef FLASHCART_ED64_LL_H__
#define FLASHCART_ED64_LL_H__

</blockquote></details>
<details>
<summary>Makefile (1)</summary><blockquote>

Line range hint `1-1`: 
**Consider adding a brief description of the project.**

Adding a brief description at the top of the Makefile can provide context for new contributors.

```diff
# Makefile for the N64FlashcartMenu project
PROJECT_NAME = N64FlashcartMenu
src/flashcart/flashcart.c (2)

113-113: Remove commented-out code.

The commented-out code for CART_EDX should be removed or addressed to avoid confusion.

- //flashcart = ed64x_get_flashcart();

Line range hint 1-1:
Consider adding a brief description of the file.

Adding a brief description at the top of the file can provide context for new contributors.

// flashcart.c - Implementation of flashcart operations for the N64FlashcartMenu project
#include <stddef.h>
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 02f4614 and 717db39.

Files selected for processing (10)
  • Makefile (1 hunks)
  • README.md (2 hunks)
  • src/flashcart/ed64/README.md (1 hunks)
  • src/flashcart/ed64/ed64.c (1 hunks)
  • src/flashcart/ed64/ed64.h (1 hunks)
  • src/flashcart/ed64/ed64_ll.c (1 hunks)
  • src/flashcart/ed64/ed64_ll.h (1 hunks)
  • src/flashcart/ed64/ed64_state.c (1 hunks)
  • src/flashcart/ed64/ed64_state.h (1 hunks)
  • src/flashcart/flashcart.c (2 hunks)
Files skipped from review due to trivial changes (1)
  • src/flashcart/ed64/README.md
Additional context used
Markdownlint
README.md

110-110: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


112-112: null
Bare URL used

(MD034, no-bare-urls)

LanguageTool
README.md

[style] ~143-~143: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...development and debugging, the menu ROM is able to run in the Ares emulator (without most ...

(BE_ABLE_TO)

Additional comments not posted (30)
src/flashcart/ed64/ed64.h (4)

1-5: File header comment block looks good.

The comment block is well-structured and follows documentation standards.


7-12: Preprocessor directives look good.

The include guards are correctly defined, and the included header file is appropriate.


19-19: Function prototype looks good.

The function prototype follows standard conventions.


21-24: Closing comment block and include guard look good.

The closing comment block and include guard are correctly placed.

src/flashcart/ed64/ed64_state.h (4)

1-5: File header comment block looks good.

The comment block is well-structured and follows documentation standards.


7-8: Preprocessor directives look good.

The include guards are correctly defined.


11-18: Structure definition looks good.

The structure ed64_pseudo_writeback_t is well-defined with appropriate member comments.


21-23: Function prototypes look good.

The function prototypes follow standard conventions.

src/flashcart/ed64/ed64_state.c (4)

1-6: Header includes look good.

The included headers are appropriate for the functionality provided.


7-13: Static variable definitions look good.

The static variables are well-defined and initialized correctly.


15-20: ed64_state_init function looks good.

The function follows standard memory management practices.


36-46: ed64_state_save function looks good.

The function follows standard practices for saving state.

Makefile (1)

35-37: LGTM! Ensure new source files are correctly integrated.

The new source files for ED64 flashcart support are correctly included.

src/flashcart/flashcart.c (2)

15-15: LGTM! Ensure the new header file is correctly integrated.

The new header file ed64.h is correctly included.


117-117: LGTM! Ensure the new initialization logic is correctly integrated.

The new initialization logic for CART_ED is correctly integrated.

src/flashcart/ed64/ed64_ll.c (10)

57-61: LGTM!

The function correctly returns the current save type.


112-116: LGTM!

The function correctly sets the SRAM bank.


147-152: LGTM!

The function correctly initializes the PI and waits for DMA to complete.


154-157: LGTM!

The function correctly waits for the PI DMA to complete.


169-177: LGTM!

The function correctly performs a DMA read from SRAM.


179-189: LGTM!

The function correctly performs a DMA write to SRAM.


232-239: LGTM!

The function correctly retrieves EEPROM data.


242-255: LGTM!

The function correctly retrieves FRAM data.


160-165: Verify the necessity of reconfiguring PI timings.

Reconfiguring PI timings might be redundant if libcart already sets them to correct values.

Verification successful

Verified: The reconfiguration of PI timings in pi_initialize_sram is necessary.

The search results indicate that PI timing configurations are not set by libcart but are present only in src/flashcart/ed64/ed64_ll.c. Thus, the reconfiguration in pi_initialize_sram is required.

  • src/flashcart/ed64/ed64_ll.c: PI timing configurations found only here.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify if PI timings are already configured by libcart.

# Test: Search for PI timing configurations in libcart. Expect: PI timings configured.
rg --type c -A 5 'io_write\(PI_BSD_DOM2_LAT_REG' libcart/

Length of output: 108


Script:

#!/bin/bash
# Description: Verify if PI timings are already configured in the codebase.

# Test: Search for PI timing configurations in the entire codebase. Expect: PI timings configured.
rg --type c -A 5 'io_write\(PI_BSD_DOM2_LAT_REG'

Length of output: 734


191-201: Verify the necessity of reconfiguring PI timings.

Reconfiguring PI timings might be redundant if libcart already sets them to correct values.

Verification successful

The reconfiguration of PI timings in ed64_ll_set_sdcard_timing is necessary.

The search results indicate that PI timings are not configured elsewhere in the codebase, confirming that the configurations in ed64_ll_set_sdcard_timing are essential.

  • src/flashcart/ed64/ed64_ll.c
  • src/flashcart/ed64/ed64_ll.h
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify if PI timings are already configured by libcart.

# Test: Search for PI timing configurations in libcart. Expect: PI timings configured.
rg --type c -A 5 'io_write\(PI_BSD_DOM2_LAT_REG' libcart/

Length of output: 108


Script:

#!/bin/bash
# Description: Locate files related to libcart or files that might configure PI timings.

# Find all files containing the term 'libcart' to identify potential directories or files.
fd -I 'libcart'

# Find all files that might configure PI timings by searching for 'PI_BSD_DOM2_LAT_REG'.
rg --type c 'PI_BSD_DOM2_LAT_REG'

Length of output: 268

README.md (3)

97-103: LGTM!

The setup instructions for ED64 and ED64P ROMs are clear and provide necessary details.


110-115: LGTM!

The instructions for building the project are clear and provide necessary details.

Tools
Markdownlint

110-110: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


112-112: null
Bare URL used

(MD034, no-bare-urls)


148-154: LGTM!

The instructions for using UNFLoader to upload ROMs via USB are clear and provide necessary details.

src/flashcart/ed64/ed64.c (2)

95-103: LGTM!

The function correctly saves the state file and exits using libCart.


274-304: LGTM!

The function correctly sets the save type for the ED64.

Comment on lines +22 to +34
void ed64_state_load (ed64_pseudo_writeback_t *state) {
if (!file_exists(ed64_state_path)) {
ed64_state_save(&init);
}

mini_t *ini = mini_try_load(ed64_state_path);

state->is_expecting_save_writeback = mini_get_bool(ini, "ed64", "is_expecting_save_writeback", init.is_expecting_save_writeback);
state->is_fram_save_type = mini_get_bool(ini, "ed64", "is_fram_save_type", init.is_fram_save_type);
state->last_save_path = strdup(mini_get_string(ini, "ed64", "last_save_path", init.last_save_path));

mini_free(ini);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix potential memory leak in ed64_state_load.

Ensure state->last_save_path is freed before assigning a new value to avoid memory leaks.

-  state->last_save_path = strdup(mini_get_string(ini, "ed64", "last_save_path", init.last_save_path));
+  free(state->last_save_path);
+  state->last_save_path = strdup(mini_get_string(ini, "ed64", "last_save_path", init.last_save_path));
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void ed64_state_load (ed64_pseudo_writeback_t *state) {
if (!file_exists(ed64_state_path)) {
ed64_state_save(&init);
}
mini_t *ini = mini_try_load(ed64_state_path);
state->is_expecting_save_writeback = mini_get_bool(ini, "ed64", "is_expecting_save_writeback", init.is_expecting_save_writeback);
state->is_fram_save_type = mini_get_bool(ini, "ed64", "is_fram_save_type", init.is_fram_save_type);
state->last_save_path = strdup(mini_get_string(ini, "ed64", "last_save_path", init.last_save_path));
mini_free(ini);
}
void ed64_state_load (ed64_pseudo_writeback_t *state) {
if (!file_exists(ed64_state_path)) {
ed64_state_save(&init);
}
mini_t *ini = mini_try_load(ed64_state_path);
state->is_expecting_save_writeback = mini_get_bool(ini, "ed64", "is_expecting_save_writeback", init.is_expecting_save_writeback);
state->is_fram_save_type = mini_get_bool(ini, "ed64", "is_fram_save_type", init.is_fram_save_type);
free(state->last_save_path);
state->last_save_path = strdup(mini_get_string(ini, "ed64", "last_save_path", init.last_save_path));
mini_free(ini);
}

Comment on lines +18 to +20
// FIXME: redefined because its in a .c instead of a .h
#define PI_BASE_REG 0x04600000

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid redefinitions of macros.

The PI_BASE_REG macro is redefined because it's in a .c file instead of a .h file. This should be addressed to avoid potential conflicts.

- #define PI_BASE_REG		    0x04600000
+ // #define PI_BASE_REG		    0x04600000

Consider moving the definition to a common header file if it's used across multiple files.


<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +32 to +40
// FIXME: redefined because its in a .c instead of a .h
#define PI_BSD_DOM1_LAT_REG (PI_BASE_REG+0x14)
#define PI_BSD_DOM1_PWD_REG (PI_BASE_REG+0x18)
#define PI_BSD_DOM1_PGS_REG (PI_BASE_REG+0x1C)
#define PI_BSD_DOM1_RLS_REG (PI_BASE_REG+0x20)
#define PI_BSD_DOM2_LAT_REG (PI_BASE_REG+0x24)
#define PI_BSD_DOM2_PWD_REG (PI_BASE_REG+0x28)
#define PI_BSD_DOM2_PGS_REG (PI_BASE_REG+0x2C)
#define PI_BSD_DOM2_RLS_REG (PI_BASE_REG+0x30)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid redefinitions of macros.

The PI_BSD_DOM1_* and PI_BSD_DOM2_* macros are redefined because they are in a .c file instead of a .h file. This should be addressed to avoid potential conflicts.

- #define PI_BSD_DOM1_LAT_REG     (PI_BASE_REG+0x14)
- #define PI_BSD_DOM1_PWD_REG     (PI_BASE_REG+0x18)
- #define PI_BSD_DOM1_PGS_REG     (PI_BASE_REG+0x1C)
- #define PI_BSD_DOM1_RLS_REG     (PI_BASE_REG+0x20)
- #define PI_BSD_DOM2_LAT_REG     (PI_BASE_REG+0x24)
- #define PI_BSD_DOM2_PWD_REG     (PI_BASE_REG+0x28)
- #define PI_BSD_DOM2_PGS_REG     (PI_BASE_REG+0x2C)
- #define PI_BSD_DOM2_RLS_REG     (PI_BASE_REG+0x30)
+ // #define PI_BSD_DOM1_LAT_REG     (PI_BASE_REG+0x14)
+ // #define PI_BSD_DOM1_PWD_REG     (PI_BASE_REG+0x18)
+ // #define PI_BSD_DOM1_PGS_REG     (PI_BASE_REG+0x1C)
+ // #define PI_BSD_DOM1_RLS_REG     (PI_BASE_REG+0x20)
+ // #define PI_BSD_DOM2_LAT_REG     (PI_BASE_REG+0x24)
+ // #define PI_BSD_DOM2_PWD_REG     (PI_BASE_REG+0x28)
+ // #define PI_BSD_DOM2_PGS_REG     (PI_BASE_REG+0x2C)
+ // #define PI_BSD_DOM2_RLS_REG     (PI_BASE_REG+0x30)

Consider moving the definition to a common header file if it's used across multiple files.


<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +43 to +51
void ed64_ll_reg_write (uint32_t reg, uint32_t data);

void ed64_ll_reg_write (uint32_t reg, uint32_t data) {

*(volatile uint32_t *) (ED64_CONFIG_REGS_BASE);
*(volatile uint32_t *) (ED64_CONFIG_REGS_BASE + reg * 4) = data;
*(volatile uint32_t *) (ROM_ADDRESS);

}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optimize redundant dummy reads and use libdragon functions.

The dummy reads are likely optimized away by the compiler. Use io_write/io_read functions provided by libdragon for consistency and reliability.

-    *(volatile uint32_t *) (ED64_CONFIG_REGS_BASE);
-    *(volatile uint32_t *) (ED64_CONFIG_REGS_BASE + reg * 4) = data;
-    *(volatile uint32_t *) (ROM_ADDRESS);
+    io_write(ED64_CONFIG_REGS_BASE + reg * 4, data);
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void ed64_ll_reg_write (uint32_t reg, uint32_t data);
void ed64_ll_reg_write (uint32_t reg, uint32_t data) {
*(volatile uint32_t *) (ED64_CONFIG_REGS_BASE);
*(volatile uint32_t *) (ED64_CONFIG_REGS_BASE + reg * 4) = data;
*(volatile uint32_t *) (ROM_ADDRESS);
}
void ed64_ll_reg_write (uint32_t reg, uint32_t data) {
io_write(ED64_CONFIG_REGS_BASE + reg * 4, data);
}

Comment on lines +118 to +139
// FIXME Id like to use libdragon's equivelant for this
void _data_cache_invalidate_all (void) {
asm(
"li $8,0x80000000;"
"li $9,0x80000000;"
"addu $9,$9,0x1FF0;"
"cacheloop:;"
"cache 1,0($8);"
"cache 1,16($8);"
"cache 1,32($8);"
"cache 1,48($8);"
"cache 1,64($8);"
"cache 1,80($8);"
"cache 1,96($8);"
"addu $8,$8,112;"
"bne $8,$9,cacheloop;"
"cache 1,0($8);"
: // no outputs
: // no inputs
: "$8", "$9" // trashed registers
);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use libdragon's cache invalidation function.

The function uses inline assembly for cache invalidation. If libdragon provides an equivalent function, it should be used for consistency and maintainability.

-void _data_cache_invalidate_all (void) {
-    asm(
-        "li $8,0x80000000;"
-        "li $9,0x80000000;"
-        "addu $9,$9,0x1FF0;"
-        "cacheloop:;"
-        "cache 1,0($8);"
-        "cache 1,16($8);"
-        "cache 1,32($8);"
-        "cache 1,48($8);"
-        "cache 1,64($8);"
-        "cache 1,80($8);"
-        "cache 1,96($8);"
-        "addu $8,$8,112;"
-        "bne $8,$9,cacheloop;"
-        "cache 1,0($8);"
-    : // no outputs
-    : // no inputs
-    : "$8", "$9" // trashed registers
-    );
-}
+// FIXME: Use libdragon's cache invalidation function if available
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// FIXME Id like to use libdragon's equivelant for this
void _data_cache_invalidate_all (void) {
asm(
"li $8,0x80000000;"
"li $9,0x80000000;"
"addu $9,$9,0x1FF0;"
"cacheloop:;"
"cache 1,0($8);"
"cache 1,16($8);"
"cache 1,32($8);"
"cache 1,48($8);"
"cache 1,64($8);"
"cache 1,80($8);"
"cache 1,96($8);"
"addu $8,$8,112;"
"bne $8,$9,cacheloop;"
"cache 1,0($8);"
: // no outputs
: // no inputs
: "$8", "$9" // trashed registers
);
}
// FIXME: Use libdragon's cache invalidation function if available

Comment on lines +27 to +93
static flashcart_err_t ed64_init (void) {

// TODO: partly already done, see https://github.com/DragonMinded/libdragon/blob/4ec469d26b6dc4e308caf3d5b86c2b340b708bbd/src/libcart/cart.c#L1064

// FIXME: Update firmware if needed.
// FIXME: Enable RTC if available.

// older everdrives cannot save during gameplay so we need to the reset method.
// works by checking if a file exists.

// FIXME: should put the file in the OS dir (ED64_OS_DIRECTORY), but different if a clone (ED64P).
char *state_path = "sd:/menu/"ED64_STATE_FILE;
ed64_state_init(state_path);
ed64_state_load(&current_state);

if (current_state.is_expecting_save_writeback == true) {

// make sure next boot does not trigger the check changing its state.
current_state.is_expecting_save_writeback = false;
ed64_state_save(&current_state);

// Now save the content back to the SD card!
FIL fil;
UINT bw;
uint8_t cartsave_data[KiB(128)];

// find the path to last save
if (file_exists(strip_fs_prefix(current_state.last_save_path))) {

int save_size = file_get_size(current_state.last_save_path);

if ((f_open(&fil, strip_fs_prefix(current_state.last_save_path), FA_CREATE_ALWAYS | FA_WRITE)) != FR_OK) {
return FLASHCART_ERR_LOAD;
}

// everdrive doesn't care about the save type other than flash sram and eeprom
// so minus flashram we can just check the size
if (current_state.is_fram_save_type == true) { // flashram is bugged atm
ed64_ll_get_fram(cartsave_data, save_size);
// deletes flag
current_state.is_fram_save_type = false;
ed64_state_save(&current_state);
}
else if (save_size > KiB(2)) { // sram
ed64_ll_get_sram(cartsave_data, save_size);
}
else { // eeprom
ed64_ll_get_eeprom(cartsave_data, save_size);
}

if (f_write(&fil, cartsave_data, save_size, &bw) != FR_OK) {
return FLASHCART_ERR_LOAD;
}

if (f_close(&fil) != FR_OK) {
return FLASHCART_ERR_LOAD;
}
}
else {
current_state.is_expecting_save_writeback = false;
current_state.is_fram_save_type = false;
current_state.last_save_path = "";
ed64_state_save(&current_state);
}
}
return FLASHCART_OK;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address TODO and FIXME comments.

The function contains several TODO and FIXME comments indicating incomplete implementation.

Do you want me to address these TODO and FIXME comments or open a GitHub issue to track these tasks?

Comment on lines +105 to +115
static bool ed64_has_feature (flashcart_features_t feature) {
switch (feature) {
case FLASHCART_FEATURE_64DD:
// FIXME: this is not valid for the V3, as does contain them:
case FLASHCART_FEATURE_RTC:
case FLASHCART_FEATURE_USB:
return false;
default:
return false;
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address FIXME comment.

The function contains a FIXME comment indicating invalid feature checks for V3.

Do you want me to address this FIXME comment or open a GitHub issue to track this task?

Comment on lines +117 to +177
static flashcart_err_t ed64_load_rom (char *rom_path, flashcart_progress_callback_t *progress) {

FIL fil;
UINT br;

if (f_open(&fil, strip_fs_prefix(rom_path), FA_READ) != FR_OK) {
return FLASHCART_ERR_LOAD;
}

fatfs_fix_file_size(&fil);

size_t rom_size = f_size(&fil);

// FIXME: if the cart is not V3 or X5 or X7, we need probably need to - 128KiB for save compatibility.
// Or somehow warn that certain ROM's will have corruption due to the address space being used for saves.
// Conker's Bad Fur Day doesn't have this issue because eeprom data is at a fixed address in pif ram.
if (rom_size > MiB(64)) {
f_close(&fil);
return FLASHCART_ERR_LOAD;
}

// FIXME: is this actually needed?
/*
if (rom_size == MiB(64)) {
ed64_save_type_t type = ed64_ll_get_save_type();
switch (type) {
case SAVE_TYPE_SRAM:
rom_size -= KiB(32);
break;
case SAVE_TYPE_SRAM_128K:
case SAVE_TYPE_FLASHRAM:
rom_size -= KiB(128);
break;
case SAVE_TYPE_DD64_CART_PORT:
break;
default:
break;
}
}
*/

size_t sdram_size = rom_size;

size_t chunk_size = MiB(1);
for (int offset = 0; offset < sdram_size; offset += chunk_size)
{
size_t block_size = MIN(sdram_size - offset, chunk_size);
if (f_read(&fil, (void *)(ROM_ADDRESS + offset), block_size, &br) != FR_OK) {
f_close(&fil);
return FLASHCART_ERR_LOAD;
}
if (progress) {
progress(f_tell(&fil) / (float)(f_size(&fil)));
}
}

if (f_close(&fil) != FR_OK) {
return FLASHCART_ERR_LOAD;
}

return FLASHCART_OK;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address FIXME comments.

The function contains several FIXME comments indicating incomplete implementation.

Do you want me to address these FIXME comments or open a GitHub issue to track these tasks?

Comment on lines +180 to +219
static flashcart_err_t ed64_load_file (char *file_path, uint32_t rom_offset, uint32_t file_offset)
{
FIL fil;
UINT br;

if (f_open(&fil, strip_fs_prefix(file_path), FA_READ) != FR_OK) {
return FLASHCART_ERR_LOAD;
}

fatfs_fix_file_size(&fil);

size_t file_size = f_size(&fil) - file_offset;

// FIXME: if the cart is not V3 or X5 or X7, we need probably need to - 128KiB for save compatibility.
// Or somehow warn that certain ROM's will have corruption due to the address space being used for saves.

if (file_size > (MiB(64) - rom_offset)) {
f_close(&fil);
return FLASHCART_ERR_ARGS;
}

if (f_lseek(&fil, file_offset) != FR_OK) {
f_close(&fil);
return FLASHCART_ERR_LOAD;
}

if (f_read(&fil, (void *)(ROM_ADDRESS + rom_offset), file_size, &br) != FR_OK) {
f_close(&fil);
return FLASHCART_ERR_LOAD;
}
if (br != file_size) {
f_close(&fil);
return FLASHCART_ERR_LOAD;
}

if (f_close(&fil) != FR_OK) {
return FLASHCART_ERR_LOAD;
}

return FLASHCART_OK;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address FIXME comment.

The function contains a FIXME comment indicating incomplete implementation.

Do you want me to address this FIXME comment or open a GitHub issue to track this task?

Comment on lines +222 to +270
static flashcart_err_t ed64_load_save (char *save_path) {

FIL fil;
UINT br;

if (f_open(&fil, strip_fs_prefix(save_path), FA_READ) != FR_OK) {
return FLASHCART_ERR_LOAD;
}

size_t save_size = file_get_size(save_path);
uint8_t cartsave_data[save_size];

if (f_read(&fil, cartsave_data, save_size, &br) != FR_OK) {
f_close(&fil);
return FLASHCART_ERR_LOAD;
}

if (br != save_size) {
return FLASHCART_ERR_LOAD;
}

current_state.is_fram_save_type = false;

ed64_save_type_t type = ed64_ll_get_save_type();
switch (type) {
case SAVE_TYPE_EEPROM_4K:
case SAVE_TYPE_EEPROM_16K:
ed64_ll_set_eeprom(cartsave_data, save_size);
break;
case SAVE_TYPE_SRAM:
case SAVE_TYPE_SRAM_128K:
ed64_ll_set_sram(cartsave_data, save_size);
break;
case SAVE_TYPE_FLASHRAM:
ed64_ll_set_fram(cartsave_data, save_size);
// a cold and warm boot has no way of seeing save types and most types can be determined by size
// this tells the cart to use flash instead of sram 128 since they are the same size
current_state.is_fram_save_type = true;
ed64_state_save(&current_state);
break;
default:
break;
}


current_state.last_save_path = save_path;
current_state.is_expecting_save_writeback = true;
ed64_state_save(&current_state);

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid variable length arrays.

The variable cartsave_data is declared with a variable length, which is not standard C. Use dynamic memory allocation instead.

-    uint8_t cartsave_data[save_size];
+    uint8_t *cartsave_data = malloc(save_size);
+    if (cartsave_data == NULL) {
+        f_close(&fil);
+        return FLASHCART_ERR_LOAD;
+    }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
static flashcart_err_t ed64_load_save (char *save_path) {
FIL fil;
UINT br;
if (f_open(&fil, strip_fs_prefix(save_path), FA_READ) != FR_OK) {
return FLASHCART_ERR_LOAD;
}
size_t save_size = file_get_size(save_path);
uint8_t cartsave_data[save_size];
if (f_read(&fil, cartsave_data, save_size, &br) != FR_OK) {
f_close(&fil);
return FLASHCART_ERR_LOAD;
}
if (br != save_size) {
return FLASHCART_ERR_LOAD;
}
current_state.is_fram_save_type = false;
ed64_save_type_t type = ed64_ll_get_save_type();
switch (type) {
case SAVE_TYPE_EEPROM_4K:
case SAVE_TYPE_EEPROM_16K:
ed64_ll_set_eeprom(cartsave_data, save_size);
break;
case SAVE_TYPE_SRAM:
case SAVE_TYPE_SRAM_128K:
ed64_ll_set_sram(cartsave_data, save_size);
break;
case SAVE_TYPE_FLASHRAM:
ed64_ll_set_fram(cartsave_data, save_size);
// a cold and warm boot has no way of seeing save types and most types can be determined by size
// this tells the cart to use flash instead of sram 128 since they are the same size
current_state.is_fram_save_type = true;
ed64_state_save(&current_state);
break;
default:
break;
}
current_state.last_save_path = save_path;
current_state.is_expecting_save_writeback = true;
ed64_state_save(&current_state);
static flashcart_err_t ed64_load_save (char *save_path) {
FIL fil;
UINT br;
if (f_open(&fil, strip_fs_prefix(save_path), FA_READ) != FR_OK) {
return FLASHCART_ERR_LOAD;
}
size_t save_size = file_get_size(save_path);
uint8_t *cartsave_data = malloc(save_size);
if (cartsave_data == NULL) {
f_close(&fil);
return FLASHCART_ERR_LOAD;
}
if (f_read(&fil, cartsave_data, save_size, &br) != FR_OK) {
f_close(&fil);
return FLASHCART_ERR_LOAD;
}
if (br != save_size) {
return FLASHCART_ERR_LOAD;
}
current_state.is_fram_save_type = false;
ed64_save_type_t type = ed64_ll_get_save_type();
switch (type) {
case SAVE_TYPE_EEPROM_4K:
case SAVE_TYPE_EEPROM_16K:
ed64_ll_set_eeprom(cartsave_data, save_size);
break;
case SAVE_TYPE_SRAM:
case SAVE_TYPE_SRAM_128K:
ed64_ll_set_sram(cartsave_data, save_size);
break;
case SAVE_TYPE_FLASHRAM:
ed64_ll_set_fram(cartsave_data, save_size);
// a cold and warm boot has no way of seeing save types and most types can be determined by size
// this tells the cart to use flash instead of sram 128 since they are the same size
current_state.is_fram_save_type = true;
ed64_state_save(&current_state);
break;
default:
break;
}
current_state.last_save_path = save_path;
current_state.is_expecting_save_writeback = true;
ed64_state_save(&current_state);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants