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

GB ASM Tutorial Cheatsheet #68

Merged
merged 65 commits into from
Mar 5, 2024

Conversation

LaroldsJubilantJunkyard
Copy link
Contributor

The goal of the cheatsheet is a bunch of concise snippets and explanations on how to do common tasks. i expect a bunch of wording/order/best practice comments/suggestions/changes. This time around, let me have'm.

As a plan of action, let's try avoid adding extra stuff in this initial PR. Why? I had to remove some topics because i realized the list could go on forever, and it would take wayyyy more time than i have. Which would start crunching with other tasks and ultimately delay actual release.

Copy link
Member

@ISSOtm ISSOtm left a comment

Choose a reason for hiding this comment

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

I only read through the first part, but this review is significant enough as-is.

src/cheatsheet.md Outdated Show resolved Hide resolved
src/SUMMARY.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved

### How to wait for the vertical blank phase

To check for the vertical blank phase, use the `rLY` register. Compare that register's value against the height of the Game Boy screen in pixels: 144.
Copy link
Member

Choose a reason for hiding this comment

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

I get that this is meant to be a cheat sheet, but there are at least three ways to do this (LY, STAT, and VBlank handler), each with their own pros and cons; so enjoining people to use only one of these three feels wrong.

Then again, perhaps I am applying the wrong scope in trying to convey here all of the subtle differences between all of those various ways... I don't know. I feel like it should be documented somewhere at least.

Can @Rangi42 help? I believe you have written most of this, so you may have some insight. (And perhaps that document could be merged with this one, to increase its visibility?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let's find the most common way, and then maybe leave links and notes about where to find info for the other ways and documentation about the technical differences?

Copy link
Member

Choose a reason for hiding this comment

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

I agree with the sentiment. But for this one specifically, even that won't work..!

The two common ways are LY and VBlank handler, and the latter is inherently dependent on said handler. The former is used mostly when the handler hasn't been set up yet (i.e. when turning off the LCD during boot-up), and the latter everywhere else.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with the sentiment. But for this one specifically, even that won't work..!

The two common ways are LY and VBlank handler, and the latter is inherently dependent on said handler. The former is used mostly when the handler hasn't been set up yet (i.e. when turning off the LCD during boot-up), and the latter everywhere else.

Yeahhh... i don't understand that :D

Copy link
Member

Choose a reason for hiding this comment

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

Can we introduce the three ways and just explain/describe one for the time being?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What's a good gameplan here? I don't know "the three ways"

I don't think the vblank handler fits in the same entry. This is how to do nothing except wait for vblank.

That's the purpose of the snippet?

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, I was perhaps a bit too brief in my previous comment. I'm responding to the debate/confusion surrounding which technique should be highlighted here.

Briefly:

  • the LY way (as it is in the text currently) is the best candidate for "how to wait for VBlank".
  • the VBlank handler is an important topic that should be covered, but is a separate thing that should be treated as such (e.g. a separate entry / under a different heading)
  • It's easier to understand LY than using STAT -- loosely: scanlines are "real" but PPU is a black box.

Not briefly:

  • I think it's reasonable to say that the way (recommended way, in general, etc.) to wait for VBlank is to enter a busy loop and read LY until scanline 144. This is "doing nothing except waiting".
    • This is essentially what the text is already saying. The snippet is fine.
    • Ideally the text will not give too strong an impression that that's the only way to do anything re. VBlank.
  • My point about the VBlank interrupt handler is that it doesn't need to be considered as a competing technique to LY144 as the usual point of using it is significantly different to waiting for VBlank. They serve different purposes.
    • The VBlank interrupt is for efficient game loop synchronisation in concert with halt (in general, etc.)
    • I would recommend not using a busy loop to synchronise a game loop.
  • verbose: The implication of doing nothing except waiting is that the program has nothing else to do, or nothing better to do at that time (or no other reliable means to "V-sync"). Using halt to wait for the VBlank interrupt and save power would be an example of something better to do, if all the program is doing is delaying until the next frame (synchronising the game loop).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess I sort of get what youre saying... Maybe that should be an addition later down the line? Unless someone else wants to submit the code snippet...

Copy link
Member

Choose a reason for hiding this comment

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

I think it shouldn't be a code snippet, then; but that this one's description should at least hint at the use of halt instead of this, whenever available. Perhaps with a link to the relevant section of the tutorial that explains that (if there isn't one yet, that's fine, and we'll open an issue to remind us later).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it shouldn't be a code snippet, then; but that this one's description should at least hint at the use of halt instead of this, whenever available. Perhaps with a link to the relevant section of the tutorial that explains that (if there isn't one yet, that's fine, and we'll open an issue to remind us later).

Sure, I can do that. I'm not familiar with halt, can you give me some documentation links or a snippet to add?

src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved

### How to wait for the vertical blank phase

To check for the vertical blank phase, use the `rLY` register. Compare that register's value against the height of the Game Boy screen in pixels: 144.
Copy link
Member

Choose a reason for hiding this comment

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

Can we introduce the three ways and just explain/describe one for the time being?

src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
@avivace avivace requested review from avivace and ISSOtm November 26, 2023 21:08
finishing save data
changing rand text per suggestion
Completing save task list
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
Copy link
Contributor

@quinnyo quinnyo left a comment

Choose a reason for hiding this comment

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

I've marked a bunch of (mostly small) specific things (in the first half or so, at least).

src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
Comment on lines 140 to 158
By default, the window and background layer will use the same tilemap. That is, any tiles you draw on the background will be mirrored on the window and vice versa.

For the window and background, there are 2 memory regions they can use: `$9800` and `$9C00`. For more information, refer to the [Pan Docs](https://gbdev.io/pandocs/Tile_Maps.html)

Which region the background uses is controlled by the 4th bit of the `rLCDC` register. Which region the window uses is controlled by the 7th bit.

You can use one of the 4 constants to specify which layer uses which region:

- LCDCF_WIN9800
- LCDCF_WIN9C00
- LCDCF_BG9800
- LCDCF_BG9C00

::: tip Note

You still need to make sure the window and background are turned on when using these constants.

:::

Copy link
Contributor

Choose a reason for hiding this comment

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

This is a lot of detail information.
This entry has no snippet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a lot of detail information. This entry has no snippet.

is it critical to have a snippet? it's just explaining the purpose of the section

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not saying that it has to have a snippet necessarily, it just seemed to be less of a concise cheatsheet tip than the other sections.

I guess I don't have any specific, actionable advice and the text isn't wrong, so you can probably ignore this.

src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
Copy link
Member

@ISSOtm ISSOtm left a comment

Choose a reason for hiding this comment

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

These are some old comments from when I had started reviewing this. I wasn't able to muster enough energy to review the entire PR, sorry.


### How to turn on/off the background

To turn the background layer on and off, alter the least significant bit of the `rLCDC` register. You can use the `LCDCF_BGON` and `LCDCF_BGOFF` constants for this.
Copy link
Member

Choose a reason for hiding this comment

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

Actually, those constants are only meant to be OR'd; so either as part of a | expression, or the operand to a or instruction. All of the LCDCF_*OFF constants are only useful for the former. Thus I'm not sure if we should mention them in this section.

Copy link
Member

Choose a reason for hiding this comment

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

Note also that this has different behaviour on DMG and CGB, and it doesn't allow access to VRAM even when off; so I don't think this section is much use at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note also that this has different behaviour on DMG and CGB, and it doesn't allow access to VRAM even when off; so I don't think this section is much use at all?

Should i remove this section?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I think that's better. I'd assume people interested will read Pan Docs, and figure out how to modify the other, similar snippets. It shouldn't hurt to focus on the most useful ones rather than try to be exhaustive, for a cheat sheet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note also that this has different behaviour on DMG and CGB, and it doesn't allow access to VRAM even when off; so I don't think this section is much use at all?

It's an easy remove , but What's the behavior difference? I guess part of me feels like turning on/ off the window at least is common.

src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
src/cheatsheet.md Outdated Show resolved Hide resolved
Copy link
Member

@avivace avivace left a comment

Choose a reason for hiding this comment

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

So, after discussing with @ISSOtm we decided to merge this in the current situation with the following reservations:

  • This "cheatsheet" probably doesn't fit the scope (and the resources) of this project. We should think about moving it to Pan Docs or to gbdev.io/guides in the next future.
  • The open unresolved threads will be moved to Issues so we can keep working on them
  • From now on, PR should be shorter and brief, so in this case it would've been better to add one snippet at the time to make the maintainers (and other potential contributors) easier.

@avivace avivace merged commit d3f93b5 into gbdev:master Mar 5, 2024
1 check failed
avivace added a commit that referenced this pull request Mar 5, 2024
---------

Co-authored-by: Antonio Vivace <[email protected]>
Co-authored-by: Eldred Habert <[email protected]>
Co-authored-by: Damian Yerrick <[email protected]>
Co-authored-by: Evie <[email protected]>
Co-authored-by: Quinn <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants