Git Product home page Git Product logo

clementine's Introduction

Alt text

Rust

Clementine - A collaborative approach to GBA emulation

Welcome to the first ripsters' project. Our goal is to understand how GameBoy Advance works and to create a modern emulator written in Rust (if you want to collaborate but you can't code in Rust take a look here).

Everything is work in progress. We will update this document a lot of times in this stage.

Collaborative Guidelines

We love collaborating with others, so feel free to interact with us however you want. First of all, we strongly suggest you to enter in our Discord channel where you can find all of us (here).

Contributing doc

Resources

Build and quick start

  • clone the repository :)
  • we are using just and not make then if you want take the benefit of this install it cargo install just

Tip: Run just to see all the available commands

# quick check all is working on you machine
just build
just test

# run a .gba file
cargo run -- ~/Desktop/my_game.gba

Run

All of those command are just a wrapper around cargo run and they are just for convenience. If you want more control on the execution of the emulator you can use cargo run directly.

# simple run of a rom in debug mode
just run <rom>
# simple run of a rom in release mode
# this is better for looking at animations and stuff like that
just run-release <rom>
# debug mode + verbose log to stdout
just run-logger <rom>
# debug mode + disassebler as widget
just run-disassebler <rom>
# all debug feature enabled
just run-all-debug <rom>

clementine's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

clementine's Issues

Convert HEX values to BIN - Inconsistency in the format of numbers

Many values are written in hexadecimal format (like 0x0B_00_00_00), and a few others in binary format (like 0b1110_1010_0000_0000_0000_0000_0111_1111). It would be useful to standardize all values in binary, for readability reasons.

However, I think it is better to close #33 first because it would allow the removal of many values.

Fix `Branch` asm

Right now we output the offset in the disassembler, we should instead print the target address. This is non-trivial since the disassembler funcion doesn't have access to the pc value

Add condition behavior in CPSR register

In cpsr.rs file must be added all the behavior based on the condition parameter of the OPCODE.

pub(crate) fn can_execute(&self, cond: Condition) -> bool {
      match cond {
          Condition::GE => self.signed() == self.overflow(),
          // TODO: complete pattern matching for every condition
          _ => todo!(),
      }
}

When an instruction has been decoded the ARM cpu executes it only if the flags in the CSPR match the condition. More information here

`ArmModeInstruction::DataProcessing` has redundancy in the fields

pub enum ArmModeInstruction {
    DataProcessing {
        condition: Condition,
        alu_instruction: ArmModeAluInstruction,
        set_conditions: bool,
        op_kind: OperandKind,
        rn: u32,
        destination: u32,
        op2: AluSecondOperandInfo,
    },
...

We can remove op_kind since it encodes the information about whether the second op is register/immediate, but we already have this information in the op2 field

Implements all the headers for the `CartridgeHeader`

An easy thing to do for those who are learning Rust or for those who want to start collaborating might be to implement all cartridge headers for CartridgeHeader in cartridge_header.rs.

The headers are documented here.

Headers

  • ROM Entry Point
  • Nintendo Logo
  • Game Title
  • Game Code
  • Maker Code
  • Fixed value
  • Main unit code
  • Device type
  • Reserved Area
  • Software version
  • Complement check
  • Reserved Area

Additional Multiboot Header Entries

  • RAM Entry Point
  • Boot mode
  • Slave ID Number
  • Not used
  • JOYBUS Entry Pt.

Where is the starting point?

Hi guys! Just some stream of thoughts about how to proceed:
We need to define all the components used by the emulator. The cool fact of Gameboy is that it has different components, so we can divide our tasks really well. I'll try to list all the components:

Emulation Stuff:

  • CPU (ARM Mode, THUMB Mode, CGB Mode, DMG Mode)
  • Memory
  • Cartridge ( Header, ROM)
  • Video
  • I/O
  • Sound
  • Controls

Debug Stuff:

I think it could be nice for us and also for homebrewing developer to have a nice graphical debugger in the emulator. Many other GBA emulators have tried to build something in this sense, but every attempt now seems old and I think that it could be done better:

  • Memory viewer (ASCII, Hex, Tile)
  • OPCode execution step by step
  • CPU Register viewer
  • Sound wave and memory viewer (In this sense I have a lot of ideas, but it too early to discuss about)
  • Joypad mapping customization

Maybe I'm missing something (I wrote just the basic things), but I think that it can be a very good starting point.
For each of these we could create an issue with discussion and we could divide better the tasks.

We need also to discuss about the contribute guidelines and issues triage.
If I understood correctly we are starting with this technology stack:

