From e5e4b31f2d9f802233997df7f030e266587e8b7d Mon Sep 17 00:00:00 2001 From: "Janni K." <24881711+nummacway@users.noreply.github.com> Date: Sat, 1 Nov 2025 17:22:54 +0100 Subject: [PATCH 1/4] Simplifying IncreaseScorePackedBCD as per #127 --- unbricked/bcd/main.asm | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/unbricked/bcd/main.asm b/unbricked/bcd/main.asm index 5f9747b..90d994c 100644 --- a/unbricked/bcd/main.asm +++ b/unbricked/bcd/main.asm @@ -294,11 +294,10 @@ IsWallTile: ; Increase score by 1 and store it as a 1 byte packed BCD number ; changes A and HL IncreaseScorePackedBCD: - xor a ; clear carry flag and a - inc a ; a = 1 - ld hl, wScore ; load score - adc [hl] ; add 1 - daa ; convert to BCD + ld hl, wScore ; load score address for faster access + ld a, [hl] ; load score to accumulator + add 1 + daa ; make sure it's a BCD ld [hl], a ; store score call UpdateScoreBoard ret @@ -754,4 +753,4 @@ wBallMomentumY: db ; ANCHOR: score-variable SECTION "Score", WRAM0 wScore: db -; ANCHOR_END: score-variable \ No newline at end of file +; ANCHOR_END: score-variable From 10e71fa3afb52c841761d812f38104752e11dd49 Mon Sep 17 00:00:00 2001 From: "Janni K." <24881711+nummacway@users.noreply.github.com> Date: Sat, 1 Nov 2025 18:28:44 +0100 Subject: [PATCH 2/4] Updated and extended prose to match code adjustments for #127 Also changed a link because that old link was too much text when gbz80(7) explains the same thing in such a beautifully concise way. This allowed explaining the use of ADD 1 instead of INC. --- src/part2/bcd.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/part2/bcd.md b/src/part2/bcd.md index eb6926f..4523bce 100644 --- a/src/part2/bcd.md +++ b/src/part2/bcd.md @@ -38,15 +38,19 @@ Don't worry about the call to `UpdateScoreBoard`, we'll get into that in a bit. ``` Let's have a look at what's going on there: -We set A to 1 and clear the carry flag -We add the score variable (contents of memory location `wScore`) to a, so now A has our increased score. + +First we store the score address (`wScore`) in HL. Doing so is 1 cycle and 1 byte more efficient than if we provided it when loading and storing the score. + +Then we load the the score from that address in HL into register A. Now we can increment it by 1. So far so good, but what if the score was 9 and we add 1? The processor thinks in binary only and will do the following math: `%00001001` + `%00000001` = `%00001010` = `$A` That's a hexadecimal representation of 10, and we need to adjust it to become decimal. `DAA` or "Decimal Adjust after Addition," does just that. -After executing `DAA` our accumulator will be adjusted from `%00001010` to `%00010000`; a 1 in the left nibble and a 0 in the right one. A more detailed article about `DAA` on the Game Boy can be found [here](https://blog.ollien.com/posts/gb-daa/). +After executing `DAA` our accumulator will be adjusted from `%00001010` to `%00010000`; a 1 in the left nibble and a 0 in the right one. `DAA`'s exact behaviour is described [here](https://rgbds.gbdev.io/docs/master/gbz80.7#DAA). + +But why do we increment A using `ADD 1` when `INC` does the same but is more efficient? That's because `DAA` evaluates the carry flag (see the linked description), but that one is unaffected by `INC`. So if the carry flag was still set from a previous operation, `DAA` would add 60 points. Then we store the score back into `wScore` and finally, we call a function that will update the score board, which we will implement next. @@ -103,4 +107,4 @@ We then add the `DIGIT_OFFSET` constant to the tens digit to calculate the tile Finally, we repeat the process for the ones digit: We mask the tens digit from `A` using `and %00001111`, no need to rotate this time. -Now we can display the score on the screen! We'll need to call `UpdateScoreBoard` after each time the score is updated. We've already done this in the `IncreaseScorePackedBCD` function, so we're all set! \ No newline at end of file +Now we can display the score on the screen! We'll need to call `UpdateScoreBoard` after each time the score is updated. We've already done this in the `IncreaseScorePackedBCD` function, so we're all set! From 99f9c5c52bfa1c814691229f0b91bb5922027667 Mon Sep 17 00:00:00 2001 From: "Janni K." <24881711+nummacway@users.noreply.github.com> Date: Sat, 1 Nov 2025 18:53:11 +0100 Subject: [PATCH 3/4] Improved wording to be clearer --- src/part2/bcd.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/part2/bcd.md b/src/part2/bcd.md index 4523bce..056df62 100644 --- a/src/part2/bcd.md +++ b/src/part2/bcd.md @@ -39,9 +39,9 @@ Don't worry about the call to `UpdateScoreBoard`, we'll get into that in a bit. Let's have a look at what's going on there: -First we store the score address (`wScore`) in HL. Doing so is 1 cycle and 1 byte more efficient than if we provided it when loading and storing the score. +First we store the score address (`wScore`) in HL. Doing so is 1 M-cycle and 1 byte more efficient than if we provided the address when loading and storing the score (`LD A, [wScore]` and `LD [wScore], A` respectively). -Then we load the the score from that address in HL into register A. Now we can increment it by 1. +Then we load the the score from that address into register A, the only register to be affected by `ADD`. This means that we can now increment it by 1. So far so good, but what if the score was 9 and we add 1? The processor thinks in binary only and will do the following math: @@ -50,9 +50,9 @@ So far so good, but what if the score was 9 and we add 1? The processor thinks i That's a hexadecimal representation of 10, and we need to adjust it to become decimal. `DAA` or "Decimal Adjust after Addition," does just that. After executing `DAA` our accumulator will be adjusted from `%00001010` to `%00010000`; a 1 in the left nibble and a 0 in the right one. `DAA`'s exact behaviour is described [here](https://rgbds.gbdev.io/docs/master/gbz80.7#DAA). -But why do we increment A using `ADD 1` when `INC` does the same but is more efficient? That's because `DAA` evaluates the carry flag (see the linked description), but that one is unaffected by `INC`. So if the carry flag was still set from a previous operation, `DAA` would add 60 points. +But why do we increment A using `ADD 1` when `INC A` does the same but is more efficient? That's because `DAA` evaluates the carry flag (see the linked description), but unlike `ADD`, `INC` does not affect that flag. So if the carry flag was still set from a previous operation, `DAA` would add 60 points. -Then we store the score back into `wScore` and finally, we call a function that will update the score board, which we will implement next. +Now that score (in A) has been properly incremented, we store it back into `wScore` and finally, we call a function that will update the score board, which we will implement next. Of course, we still need to call it on impact. To do this, we add a call to `IncreaseScorePackedBCD` after each collision handler (we had a left and a right collision) in `CheckAndHandleBrick` From 7953d02247306c2249aa0645c5018411126c21af Mon Sep 17 00:00:00 2001 From: "Janni K." <24881711+nummacway@users.noreply.github.com> Date: Sat, 1 Nov 2025 19:01:07 +0100 Subject: [PATCH 4/4] Improved wording to be even clearer --- src/part2/bcd.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/part2/bcd.md b/src/part2/bcd.md index 056df62..bb5cac9 100644 --- a/src/part2/bcd.md +++ b/src/part2/bcd.md @@ -39,9 +39,9 @@ Don't worry about the call to `UpdateScoreBoard`, we'll get into that in a bit. Let's have a look at what's going on there: -First we store the score address (`wScore`) in HL. Doing so is 1 M-cycle and 1 byte more efficient than if we provided the address when loading and storing the score (`LD A, [wScore]` and `LD [wScore], A` respectively). +First we store the score address (`wScore`) in HL. This allows us to use instructions like `LD A, [HL]` and `LD [HL], A`. In total this is 1 M-cycle and 1 byte more efficient than if we provided the address itself when loading and storing the score (`LD A, [wScore]` and `LD [wScore], A` respectively). -Then we load the the score from that address into register A, the only register to be affected by `ADD`. This means that we can now increment it by 1. +Then we load the the score from that address into register A, the only register to be affected by `ADD`. This means that we can now increment it by 1 using exactly that instruction. So far so good, but what if the score was 9 and we add 1? The processor thinks in binary only and will do the following math: