1

              inc _d
              lda _d
              and #$07
              beq _d1
              rts
_d1           lda #$20
              clc
              adc _e
              sta _e
              bcc _d2
              rts
_d2           lda _d
              sec
              sbc #$08
              sta _d
              rts
http://atari.pl/hsc/ad.php?i=1.

2 Ostatnio edytowany przez seban (2009-08-19 10:11:29)

a można używać rej x,y, czy wartość _e jest ci potrzebna? (ale chyba tak, bo to jakieś operację widzę na obrazie zorganizowanym jak w przypadku ZX ;] )

na początek możesz sobie sec, sbc zamienić na adc #-$08, wyjdzie na to samo. znacznik C masz w tym miejscu zawsze skasowany.

3 Ostatnio edytowany przez xxl (2009-08-19 10:41:34)

zgadza sie, zx. mozna uzywac rejestrow, jesli to pomoze rej Y zawsze rowny jest 0.

dzieki seban, juz jest troszke lepiej :-) ... jeszcze malo.

---
tu jest miejsce do optymalizacji, procedura jest tak wywolywana:


_enter
              jsr _enter2
_enter2   jsr _enter3
_enter3
              inc _d
              lda _d
              and #$07
              beq _d1
              rts
_d1           lda #$20
              clc
              adc _e
              sta _e
              bcc _d2
              rts
_d2           lda _d
            ;  sec
            ;  sbc #$08
              adc #-$08
              sta _d
              rts

wejscie w miejscu _enter i _enter2

http://atari.pl/hsc/ad.php?i=1.

4

Wzorzec zmienności _d jest taki dziwny, że nie rozumiem co ten algorytm ma właściwie robić. Jakiś szerszy kontekst by się przydał. Może wtedy  znalazłaby się nawet jakaś bardziej globalna optymalizacja.

5 Ostatnio edytowany przez xxl (2009-08-19 10:34:22)

to jest do oblicznia pozycji na ekranie zx spectrum, z tymi jsr mozna cos pokombinowac.

---
ekran zx bedzie umieszczany w roznych miejscach pamieci nie od $4000 wiec nie nalezy sie sugerowac oryginalem

http://atari.pl/hsc/ad.php?i=1.

6 Ostatnio edytowany przez mono (2009-08-19 12:14:51)

Czy _d jest tylko licznikiem, czy jest wykorzystywany gdzieś poza tym kodem i czy jego wartości (powiedzmy -8..-1) są ważne czy można je przetransponować?

Edit: głupie pytanie - rozumiem już co tu się dzieje.

hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje

7 Ostatnio edytowany przez laoo/ng (2009-08-19 13:12:42)

Jeżeli masz 512 bajtów miejsca na tablice (lub mniej jeżeli |Dom(_d)| < 256) to można trochę potablicować. Jeżeli nigdzie się nie walnąłem, to można tak:

_enter jsr _enter2
_enter2              
              
    ldx _d
    lda t1,x
    sta _d
    cmp t2,x
    bcc _d1
    rts
_d1 lda #$20
    adc _e
    sta _e
    bcs _d2
    lda _d
    adc #-$08
    sta _d
_d2 rts
    
; x:      0,1,2,3,4,5,6,7, 8, 9,10,11,12,13,14,15,16,17,18,19,20    
t1  .byte 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22
t2  .byte 2,3,4,5,6,7,0,0,10,11,12,13,14,15, 0, 0,18,19,20,21,22

Idea jest taka, że wspomniana procedura jest wołana 2 lub 4 razy, można więc zamknąć dwa wywołania w jednym. t1[x] == x + 2. Na każde dwa pierwotne wywołania _e jest modyfikowane maksymalnie raz i to wtedy, gdy _d & 7 == (6 lub 7). Do tej decyzji służy tablica t2, która dodatkowo determinuje wartość flagi C: t2[x] < t1[x] gdy _d & 7 == (6 lub 7), t2[x] >= t1[x] wpp. Drugi trick, (który jest niezależny) pomaga zaoszczędzić 7/32 cyklu: jest większe prawdopodobieństwo, że _e się nie przepełni, niż to, że się przepełni, więc bardziej prawdopodobna ścieżka powinna być krótsza, czyli skok powinien być wykonywany gdy się przepełni.

EDIT:

Jeżeli _enter jest wołane często, a masz dodatkowe 512 bajtów, to można spreparować tablice dla wywołania podwójnego (poczwórnego dla oryginalnego algorytmu). t1'[x] == x + 4; t2'[x] < t1'[x] gdy _d & 7 in {4,5,6,7}; t2'[x] >= t1'[x] wpp.

8 Ostatnio edytowany przez xxl (2009-08-19 15:03:34)

zastosowalem (w tablicy powinny byc $ff zamiast $00)
pomysl jest dobry ale nie wiem, nie widac poprawy :/

---
skok z bcs do rts, dobry.

http://atari.pl/hsc/ad.php?i=1.

9 Ostatnio edytowany przez seban (2009-08-19 15:34:37)

xxl napisał/a:

skok z bcs do rts, dobry.

to jeżeli mamy już optymalizować skoki... to rozwiązanie od razu było oczywiste ;) ale osiągów to zbyt nie poprawia :)

              inc _d
              lda _d
              and #$07
              bne ext
              lda #$20
              clc
              adc _e
              sta _e
              bcs ext
              lda _d
              adc #-$08
              sta _d
ext           rts

jeszcze jedno dziwne pytanie dotyczące wartości D, rozumiem iż każde wywołanie procedury następuje zawsze z różną nieprzewidywalną wartością w d? powiedzmy w zależności od interakcji użytkownika? czy zawsze startujemy ze z góry określonej wartości d?

10 Ostatnio edytowany przez Marek Konopka (2009-08-19 16:16:36)

Przepraszam, nie wiem, jak wstawiać znacznik kodu. Poniższe prezentuje pewien pomysł, aniżeli gotowe rozwiązanie.

.align 256

  inc _d+1
_d lda FlagiSkokowZawierajace_0_oraz_20_Tbl
 bne ver2

continue

ver2
 clc
 adc _e
 sta _e
 bcs continue

 lda _d+1
 adc #-$08
 sta _d+1
 jmp continue

Edit: Wstawka z kodem poprawiona.

11

"code" w nawiasach kwadratowych.

Moje wariacje:

    inc:lda _d
    dta $0c,$07 ; anc #
    bne exit
    lda #$20
    adc:sta _e -
    bcs exit
    lda #-8
    adc:sta _d -
exit    rts
    lda _d
    add #1
    bit const7
    bne exit
    ldx _e
    ldy add32,x
    sty _e
    cpy #32
    bcc exit
    sbc #8 +
exit    sta _d
    rts

A poważnie: jeśli wejście jest tylko (albo zwykle) z _enter i _enter2, to trzeba optymalizować pod tym kątem.

https://www.youtube.com/watch?v=jofNR_WkoCE

12 Ostatnio edytowany przez xxl (2009-08-19 18:19:08)

              inc _d
              lda _d
              and #$07
              beq _d1
              rts
_d1           lda _e
              clc
              adc #$20
              sta _e
              bcs _d2
              lda _d
              adc #-$08
              sta _d
_d2           rts

beq na poczatku jest lepszy, poniewaz rzadziej bedzie wykonywany skok.

D przyjmuje wartosci (teraz) od $e0,$e1,$e2,... 23 sztuki natomiast E od 0-255, ale chyba nic wiecej sie z tego nie wycisnie, oszczednosci trzeba szukac gdzieindziej, chyba ze ktos wpadnie na pomysl z tymi jsr na poczatku.

kodu konopa niestety nie rozumiem.

---
dta $0c,$07 ; anc #

pod atariwin+ chyba nie dziala

http://atari.pl/hsc/ad.php?i=1.

13

xxl napisał/a:

zastosowalem (w tablicy powinny byc $ff zamiast $00)
pomysl jest dobry ale nie wiem, nie widac poprawy :/

A zaimplementowałeś wersję optymalizującą start od _enter (skompresowanie 4 przebiegów)? Jak nie pomogło, to może wąskie gardło jest gdzieś indziej? Sprawdzałeś pod profilerem?

14 Ostatnio edytowany przez Marek Konopka (2009-08-19 18:37:00)

Pod adresem _d+1 zawarte jest faktyczne _d. Rozkaz inc _d+1 dokonuje automodyfikacji argumentu instrukcji lda pobierającej status skoku, a zarazem argument do dodania w późniejszej instrukcji adc _e, w przypadku dokonania skoku. Wyeliminowałem również konieczność dokonywania skoku JSR enter2 oraz powrotu poprzez RTS, zakładając, że umieścimy cały zaproponowany przeze mnie kod w miejsce JSR enter2. Z tego powodu etykieta continue określa miejsce, od którego następuje kontynuacja wykonywania programu po zakończeniu działania optymalizowanego fragmentu.

Tablica FlagiSkokowZawierajace_0_oraz_20_Tbl jest skonstruowana tak:

$20, 0, 0, 0, 0, 0, 0, 0, $20, 0, 0, 0, 0, 0, 0, 0, itp.

czyli wygenerowana formułą !(i & 7)*0x20 i pełni jak już wspominałem dwoistą funkcję. Pierwsza określa decyzję dotyczącą skoku do dalszego kodu, a druga argument (#$20) do dodania do _e.

15

ale tak sie nie da ?chyba? d i e musza byc na stronie zerowej (emulowane rejestry z80) - adresowanie ... (de),y

laoo Twoim sposobem to wyglada tak:

_enter         jsr _enter2
_enter2
    ldx _d
    lda t1-$e0,x
    sta _d
    cmp t2-$e0,x
    bcc _d1
    rts
_d1 lda #$20
    adc _e
    sta _e
    bcs _d2
    lda _d
    adc #-$08
    sta _d
_d2 rts
;
t1      dta $e2,$e3,$e4,$e5,$e6,$e7,$e8,$e9,$ea,$eb,$ec,$ed,$ee,$ef
        dta $f0,$f1,$f2,$f3,$f4,$f5,$f6,$f7,$f8,$f9,$fa,$fb,$fc
t2      dta $e2,$e3,$e4,$e5,$e6,$e7,$FF,$FF,$ea,$eb,$ec,$ed,$ee,$ef
        dta $FF,$FF,$f2,$f3,$f4,$f5,$f6,$f7,$FF,$FF,$fa,$fb,$fc
http://atari.pl/hsc/ad.php?i=1.

16 Ostatnio edytowany przez Marek Konopka (2009-08-19 19:12:09)

xxl napisał/a:

ale tak sie nie da ?chyba? d i e musza byc na stronie zerowej (emulowane rejestry z80) - adresowanie ... (de),y

.align 256

 inc _d
 ldx _d
 lda FlagiSkokowZawierajace_0_oraz_20_Tbl,x
 bne ver2

continue

ver2
 clc
 adc _e
 sta _e
 bcs continue

 lda _d+1
 adc #-$08
 sta _d+1
 jmp continue

EDIT: W poprzedniej wersji występował błąd. Zamiast

 lda _d+1
 adc #-$08
 sta _d+1

miało oczywiście być

 lda _dh
 adc #-$08
 sta _dh

17

Chodziło mi o rozpisanie wejścia _enter tak, aby nie robić tego jsr:

_enter
    ldx _d
    lda t3-$e0,x
    sta _d
    cmp t4-$e0,x
    bcc _d1
    rts

_enter2
    ldx _d
    lda t1-$e0,x
    sta _d
    cmp t2-$e0,x
    bcc _d1
    rts

_d1 lda #$20
    adc _e
    sta _e
    bcs _d2
    lda _d
    adc #-$08
    sta _d
_d2 rts
;
t1      dta $e2,$e3,$e4,$e5,$e6,$e7,$e8,$e9,$ea,$eb,$ec,$ed,$ee,$ef
        dta $f0,$f1,$f2,$f3,$f4,$f5,$f6,$f7,$f8,$f9,$fa,$fb,$fc
t2      dta $e2,$e3,$e4,$e5,$e6,$e7,$FF,$FF,$ea,$eb,$ec,$ed,$ee,$ef
        dta $FF,$FF,$f2,$f3,$f4,$f5,$f6,$f7,$FF,$FF,$fa,$fb,$fc

t3      dta $e4,$e5,$e6,$e7,$e8,$e9,$ea,$eb,$ec,$ed,$ee,$ef,$f0,$f1
        dta $f2,$f3,$f4,$f5,$f6,$f7,$f8,$f9,$fa,$fb,$fc,$fd,$fe
t4      dta $e4,$e5,$e6,$e7,$FF,$FF,$FF,$FF,$ec,$ed,$ee,$ef,$FF,$FF
        dta $FF,$FF,$f4,$f5,$f6,$f7,$FF,$FF,$FF,$FF,$fc,$fd,$fe

18

procka wklejona i dziala :-) to by bylo na tyle.


dzieki :-)

http://atari.pl/hsc/ad.php?i=1.

19

Tak jeszcze teraz do mnie dotarło, że można zaoszczędzić pamięć łącząc tablice t1 i t3 :)