  • Rust
  • egui as gui-library (we can discuss about OpenGL for rendering if we want to take a look about performance, but for now I think it is better keep it simple)

Let me know! Feel free to comment about it or to mess everything up.

Add comments on the instructions

Enums used for convenience have shortened names, so sometimes their meaning is not immediate; it might be useful to clarify their meaning.

Documentation of the various instructions can be found here

pub(crate) enum ArmModeAluInstruction {
    And = 0x0,  // AND logical
    Eor = 0x1,  // XOR logical
    ...
    Bic = 0xE,  // Bit clear
}

The same applies to the Condition enum.

It would also be useful to discuss whether or not it is worthwhile to write down not only what they mean, but also how they work. For example, in addition to writing that bic = bit clear, it might be useful to explain that it does: Rd = Rn AND NOT Op2

Add VRAM

First implementation of Video RAM. In future it can require some changes because data are structured in a certain way based on MODE of rendering.

Finish single data transfer ASM

Right now the disassembler part of the single data transfer is not completed.
We should understand what the T flag is and we should format the address for the various cases

Fix `MultipleLoadStore` ASM

Now we have {R0, R1, } in the register list (I mean at the end we would have an additional comma).

Also, to be consistent with the datasheet we should use - to separate registers.

Originally posted by @AlessioC31 in #189 (comment)

Understand access rights for I/O registers

Right now we're creating I/O registers with Read/Write rights since they have to be writable/readable by code (bios for example).
We should maybe investigate a smarter access control, depending on which section of code is executing (bios/user code, etc)

Add `clear` function to `bitwise.rs`

To complete API bitwise, I think we need to implement two more funcion:

  • clear_bits_msb_to_idx(&self, bit_idx: u8) // msb: most significant bit
  • clear_bits_idx_to_0(&self, bit_idx: u8)

Inconsistency in the variable name for opcode

In the processor logic, opcode is often called op_code or opcode. We have to decide which name to use definitely, in order not to confuse, not to have two variables doing the same thing, etc.

I propose opcode. It is easier to write and read. It also reflects the documentation better.

Split and restyle tests

It would be nice to split the tests between the decoding part and the executing part, right now we're testing everything in the same functions.

Also, we should "standardize" how we write these tests. Right now, since they've been written by different people, they are written in many different ways.

Docker support

Clementine could be run within a Docker container. It should be created a proper Dockerfile, documentation and some github action to build and push the container into a public registry when a PR is merged.

PR CI: Add check on rebase

We currently have checks (fmt, test, lint) on PR branches. It would be useful to execute the same set of checks on the "potential" new main branch (PR branch rebased to current main).

This is useful because the PR branch may be not rebased to the main, thus merging the PR could result in broken tests.

Add Palette RAM

To manage correcty some mode of rendering of GBA Display we need to implement Palette RAM.

  • 0x05000000-0x050001FF - BG Palette RAM (512 bytes, 256 colors)
  • 0x05000200-0x050003FF - OBJ Palette RAM (512 bytes, 256 colors)

Wrong size of buffer memory in `internal_memory.rs`

It the documentation we can find:

03000000-03007FFF WRAM - On-chip Work RAM (32 KBytes)
05000000-050003FF BG/OBJ Palette RAM (1 Kbyte)
06000000-06017FFF VRAM - Video RAM (96 KBytes)

but we define them as an array of (take WRAM as example): [u8; 0x7FFF]

0x7FFF = 32767 bytes, but we are missing 1 bytes to get 32 Kbytes!
The right value in this case is 0x8000

This is a problem since we forget to add the last byte in the array. The second parameter is the size of the array (in this case 32 Kbytes) and it is not the last index used to access.

We need to change all the arrays in InternalMemory.

p.s. preparatory to #89

No usage message or help command

Wanting to start contributing to this project I cloned the repo and started reading the code. Before reading any of it I wanted to see it running. Intuitively its pretty easy, just clementine <cartridge>, but no message or help command told me that.
This is just to say, we should add something like a help command or usage message on failed startup. Looks like a good first issue I can do myself.

Tracking issue for cycles

Check if cartridge checksum is correct

It should be in cartridge_header.rs.

Specific in the function:

fn extract_complement_check(data: &[u8]) -> [u8; 1] {
        // TODO: this issue
        data[0x0BD..=0x0BD]
            .try_into()
            .expect("extracting complement check")
    }

Reference here at Complement check header

Palette Visualizer

I checked in the documentation and GBA has many MODES to render the screen.
I'm starting to study the MODE 0 and MODE 1: they use palettes to render some tiles built by memory indices referring to palette RAM.

It can be useful to have a widget to visualize this part of memory and to check colors and palette(s) inside. This is also preparatory to implement the real render algorithm in ppu.rs

From the documentation:

Color Palette RAM
Each BG and OBJ palette RAM may be either split into 16 palettes with 16 colors each, or may be used as a single palette with 256 colors.

Color Definitions
Each color occupies two bytes (same for 327688 BG modes):
[0-4] Red Intensity (0-31)
[5-9] Green Intensity (0-31)
[10-14] Blue Intensity (0-31)
15 Not used

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤ī¸ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.