ポケモン赤緑で素数を列挙する

ポケモン赤緑素数を列挙しました。 9999までの素数を列挙できます。

f:id:fujidig:20220111224419p:plain:w500

バイナリ

d9b3から開始です。

21 93 da 06 00 0e 64 3e 01 cd 18 37 01 02 00 21
93 da 09 7e b7 28 15 c5 59 79 87 fe 64 30 0c 21
93 da 06 00 4f 09 36 00 83 18 f0 c1 0c 79 fe 64
20 dd 01 02 00 11 f7 da 21 93 da 09 7e b7 28 03
79 12 13 0c 79 fe 64 20 ef 11 02 00 cd 17 da e5
cd 67 38 e1 fa b3 ff cb 47 28 07 54 5d cd 17 da
18 ed 18 eb 21 a0 c3 0e 00 d5 d5 e5 c5 cd 7f da
c1 e1 d1 3e 14 85 6f 30 01 24 c5 e5 cd 3e da e1
c1 0c 79 fe 12 20 e3 62 6b d1 c9 13 cd 49 da b7
28 01 c9 13 18 f6 7a b7 20 0b 7b fe 64 30 06 21
93 da 19 7e c9 0e 19 21 f7 da af e0 95 e0 96 7a
e0 97 7b e0 98 7e e0 99 06 04 cd f0 38 f0 99 b7
20 03 3e 00 c9 23 0d 20 e1 3e 01 c9 e5 e5 f8 02
72 23 73 f8 02 54 5d e1 01 04 c2 cd 7d 3c e1 c9

ソースコード

N = 100
FillMemory = 0x3718
PrintNumber = 0x3C7D
JoypadLowSensitivity = 0x3867
Divide = 0x38F0
hJoyPressed = 0xffb3
prime_table = sieve_table + N
prime_table_size = 25

[org(0xd9b3)]
first:
    ld hl, sieve_table
    ld b, 0
    ld c, N
    ld a, 1
    call FillMemory
    ld bc, 2
sieve_loop:
    ld hl, sieve_table
    add hl, bc
    ld a, [hl]
    or a
    jr z, sieve_skip
    push bc
    ld e, c
    ld a, c
    add a, a
sieve_inner_loop:
    cp N
    jr nc, sieve_inner_loop_end
    ld hl, sieve_table
    ld b, 0
    ld c, a
    add hl, bc
    ld [hl], 0
    add a, e
    jr sieve_inner_loop
sieve_inner_loop_end:
    pop bc
sieve_skip:
    inc c
    ld a, c
    cp N
    jr nz, sieve_loop

make_prime_table:
    ld bc, 2
    ld de, prime_table
make_prime_table_loop:
    ld hl, sieve_table
    add hl, bc
    ld a, [hl]
    or a
    jr z, make_prime_table_skip
    ld a, c
    ld [de], a
    inc de
make_prime_table_skip:
    inc c
    ld a, c
    cp N
    jr nz, make_prime_table_loop
main:
    ld de, 2
    call printprimes
mainloop:
    push hl
    call JoypadLowSensitivity
    pop hl
    ld a, [hJoyPressed]
    bit 0, a
    jr z, ifnotapressed
    ld d, h
    ld e, l
    call printprimes
    jr mainloop
ifnotapressed:
    jr mainloop

printprimes:
    ld   hl, 0xC3A0
    ld c, 0
    push de
printprimesloop:
    push de
        push hl
            push bc
                call print
            pop bc
        pop hl
    pop de
    ld a, 0x14
    add a, l
    ld l,a
    jr nc, skipincrh
    inc h
skipincrh:
    push bc
        push hl
            call next_prime
        pop hl
    pop bc
    inc c
    ld a, c
    cp 0x12
    jr nz, printprimesloop
    ld h, d
    ld l, e
    pop de
    ret

next_prime:
    inc de
next_prime_do:
    call is_prime
    or a
    jr z, next_prime_ifzero
    ret
next_prime_ifzero:
    inc de
    jr next_prime_do

is_prime:
    ld a, d
    or a
    jr nz, is_prime_general
    ld a, e
    cp N
    jr nc, is_prime_general
    ld hl, sieve_table
    add hl, de
    ld a, [hl]
    ret
is_prime_general:
    ld c, prime_table_size
    ld hl, prime_table
is_prime_loop:
    xor a
    ld [0xff95], a
    ld [0xff96], a
    ld a, d
    ld [0xff97], a
    ld a, e
    ld [0xff98], a
    ld a, [hl]
    ld [0xff99], a
    ld b, 04
    call Divide
    ld a, [0xff99]
    or a
    jr nz, is_prime_ok
    ld a, 0
    ret
is_prime_ok:
    inc hl
    dec c
    jr nz, is_prime_loop
    ld a, 1
    ret

print:
    push hl
        push hl
            ld hl, sp+2
            ld [hl], d
            inc hl
            ld [hl], e
            ld hl, sp+2
            ld d, h
            ld e, l
        pop hl
        ld bc, 0xc204
        call PrintNumber
    pop hl
    ret
sieve_table: