Autor Wątek: Procedura DRAW w ROM z 3 parametrem  (Przeczytany 15321 razy)

Dalthon

  • ****
  • Wiadomości: 428
  • Miejsce pobytu:
    TriCity
Procedura DRAW w ROM z 3 parametrem
« dnia: 2018.08.21, 02:46:31 »
O ile rysowanie punktu procedurą z ROM jest banalne...

10 PLOT 80,80

ld b,80 ; y
ld c,80 ; x
call 8933

... linie też się bez problemu rysuje...

10 PLOT 8,80
20 DRAW 10,10

ld b,80 ; y
ld c,80 ; x
call 8933

ld b,10 ; Y
ld c,10 ; X
ld d,1 ; +Y
ld e,1 ; +X
call 9402

... tak nie mam pojęcia (a analizowałem sobie rom tutaj: http://skoolkid.github.io/rom/) jak zrobić rysowanie 'po łuku'...

10 PLOT 80,80
20 DRAW 10,10,.5

Ktoś, coś? ;)
ZX Spectrum +2 Grey | Just Speccy 128 | ZX Spectrum Next | ZX-Uno 2MB |  Murmulator | Amstrad 6128 | MSX2 Philips VG-8235 | Commodore 64 | Commodore +4 | Atari 520 STF | Amiga 1200

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Procedura DRAW w ROM z 3 parametrem
« Odpowiedź #1 dnia: 2018.08.21, 08:05:39 »
Musiałbym pogrzebać, ale w związku z tym, że trzeci parametr jest ułamkowy więc prawie na pewno będzie trzeba go przekazywać przez stos kalkulatora. I pozostałe dwa raczej też.

Zajrzę do TCSRD i spróbuję coś "wywąchać" ;)

edit: Wywąchałem... Nie podejmuję się opisać na 100% jak się to robi ;)
A wydaje mi się, że robi się tak jak myślałem - najpierw ustawiamy współrzędne początku linii w COORDS, potem na stos kalkulatora wrzucamy X, Y i kąt (kąt leży na górze, Y, X poniżej) a następnie skaczemy w środek procedury DRAW - pod adres $2394. Tam zaczyna się program dla kalkulatora, który robi kontrolę kąta, kierunku itp. dzieli łuk na mniejsze kawałki i w pętli (cały czas napieprzając kalkulatorem ;)) wywołuje LINE-DRAW ($2477) rysując przybliżenie zadanego parametrami łuku. Z tej procedury widzę dwa wnioski - już wiem, czemu to jest takie cholernie wolne i już wiem skąd się bierze rysowanie "gwiazdek" jak się zada dziwny kąt jako parametr.
« Ostatnia zmiana: 2018.08.21, 08:17:14 wysłana przez matofesi »

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Procedura DRAW w ROM z 3 parametrem
« Odpowiedź #2 dnia: 2018.08.21, 09:00:20 »
Ok. Zrobiłem w ASMie ;)

        org $8000

        ld a,100
        ld (23677),a            ; początkowe X
        ld a,50
        ld (23678),a            ; początkowe Y

        ld a,50
        call $2d28              ; wrzuć na stos kalkulatora A - X linii
        ld a,50
        call $2d28              ; j.w. - Y linii

        rst $28                         ; FP-CALC
        db $34                          ; stk-data - wrzuć na stos kalkulatora liczbę FP
        db $f1, $49, $0f, $da, $a2      ; PI/2
        db $38                          ; end-calc

        call $2394              ; rysowanie łuku wg parametrów ze stosu kalkulatora

        ld hl,$2758             ; wracamy do BASICa - kalkulator zmienia
                                ; HL' trzeba więc przywrócić właściwą
                                ; zawartość
        exx

        ret

        end $8000

Powyższy kod jest mniej więcej odpowiednikiem PLOT 100,50 : DRAW 50,50,PI/2

Tak jak pisałem - najpierw ładujemy do COORDS początkowe współrzędne (PLOT bez PLOTa ;)), potem wrzucamy na stos parametry w tym ułamkowy kąt a następnie skaczemy do rysowania łuku. Na koniec odtwarzamy HL' - to jeden z błędów w ROMie - HL' musi być na wyjściu procedur używających kalkulatora ustawiony na $2758, jeśli tak nie jest program się po prostu zawiesi po wykonaniu ostatniego RET.

Całość działa tak samo jak z BASICa i jedyny problem, to przygotowanie startowych parametrów jeśli chcemy rysować łuki oparte na jakichś konkretnych kątach. Albo trzeba te liczby wyliczać kalkulatorem albo np. wydłubywać ze zmiennoprzecinkowej reprezentacji w programie BASICowych albo zmiennej ;)

Dalthon

  • ****
  • Wiadomości: 428
  • Miejsce pobytu:
    TriCity
Odp: Procedura DRAW w ROM z 3 parametrem
« Odpowiedź #3 dnia: 2018.08.21, 11:52:19 »
Ooooooooooooooo...  rozpykałeś to bez mydła! Wielkie dzięki!!! Teraz tylko rozkminić jak zapisywane są ułamki i będzie z górki :)

Szkoda że już nie robisz nic na zx'ie - taki talent się marnuje...
ZX Spectrum +2 Grey | Just Speccy 128 | ZX Spectrum Next | ZX-Uno 2MB |  Murmulator | Amstrad 6128 | MSX2 Philips VG-8235 | Commodore 64 | Commodore +4 | Atari 520 STF | Amiga 1200

steev

  • *****
  • Wiadomości: 1363
  • Miejsce pobytu:
    inode 42
Machines should work. People should think.

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Procedura DRAW w ROM z 3 parametrem
« Odpowiedź #5 dnia: 2018.08.21, 12:20:02 »
Ooooooooooooooo...  rozpykałeś to bez mydła! Wielkie dzięki!!! Teraz tylko rozkminić jak zapisywane są ułamki i będzie z górki :)

Liczby zmiennoprzecinkowe co do zasady zapisywane są wykładniczo jako pięć bajtów, ale mogą też być 2 albo 4 o ile pamiętam. W kilku miejscach były opisy jak to jest przeliczane, ale jakoś nigdy nie miałem zacięcia, żeby się w to wgryzać. Najprostsza metoda przeliczenia wartości ułamkowej na odpowiedni zapis dla kalkulatora to użycie takiej liczby w programie w BASICu (ROM zamieni za ciebie cyferki na formę FP) a potem podejrzenie w pamięci co mu wyszło - liczba jest w linii BASICa zapisana najpierw tekstem potem jest $0e a potem pięć bajtów reprezentacji FP. Można też kazać ROMowi sparsować tekst i zamienić na postać FP albo "wyliczyć" sobie kalkulatorem jeśli dana wartość jest "wyliczalna".

Cytuj
Szkoda że już nie robisz nic na zx'ie - taki talent się marnuje...

Mój problem z robieniem na cokolwiek jest taki, że mam problemy z wymyśleniem tego, CO ewentualnie miałbym zrobić. Wolę się zajmować rozwiązywaniem zadanych przez kogoś problemów nić wymyślać sobie własne. Przynajmniej jeśli chodzi zabawę ;)

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Procedura DRAW w ROM z 3 parametrem
« Odpowiedź #6 dnia: 2018.08.21, 12:21:57 »
Prosz... :>
http://www.worldofspectrum.org/z88forever/dn327/fpp.htm

Hmmm... Czy z88 aby na pewno używa systemowego kalkulatora i zgodnego z nim formatu liczb?

Nie używałem to nie wiem :)

ZbyniuR

  • *****
  • Wiadomości: 3333
  • Miejsce pobytu:
    Carlisle w UK
  • CPC AGA PSX
Odp: Procedura DRAW w ROM z 3 parametrem
« Odpowiedź #7 dnia: 2018.08.21, 13:08:09 »
A czy przypadkiem liczba w 5 bajtach nie jest tak że w każdej połówce bajta jest jedna cyfra dziesiętna?
Tylko nie wiem gdzie przecinek trzyma.
- Jeśli masz w domu światło i wodę, tzn. że masz światłowód. ;)

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Procedura DRAW w ROM z 3 parametrem
« Odpowiedź #8 dnia: 2018.08.21, 13:10:35 »
@ZbyniuR Przypadkiem nie. Celowo też nie.

W pierwszym bajcie jest wykładnik, w pozostałych czterech mantysa.

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Procedura DRAW w ROM z 3 parametrem
« Odpowiedź #9 dnia: 2018.08.21, 14:23:41 »
W dodatku do Komputera "Tajniki ZX Spectrum" Andrzej Kadlof wyjaśniał zapis liczb w taki sposób:

Cytuj
Sposoby kodowania liczb większych i zmiennoprzecinkowych
są w różnych komputerach rozmaite. W ZX-Basic wszystkie
liczby są przechowywane w pięciu kolejnych komórkach pamięci.
Dla programisty istnieją tylko liczby zmiennoprzecinkowe,
ale w pamięci liczby całkowite z przedziału - 65536...65535 są
kodowane w innej postaci niż pozostałe. Pierwszy i ostatni bajt
w ich przedstawieniu zawsze zawiera zero. Drugi bajt jest równy
0 dla liczb dodatnich i 255 dla ujemnych. W trzecim i czwartym
umieszcza się odpowiednio młodszy i starszy bajt danej liczby,
przy czym wartości ujemne są pamiętane w kodzie uzupełnień do
dwóch. Np. liczba 38 wygląda tak: 0 0 0 38 0, natomiast
743=2*256+231 ma postać 0 0 231 2 0. Z kolei - 1231 zapamiętane
jest jako 0 255 251 49 0, bo 256*251+49=65536-1231.

Z pozostałymi liczbami sprawa jest bardziej zawiła. Wykorzystuje
się fakt, że każdą liczbę można jednoznacznie przedstawić
w postaci 2 ^ n*m, gdzie m jest liczbą z przedziału [1/2,1]. W
pierwszym bajcie Spectrum przechowuje wartość n+128. W pozostałych
czterech umieszczona jest liczba m w postaci binarnej, a
dokładnie - m*2 ^ 32, z tym, że najstarszy bit, który powinien
zawsze być równy 1 służy do przechowywania znaku liczby. Jedynka
oznacza minus a zero plus.

Przypuśćmy, że pięć kolejnych komórek pamięci zawiera liczby
130 212 16 34 178. Są one interpretowane jako liczba

2 ^ (130-128)*(212/2 ^ 8+16/2 ^ 16+34/2 ^ 24+178/2 ^ 32),

natomiast bajty 106 112 4 231 78 przedstawiają liczbę

2 ^ (106-128)*((128+112)/2 ^ 8+4/2 ^ 16+231/2 ^ 24+78/2 ^ 32)

Nie przekonuje mnie ta matematyka, ale może komuś coś z tego wyniknie ;)

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4538
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: Procedura DRAW w ROM z 3 parametrem
« Odpowiedź #10 dnia: 2018.08.21, 15:10:38 »
Ciekawa lekturą. Póki co nie wykorzystywałem procedur rysujących z ROM.

Trochę więcej, wraz z przykładowym programem wylicząjacym IEEE 754, znajduje się na stronie https://eduinf.waw.pl/inf/alg/006_bin/0022.php, co jest dobrym uzupełnieniem wiedzy dotyczącej DRAW oraz parametrów dla niego.

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Procedura DRAW w ROM z 3 parametrem
« Odpowiedź #11 dnia: 2018.08.21, 15:52:10 »
To jeszcze na koniec to o czym pisałem czyli metoda na przekształcenie tekstowej reprezentacji liczby na liczbę FP na stosie kalkulatora:

        org $8000
ch_add  equ 23645

        ld a,2
        call $1601      ; chan-open

; === POCZĄTEK ===
        ld hl,(ch_add)
        push hl

        ld hl,number
        ld (ch_add),hl

        rst $20
        call $2c9b      ; dec-to-fp

        pop hl
        ld (ch_add),hl
; === KONIEC ===

        call $2de3      ; print-fp

        ld hl,$2758
        exx
        ret

number
        db 0
        db "12.345"
        db 0

Właściwy kod jest między POCZĄTEK a KONIEC - reszta to otoczka otwierająca kanał 2 i drukująca liczbę FP ze stosu kalkulatora na ekran.

A właściwy kod najpierw zachowuje na stosie (procesora) zawartość zmiennej ch_add a potem przestawia ją na adres tekstowej reprezentacji liczby, którą chcemy dostać w formacie FP. Następnie wywoływane jest RST $20 pobierające znak spod ch_add - nie analizowałem dlaczego, ale pierwszy znak przez procedurę jest pomijany stąd db 0 na początku. Po pobraniu znaku skaczemy do właściwej procedury dec-to-fp, która parsuje to, co dostała i przetwarza na formę FP - obsługuje wszystkie formy zapisu liczb, których można użyć w BASICu (.123, 1.234, 1.2E2 itp.) i kończy analizę po napotkaniu znaku, który nie jest dopuszczalną częścią liczby (tutaj ostatnie db 0). Po wyjściu mamy na stosie kalkulatora formę FP liczby, którą na zewnątrz drukujemy na ekran używając print-fp a w praktycznych zastosowaniach używamy jej np. jako parametru dla DRAW albo do innych obliczeń kalkulatorem.


Dalthon

  • ****
  • Wiadomości: 428
  • Miejsce pobytu:
    TriCity
Odp: Procedura DRAW w ROM z 3 parametrem
« Odpowiedź #12 dnia: 2018.08.21, 19:29:07 »
Zawsze można liczyć na forum - nawet taki niszowy temat rozpracowany na czynniki pierwsze :)

Szkoda że ten 3 parametr jest tak zapisywany - z racji długości, raczej ciężko będzie to wykorzystać w 256b produkcjach (bo taki był pierwotny zamysł) ale do 1kB i 4kB jak znalazł!

ps. muszę częściej wrzucać tutaj swoje rozterki, zamiast odpuszczać i wymyślać co innego :D
ZX Spectrum +2 Grey | Just Speccy 128 | ZX Spectrum Next | ZX-Uno 2MB |  Murmulator | Amstrad 6128 | MSX2 Philips VG-8235 | Commodore 64 | Commodore +4 | Atari 520 STF | Amiga 1200

Dalthon

  • ****
  • Wiadomości: 428
  • Miejsce pobytu:
    TriCity
Odp: Procedura DRAW w ROM z 3 parametrem
« Odpowiedź #13 dnia: 2019.07.22, 00:02:13 »
Taaaa... jednak za głupi jestem :/

A jak ze znakami? Próbuję zrobić

10 PLOT 0,47
20 DRAW 255,0,-3.14

albo (bo efekt ten sam;)

10 PLOT 255,47
20 DRAW -255,0,3.14

i nic mi z tego nie wychodzi :(
« Ostatnia zmiana: 2019.07.22, 00:50:31 wysłana przez Dalthon »
ZX Spectrum +2 Grey | Just Speccy 128 | ZX Spectrum Next | ZX-Uno 2MB |  Murmulator | Amstrad 6128 | MSX2 Philips VG-8235 | Commodore 64 | Commodore +4 | Atari 520 STF | Amiga 1200

steev

  • *****
  • Wiadomości: 1363
  • Miejsce pobytu:
    inode 42
Odp: Procedura DRAW w ROM z 3 parametrem
« Odpowiedź #14 dnia: 2019.07.22, 01:36:49 »
Problem pewnie w tym, że  stk-data wymaga nie po prostu liczby, ale liczby w postaci 'skondensowanej'.
Więc -pi to nie $82, $c8, $f5, $c2, $8f ale  $f2, $c8, $f5, $c2, $8f.

        org $8000

        ld a,0
        ld (23677),a            ; początkowe X
        ld a,47
        ld (23678),a            ; początkowe Y

        ld a,255
        call $2d28              ; wrzuć na stos kalkulatora A - X linii
        ld a,0
        call $2d28              ; j.w. - Y linii

        rst $28                                 ; FP-CALC
        db $34                                  ; stk-data - wrzuć na stos kalkulatora liczbę FP
        db $f2, $c8, $f5, $c2, $8f              ; -PI
        db $38 

        call $2394         ; rysowanie łuku wg parametrów ze stosu kalkulatora

        ld hl,$2758        ; wracamy do BASICa - kalkulator zmienia
                           ; HL' trzeba więc przywrócić właściwą
                           ; zawartość
        exx

        ret
Machines should work. People should think.