gbdev / gbdev/rgbds

Facilitating cycle-counted code

Open
#2,033 0 comments 1 reaction 0 assignees View on GitHub
enhancement rgbasm
Dominant language
C++
Stars
1.6k
Forks
193
Avg merge
22h 17m
Merged PRs (30d)
26

Description

*This is niche, but I think we can provide an interesting, and dare I say innovative, improvement with relatively little effort.*

*Rationale.* Sometimes we write timed code, for example because we're syncing to the PPU. The common practice is to write something like this:

```asm
halt
ld a, [de] ; 2
ld [hli], a ; 2
inc e ; 1
; 5 is less than 16, so we're good.
```

...this is manual and error-prone, so I'd like a way to automate (parts of) this. I think we could have a `__CYCLES__` variable, which can be modified like any other, but that also gets automatically increased by however many cycles each instruction takes.

```asm
halt
def __CYCLES__ = 0
ld a, [de]
ld [hli], a
inc e
assert __CYCLES__ <= 16, "Overflowed safe VRAM access time!"
```

*Edge cases.*

- `db` is sometimes used for code. I think this shouldn't be taken into account, as the user can adjust `__CYCLES__` themselves as necessary. For example:
```asm
MACRO code_db
db \#
def __CYCLES__ += _NARG
ENDM
```
- Control flow instructions should not be treated specially (no attempt made to do any kind of control flow analysis).
- *Conditional* instructions should be handled in a way as useful as we can make it while keeping it useful. I think treating them as untaken always achieves that goal, as either all branches take the same number of cycles (e.g. `jr nc, .noCarry :: inc h :: .noCarry`) or a single measure isn't going to be sufficient anyway.
- Opening a section should automatically `def __CYCLES__ = 0` for convenience. We don't need to provide an opt-out, since I expect that would be rare, and it can be done manually with
```asm
def cycles equ __CYCLES__
SECTION "...", ROM0
def __CYCLES__ = cycles
```

Contributor guide

Open the contributing guide

Research direction

Start by tracing how the assembler represents instruction cycle counts, evaluates `def` and `assert`, and opens sections. Check how conditional instructions and `db` are currently handled before deciding where `__CYCLES__` updates belong. Done means the proposed counter behavior and listed edge cases are implemented with coverage for representative instruction, section, and assertion cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers, devtools
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.