Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)
You are not logged in.
Hello!
Is there a better way to apply module operation to a number?
x = number % 10
I have read that "%" is not efficient enough in gbdk
Thanks!
Offline
Wow, great idea!
Thanks a lot
Offline
If you don't mind wasting some space, you could use a lookup table.
(Note: I'm new, so hopefully what I just said isn't a bad idea)
Last edited by h0tp3ngu1n (2019-12-14 19:45:20)
Offline
It's interesting too, thanks h0tp3ngu1n.
Offline
if you need decimal numbers to count score, for example, you may use BCD numbers. i wrote some routines to deal with 8-digit (4-byte) BCD numbers. something like this:
#include "bcd.h"
BCD bcd_timer_value = {{0, 0, 0, 0}}; // decimal 12345678 will be {{0x78, 0x56, 0x34, 0x12}}
BCD bcd_addend = {{1, 0, 0, 0}};
unsigned char text[9]; // at least 8+1 symbols
// ...
while (1) {
// ...
bcd_add(&bcd_timer_value, &bcd_addend);
set_bkg_tiles(6, 1, bcd2text(&bcd_timer_value, 0x2D, text), 1, text); // 0x2d - offset for zero digit tile
}so, the % 10 for this bcd value will be: bcd_timer_value.bytes[0] & 0x0f (the lower nibble of the lower byte of the 4-byte BCD number)
the bcd.h file:
typedef struct { unsigned char bytes[4]; } BCD;
void bcd_add(BCD * sour, BCD * value) __naked
{
sour; value; // suppress warninig: unreferenced function argument
__asm
lda HL, 5(SP)
ld D, (HL)
dec HL
ld E, (HL) ; DE: value
dec HL
ld A, (HL-)
ld L, (HL)
ld H, A ; HL: sour
or A ; clear C, HC
ld A,(DE)
add (HL)
daa
ld (HL+), A
inc DE
ld A,(DE)
adc (HL)
daa
ld (HL+), A
inc DE
ld A,(DE)
adc (HL)
daa
ld (HL+), A
inc DE
ld A,(DE)
adc (HL)
daa
ld (HL+), A
ret
__endasm;
}
void bcd_sub(BCD * sour, BCD * value) __naked
{
sour; value; // suppress warninig: unreferenced function argument
__asm
lda HL, 2(SP)
ld E, (HL)
inc HL
ld D, (HL) ; DE: sour
inc HL
ld A, (HL+)
ld H, (HL)
ld L, A ; HL: value
or A ; clear C, HC
ld A,(DE)
sub (HL)
daa
ld (DE), A
inc DE
inc HL
ld A,(DE)
sbc (HL)
daa
ld (DE), A
inc DE
inc HL
ld A,(DE)
sbc (HL)
daa
ld (DE), A
inc DE
inc HL
ld A,(DE)
sbc (HL)
daa
ld (DE), A
ret
__endasm;
}
UBYTE bcd2text(BCD * bcd, UBYTE tile_offset, unsigned char * buffer) __naked
{
bcd; tile_offset; buffer;
__asm
push BC
lda HL, 4(SP)
ld E, (HL)
inc HL
ld D, (HL) ; DE: bcd
inc HL
ld B, #0
ld C, (HL) ; C: digit offset
inc HL
ld A, (HL+)
ld H, (HL)
ld L, A ; HL: buffer
inc DE
inc DE
inc DE
ld A, (DE)
srl A
srl A
srl A
srl A
jr Z, $bcdtxt01
add C
ld (HL+), A
inc B
$bcdtxt01: ld A, (DE)
and #0x0f
or B
jr Z, $bcdtxt02
ld A, (DE)
and #0x0f
add C
ld (HL+), A
inc B
$bcdtxt02: ld A, (DE)
dec DE
ld A, (DE)
srl A
srl A
srl A
srl A
or B
jr Z, $bcdtxt03
ld A, (DE)
srl A
srl A
srl A
srl A
add C
ld (HL+), A
inc B
$bcdtxt03: ld A, (DE)
and #0x0f
or B
jr Z, $bcdtxt04
ld A, (DE)
and #0x0f
add C
ld (HL+), A
inc B
$bcdtxt04: ld A, (DE)
dec DE
ld A, (DE)
srl A
srl A
srl A
srl A
or B
jr Z, $bcdtxt05
ld A, (DE)
srl A
srl A
srl A
srl A
add C
ld (HL+), A
inc B
$bcdtxt05: ld A, (DE)
and #0x0f
or B
jr Z, $bcdtxt06
ld A, (DE)
and #0x0f
add C
ld (HL+), A
inc B
$bcdtxt06: ld A, (DE)
dec DE
ld A, (DE)
srl A
srl A
srl A
srl A
or B
jr Z, $bcdtxt07
ld A, (DE)
srl A
srl A
srl A
srl A
add C
ld (HL+), A
inc B
$bcdtxt07: ld A, (DE)
and #0x0f
add C
ld (HL+), A
inc B
xor A, A
ld (HL+), A
ld D, A
ld E, B
pop BC
ret
__endasm;
}Last edited by toxa (2020-02-28 06:28:05)
Offline
ps: and a compare function, returns -1 when A<B; 1 when A>B and 0 when equal
BYTE bcd_compare(BCD * A, BCD * B) __naked
{
A; B;
__asm
lda HL, 2(SP)
ld E, (HL)
inc HL
ld D, (HL) ; DE: sour
inc HL
ld A, (HL+)
ld H, (HL)
ld L, A ; HL: value
inc DE
inc DE
inc DE
inc HL
inc HL
inc HL
ld A, (DE)
cp (HL)
jr Z, $bcdcmp01
jr C, $bcdcmp_aB
$bcdcmp_Ab:
ld DE, #0x0001
ret
$bcdcmp_aB:
ld DE, #0xffff
ret
$bcdcmp01:
dec DE
dec HL
ld A, (DE)
cp (HL)
jr Z, $bcdcmp02
jr C, $bcdcmp_aB
jr $bcdcmp_Ab
$bcdcmp02:
dec DE
dec HL
ld A, (DE)
cp (HL)
jr Z, $bcdcmp03
jr C, $bcdcmp_aB
jr $bcdcmp_Ab
$bcdcmp03:
dec DE
dec HL
ld A, (DE)
cp (HL)
jr C, $bcdcmp_aB
jr NZ, $bcdcmp_Ab
ld DE, #0x0000
ret
__endasm;
}Offline