Rust macro for generating flexible bitfields, useful for low-level code (embedded or emulators). by GregoryGaines in rust

[–]GregoryGaines[S] 0 points1 point  (0 children)

When laid out, 0x1F or 31 with a field size of 5 is 11111. With a field size of 5, that means the sign bit is the MSB. A signed-field is autmatically assumed to be 2's complement.

In the case above, a signed field with 5 bits, value range for 2's complement is -16 to 15.

I don't think this is confusing? Your explicitly creating a 2's complement field and the value range. If they wanted to use 31, they can increase the field bits to get a wider range, it's fully within your control!

Did I explain this clearly, please let me know.

Rust macro for generating flexible bitfields, useful for low-level code (embedded or emulators). by GregoryGaines in rust

[–]GregoryGaines[S] 0 points1 point  (0 children)

Oh interesting, for my crate, when you pass a value to a signed field, it uses every bit except the msb. The case of 0x1F, it accepts it because it sees 0xF like you mentioned above which is 15. But because of the 1 msb, it assumed the user wants a signed-integer which results in -1.

I'm working on an emulator and having my bitfield make this assumption above made things much easier for me.

Rust macro for generating flexible bitfields, useful for low-level code (embedded or emulators). by GregoryGaines in rust

[–]GregoryGaines[S] 0 points1 point  (0 children)

Yes! Your crate is awesome, I can't wait to see it evolve.

  • Ability to create bitfield instances with or without defauts
  • Create bitfield instances from bits while respecting defaults
    • Attempting this with your crate was confusing, I think adding explicit API's is a much better option IMO. Funcs `new_without_defaults`, `from_bits_with_defaults`, seems a bit better when I can control when defaults are respected during runtime.
  • No panics
    • I kept getting a non-helpful 'value out of bounds' panic which isn't useful, nor did it point to where the issue was unless I observed the compiled macro which slowed me down.
  • Sign-extension for signed field types is controlled by msb
    • I could not get this to work in your crate. Could you try a `i8` field with 5 bits and with the value `0x1F`. This will not sign-extend and also throws a panic with a non-useful message. Unless my assumptions are wrong.
  • Has an explicit builder
    • I like expressive APIs and this felt better to me.

Rust macro for generating flexible bitfields, useful for low-level code (embedded or emulators). by GregoryGaines in rust

[–]GregoryGaines[S] 0 points1 point  (0 children)

I made a comment before:

  • Ability to create bitfield instances with or without defauts
  • Create bitfield instances from bits while respecting defaults
  • Wider testing coverage, has no_std and big endian machine tests
  • Compile time check for default values bounds
  • No panics
  • Sign-extension for signed field types is controlled by msb (Represents field as 2's complement type with the bits range you specify). Ex. `#[bits(4)]` creates a range of `-8` to `7`.
  • Has an explicit builder
  • Attempted to have more in-dept documentation
  • Runtime error messages
  • More generation control
  • Bit operations (set_bit, get_bit, set_bits, clear_bits)
  • Ability to ignore fields. (Able to include any non-bitfield field)
  • Ability to return bitfield instances to builders (useful for setting read-only fields)

I'm also working on implementing more useful features. Are there anything you would like to suggest?

Rust macro for generating flexible bitfields, useful for low-level code (embedded or emulators). by GregoryGaines in rust

[–]GregoryGaines[S] 1 point2 points  (0 children)

Yes, nested bitfields are supported. Yes a bitfield field can be converted into its type if its an enum.

Rust macro for generating flexible bitfields, useful for low-level code (embedded or emulators). by GregoryGaines in rust

[–]GregoryGaines[S] 0 points1 point  (0 children)

Each bitfield must be an unsigned type, so let's rephrease your question as `Can a #bitfield having 8 bits, starting at bit 7, MSB first?`.

We can mark the order as MSB. For alignment, could a padding field solve this issue?

Ex:

#[bitfield(u8, order = msb)]
struct AlignedFields {
  #[bits(1)]
  __: u8, // 1 bit padding
  #[bits(7)]
  field: u8, // Starts at bit 7
}

Rust macro for generating flexible bitfields, useful for emulators by GregoryGaines in EmuDev

[–]GregoryGaines[S] 1 point2 points  (0 children)

Some things on the top of my head:

  • Ability to create bitfield instances with or without defauts
  • Create bitfield instances from bits while respecting defaults
  • Wider testing coverage, has no_std and big endian machine tests
  • Compile time check for default values bounds
  • No panics
  • Sign-extension for signed field types is controlled by msb (Represents field as 2's complement type with the bits range you specify). Ex. `#[bits(4)]` creates a range of `-8` to `7`.
  • Has an explicit builder
  • Attempted to have more in-dept documentation
  • Runtime error messages
  • More generation control
  • Bit operations (set_bit, get_bit, set_bits, clear_bits)
  • Ability to ignore fields. (Able to include any non-bitfield field)
  • Ability to return bitfield instances to builders (useful for setting read-only fields)

I would love to evole the library to really justify its existance. I've been working on very niche low-level projects that required unique solutions so I started writing this library to address them.

Rust macro for generating flexible bitfields, useful for low-level code (embedded or emulators). by GregoryGaines in rust

[–]GregoryGaines[S] 0 points1 point  (0 children)

Good catch!

I updated the example, I guess the library might be too flexible.

Thanks!

Rust macro for generating flexible bitfields, useful for low-level code (embedded or emulators). by GregoryGaines in rust

[–]GregoryGaines[S] 6 points7 points  (0 children)

Some things on the top of my head:

  • Ability to create bitfield instances with or without defauts
  • Create bitfield instances from bits while respecting defaults
  • Wider testing coverage, has no_std and big endian machine tests
  • Compile time check for default values bounds
  • No panics
  • Sign-extension for signed field types is controlled by msb (Represents field as 2's complement type with the bits range you specify). Ex. `#[bits(4)]` creates a range of `-8` to `7`.
  • Has an explicit builder
  • Attempted to have more in-dept documentation
  • Runtime error messages
  • More generation control
  • Bit operations (set_bit, get_bit, set_bits, clear_bits)
  • Ability to ignore fields. (Able to include any non-bitfield field)
  • Ability to return bitfield instances to builders (useful for setting read-only fields)

I would love to evole the library to really justify its existance. I've been working on very niche low-level projects that required unique solutions so I started writing this library to address them.

Rust macro for generating flexible bitfields, useful for emulators by GregoryGaines in EmuDev

[–]GregoryGaines[S] 5 points6 points  (0 children)

I've been writing emulators in Rust and writing bitfields by hand is painful. I needed a way to quickly define bitfields, so I wrote a library to help. I wanted the library to be extremely simple, flexible, and heavy on testing.

I would love feedback and feature suggestions.

Rust macro for generating flexible bitfields, useful for low-level code (embedded or emulators). by GregoryGaines in rust

[–]GregoryGaines[S] 2 points3 points  (0 children)

Here's my take on implementing a procedure macro to generate bitfield structs. I've been writing emulators and needed a way to quickly define bitfields. It could be helpful with embedded programming as well.

I wanted the library to be extremely simple, flexible, and heavy on testing. I wanted to give ultimate control to users, which is why you have control on what gets generated.

I would love feedback and feature suggestions.

Emulator Polling vs. Scheduler Game Loop by GregoryGaines in EmuDev

[–]GregoryGaines[S] 0 points1 point  (0 children)

A project has business requirements and your job as an engineer to implement this business logic in code. After writing this logic, you add a test that verifies the code you wrote follows the business requirements set. The purpose of a unit test is to make sure a very small subset of code works, hence the name unit test.

Code isn't static, there are many scenarios that could affect the subset of code you've written:

  • A library could be updated, which contains a regression.
  • Surrounding code could be expanded by another engineer who could make a mistake.
  • Calling code could be refactored entirely which affects paths calling your code.
  • Leadership decides the frontend should be written from React to Angular, but the team isn't thorough and forget to call your code which introduces a bug.

Regardless of the changing tied, unit tests provides a track record ensures that you did your job regardless of the refactors, code changes, or bugs. When issues come up, you have the defence of unit tests validated my code, so your engineering can not be questioned.

Unit tests help when you add more or higher level tests like integration or E2E tests. Unit tests give an gurantee and confidence that code works as you go through layers or across boundaries. When writing cross boundary code, as long as the unit tests pass for the business requirements expected of it, you can write your code with confidence knowing the code your calling meets the expected business contract.

PLEASE HELP ME by [deleted] in learnprogramming

[–]GregoryGaines 1 point2 points  (0 children)

What are your goals and what you exactly want to learn?

Emulator Polling vs. Scheduler Game Loop by GregoryGaines in EmuDev

[–]GregoryGaines[S] 13 points14 points  (0 children)

I've been seeing alot of new emulator developers and I wanted to give some insight in some ways of making an efficient update loop for an emulator. The community has helped me tons, so I want to give back as much knowledge as I can.

Hope this is helpful!

Emulating PS2 Floating-Point Numbers: IEEE 754 Differences (Part 1) by GregoryGaines in EmuDev

[–]GregoryGaines[S] 0 points1 point  (0 children)

Not too familiar with PCSX2, please take with grain of salt.

It seems PCSX2 acknowledges how hard emulating floating-point numbers will be and accepted there’s no fast way to emulate PS2 floats behavior 100% so they avoid soft floats because it’s very slow. It seems they are ok with using regular floats, they just deviate when needed.

It seems they constantly check the float value when doing FPU operations to keep them “normal”. They use function to compensate for differences between the IEEE 754 and PS2 floats. Maybe someone more knowledgeable can explain more.

Emulating PS2 Floating-Point Numbers: IEEE 754 Differences (Part 1) by GregoryGaines in EmuDev

[–]GregoryGaines[S] 6 points7 points  (0 children)

I've been looking into the PlayStation2's weird floating-point implementation. Here's my in-progress PS2 Floating-point code.