Autor Wątek: Pierwsze kroki w Pasmo  (Przeczytany 107061 razy)

trojacek

  • *****
  • Wiadomości: 6846
  • Miejsce pobytu:
    Warszawa
Odp: Pierwsze kroki w Pasmo
« Odpowiedź #90 dnia: 2015.04.27, 12:25:02 »
Przez modyfikację zmiennych systemowych nie udawało się nic osiągnąć, więc w końcu przeanalizowałem problem. Tak można ustawić tą samą pozycję co wyżej, krócej i (przynajmniej dla mnie) elegancko:
LD BC,$0E15   ;B=24-y, C=33-x
CALL $0DD9

Zacząłem przeglądać swoje stare pliki ASM i znalazłem, że można prościej:
LD BC,$0E15   ;B=y, C=x
CALL $200A

Phonex

  • *****
  • Wiadomości: 1261
  • Miejsce pobytu:
    Warszawa
Odp: Pierwsze kroki w Pasmo
« Odpowiedź #91 dnia: 2015.04.27, 12:44:49 »
Ładnie. Ale moja procedura jest szybsza! :P

@Phonex Oczywiście, że robienie tego ciągiem LD A,n, RST 16 jest brzydkie i bez sensu ;) Jak już robię takie rzeczy to raczej wstawiam kody sterujące na początek właściwego tekstu i wołam PO-MSG albo inną stosowną procedurę drukującą tekst. Jest spójniej i krócej niż osobne ustawianie pozycji :)

Zgadza się, ale nie można tak gdy drukuje się zmienne.

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Pierwsze kroki w Pasmo
« Odpowiedź #92 dnia: 2015.04.27, 13:32:09 »
A właściwie kto powiedział, że nie da się ustawić pozycji przez modyfikację zmiennych? Da się tylko jest to wysoce upiardliwe, bo trzeba modyfikować równocześnie "DF CC" (23684) i "SPOSN" (23688) - ta pierwsza zawiera adres w pamięci ekranu aktualnej pozycji kursora, ta druga to 33-kolumna, 24-wiersz.

Takie coś...
        ld a,33-10
        ld (23688),a
        ld a,24-10
        ld (23689),a
        ld hl,16384+2048+32*2+10
        ld (23684),hl

        ld a,48
        rst 16
...wyświetli "0" na pozycji 10,10 ;)


Phonex

  • *****
  • Wiadomości: 1261
  • Miejsce pobytu:
    Warszawa
Odp: Pierwsze kroki w Pasmo
« Odpowiedź #93 dnia: 2015.04.27, 14:17:16 »
Oczywiście że da się. ;)
Napisałem za krótko. Miałem na myśli: "Przez modyfikację zmiennych systemowych pozycji (SPOSN) nie udawało się nic osiągnąć..."
CALL $0DD9 robi właśnie to co Twoja procedura - dla otwartego kanału 2 (ekran), ustawia zmienne SPOSN oraz DF CC.
« Ostatnia zmiana: 2015.04.27, 15:23:35 wysłana przez Phonex »

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Pierwsze kroki w Pasmo
« Odpowiedź #94 dnia: 2015.04.27, 15:42:54 »
A tak całkiem na koniec przypomniałem sobie, że przecież w ROMie jest też procedura do zrzucania na ekran dowolnej liczby ze stosu kalkulatora. I oczywiście procedury do wrzucania na ten stos liczb z rejestrów. A więc drukowanie liczb można też rozwiązać tak:
        ld a,200
        call $2d28   ; stack-a
        call $2de3   ; print-fp

...

        ld bc,12345
        call $2d2b   ; stack-bc
        call $2de3   ; print-fp

Oczywiście print-fp wydrukuje też liczby zmiennoprzecinkowe o ile będziemy w stanie przygotować stosowną formę i wrzucić na stos kalkulatora albo będzie wynikiem jakichś obliczeń wykonanych tymże kalkulatorem...
        ld bc,12345
        call $2d2b   ; stack-bc

        ld a,7
        call $2d28   ; stack-a

        rst $28      ; uruchamiamy kalkulator - na stosie mamy 7 i 12345
        db $05       ; dzielenie - zdejmuje ze stosu dwie wartości i dzieli
                     ; jedną przez drugą pozostawiając wynik
                     ; w efekcie na stosie zostaje 12345/7
        db $38       ; koniec obliczeń

        call $2de3   ; print-fp - drukuje ostatnią liczbę ze stosu kalkulatora, czyli
                     ; wynik obliczeń

Takie zabawy dają sporo możliwości (można sobie policzyć z ASMa w zasadzie wszystko to, co się da policzyć z BASICa), ale mają jedna zasadniczą wadę - kalkulator nie jest szybki i bardziej rozbudowane obliczenia trwają zdecydowanie za długo.

Ale jak ktoś potrzebuje, to się da ;)

tdu

  • *****
  • Wiadomości: 926
  • Miejsce pobytu:
    Gdansk
    • Nasze Wędrowanie
Odp: Pierwsze kroki w Pasmo
« Odpowiedź #95 dnia: 2015.04.27, 19:22:38 »
Wersja z licznikiem i napisami

napisy robione tak:
wstep
ld hl,wst
call tekst
wst DEFM 22,10,1,'Wedrujacy punkt',0


tekst
ld a,(hl)
sko3
push af
rst 16
pop af
inc hl
ld a,(hl)
cp 0
jp nz,sko3
ret
ZX81/ZX 48k/Zx48k+/ZX +2/ZX +2A/+3/TC2048/FDD3000/FDD5000/3"/3,5'/5,25'/Beta 48k Apina/D+/GP50s/DIVIDE CF/Masterface/Polbasic SamCoupe QL CPC6128/N100 MSX-SVI738  MSX2-VG8235

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Pierwsze kroki w Pasmo
« Odpowiedź #96 dnia: 2015.04.28, 08:12:59 »
Wersja z licznikiem i napisami

Prawie dobrze ;)

Cytuj
tekst
ld a,(hl)
sko3
push af
rst 16
pop af
inc hl
ld a,(hl)
cp 0
jp nz,sko3
ret

Działa a to do czego się przyczepię to drobiazgi, z których z czasem "wyrośniesz" ;)

Po pierwsze... w dwóch miejscach pobierasz bajt spod (hl) - niepotrzebnie. Po drugie - przed RST 16 zrzucasz na stos AF, które i tak później nie będzie ci potrzebne. Po trzecie - nadal używasz CP 0, które jest dłuższe niż OR A i zajmuje więcej miejsca.

"Ładniej" zrobiona procedura mogłaby wyglądać tak:
tekst
        ld a,(hl) ; pobieramy kolejny bajt
        or a      ; zero?
        ret z     ; jeśli tak, kończymy procedurę
        rst 16    ; drukujemy znak
        inc hl    ; zwiększamy wskaźnik
        jr tekst  ; skaczemy na początek pętli

Ale poza tym poruszasz się we właściwym kierunku :)

tdu

  • *****
  • Wiadomości: 926
  • Miejsce pobytu:
    Gdansk
    • Nasze Wędrowanie
Odp: Pierwsze kroki w Pasmo
« Odpowiedź #97 dnia: 2015.04.28, 11:56:26 »
Dziękuje za poprawki.

Znalazłem w końcu błąd z którym walczyłem ze dwie godziny
takie coś daje kolorowe kwadraty na ekranie:

info2
ld hl,inf2
call tekst
inf2 DEFB 22,19,1,'Sterowanie klawiszami: Q A O P',0
ret

musi być tak:

info2
ld hl,inf2
call tekst
ret
inf2 DEFB 22,19,1,'Sterowanie klawiszami: Q A O P',0
ZX81/ZX 48k/Zx48k+/ZX +2/ZX +2A/+3/TC2048/FDD3000/FDD5000/3"/3,5'/5,25'/Beta 48k Apina/D+/GP50s/DIVIDE CF/Masterface/Polbasic SamCoupe QL CPC6128/N100 MSX-SVI738  MSX2-VG8235

RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Pierwsze kroki w Pasmo
« Odpowiedź #98 dnia: 2015.04.28, 12:32:29 »
No słuchaj, w oryginalnej wersji chciałeś treść swojego napisu wykonać jako kod. To nie mogło się udać ;)

Po instrukcji CALL tekst następną rzeczą w pamięci jest treść twojego tekstu. Program nie wie że to tekst, potraktuje to jako kod.

W asemblerze  program i dane są właściwie tym samym - sekwencją bajtów. Twój napis został zamieniony na jakieś bajty a im zawsze odpowiadają jakieś instrukcje asemblera. W przypadku takiego tekstu będą to jednak zupełnie bezsensowne, losowe instrukcje które na 90% zawieszą program lub spowodują reset.


tdu

  • *****
  • Wiadomości: 926
  • Miejsce pobytu:
    Gdansk
    • Nasze Wędrowanie
Odp: Pierwsze kroki w Pasmo
« Odpowiedź #99 dnia: 2015.04.28, 13:10:11 »
No chyba tak nie do końca:
Cytuj
Po instrukcji CALL tekst następną rzeczą w pamięci jest treść twojego tekstu. Program nie wie że to tekst, potraktuje to jako kod.

miejsce w pamięci gdzie znajduje się tekst jest wskazany w rejestrze HL
i gdzie by on nie był to program powinien go sobie znaleźć,
a to że okazało się że nie jest tak całkiem wszystko jedno,
to raczej ograniczenie programu asemblującego.

a następną wykonywaną instrukcją po CALL jest instrukcja
w podprogramie "tekst"

Tak mi się przynajmniej wydaje
ZX81/ZX 48k/Zx48k+/ZX +2/ZX +2A/+3/TC2048/FDD3000/FDD5000/3"/3,5'/5,25'/Beta 48k Apina/D+/GP50s/DIVIDE CF/Masterface/Polbasic SamCoupe QL CPC6128/N100 MSX-SVI738  MSX2-VG8235

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Pierwsze kroki w Pasmo
« Odpowiedź #100 dnia: 2015.04.28, 13:14:36 »
Tak mi się przynajmniej wydaje

Masz rację - wydaje ci się ;)

Owszem - po CALL wykonywana jest procedura, którą wywołujesz, ale jak w niej trafisz na RET, to program wraca do kolejnego bajtu za instrukcją CALL czyli w twoim wypadku tak jak pisał Rafał usiłuje wykonać twój tekst jako kod i idzie w kartofle ;)

edit: Z ciekawości sprawdziłem co ci się tam tak na prawdę wykonywało...
                org $0000
                ld d,$13         ; 1613       ; db $16, $13
                ld bc,$7453      ; 015374     ; db $01, $53, $74
                ld h,l           ; 65         ; db $65
                ld (hl),d        ; 72         ; db $72
                ld l,a           ; 6F         ; db $6F
                ld (hl),a        ; 77         ; db $77
                ld h,c           ; 61         ; db $61
                ld l,(hl)        ; 6E         ; db $6E
                ld l,c           ; 69         ; db $69
                ld h,l           ; 65         ; db $65
                jr nz,$007A      ; 206B       ; db $20, $6B
                ld l,h           ; 6C         ; db $6C
                ld h,c           ; 61         ; db $61
                ld (hl),a        ; 77         ; db $77
                ld l,c           ; 69         ; db $69
                ld (hl),e        ; 73         ; db $73
                ld a,d           ; 7A         ; db $7A
                ld h,c           ; 61         ; db $61
                ld l,l           ; 6D         ; db $6D
                ld l,c           ; 69         ; db $69
                ld a,($5120)     ; 3A2051     ; db $3A, $20, $51
                jr nz,$005E      ; 2041       ; db $20, $41
                jr nz,$006E      ; 204F       ; db $20, $4F
                jr nz,$0071      ; 2050       ; db $20, $50
                nop              ; 00         ; db $00

ORG $0000 jest po to, żeby cokolwiek dało się wywnioskować - kod nie robi nic istotnego, co najwyżej przeskakuje gdzieś dalej i zależnie od tego, co miałeś za tekstem i w jaki dokładnie adres się wstrzeli może się zachowywać w dowolnie nieprzewidywalny sposób ;)

RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Pierwsze kroki w Pasmo
« Odpowiedź #101 dnia: 2015.04.28, 13:25:13 »
No zdecydowanie nie rozumiesz :)

Włącz sobie w emulatorze debugger i zobacz instrukcja po instrukcji co wykonuje twój program. Zobaczysz że pomieszałeś  kod z danymi. To że wstawisz do HL adres tego tekstu nie ma na tym etapie żadnego znaczenia.




matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Pierwsze kroki w Pasmo
« Odpowiedź #102 dnia: 2015.04.28, 13:52:22 »
A żeby ci jeszcze bardziej namieszać, to pokażę ci jeden z bardziej zaawansowanych kawałków, który pozwala na mieszanie kodu z danymi...
W głównej części programu można drukować teksty w taki sposób:
        ...
        call print_text
        db 22,18,0,"Napis w tresci",0
        ...
Wielokropki to oczywiście dowolny kod przed i po wydrukowaniu tekstu. A sama procedura drukowania wygląda tak:
print_text
        pop hl
print_text2
        ld a,(hl)
        inc hl
        or a
        jr nz,print_text1
        push hl
        ret
print_text1
        rst 16
        jr print_text2

Procedury dostarczające w taki sposób statycznych parametrów są dość częstym rozwiązaniem w ROMie (RST 8, RST 28 - kalkulator itp).
Cały mechanizm polega na tym, że po CALL na stos odkładany jest adres powrotu, czyli adres następnego bajtu po trzybajtowej instrukcji. W procedurze podnosimy ten adres ze stosu i używamy go jako wskaźnika do tekstu. Jedyna istotna różnica to sposób powrotu - po odczytaniu ostatniego bajtu wskaźnik ustawia się na pierwszy bajt po tekście (a właściwie po znaczniku końca) a następnie jest odkładany na stos a RET działa dokładnie odwrotnie do CALL - podnosi adres ze stosu i skacze pod ten adres wracając do kolejnej instrukcji po tekście.

Powrót zamiast PUSH/RET można w tym wypadku wykonać też przez JP (HL), ale nie zawsze się da, bo nie zawsze wskaźnikiem do danych będzie HL.

Ot taki sobie - czasem przydatny - myk ;)

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4540
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: Pierwsze kroki w Pasmo
« Odpowiedź #103 dnia: 2015.04.28, 13:57:49 »
Świetny przykład, choć pewnie istnieją jeszcze bardziej zagmatwane kody, z pracą na stosie, JP zamiast CALL i innymi cudami.

tdu: czy to co piszesz ma jakąś zaplanowaną formę?

tdu

  • *****
  • Wiadomości: 926
  • Miejsce pobytu:
    Gdansk
    • Nasze Wędrowanie
Odp: Pierwsze kroki w Pasmo
« Odpowiedź #104 dnia: 2015.04.28, 14:08:01 »
Ta analiza programu przemówiła do mnie, zwracam honor starym wyjadaczom asemblera.

Na moją obronę mam to że sam błąd znalazłem, nie wiedziałem tylko dlaczego.

A te dywagacje nad udziwnieniami to nie na mój poziom.


@tygrys - to tylko taka improwizacja, nie wiem co z tego wyjdzie, może się zniechęcę i zajmę się czymś innym.
Chciałem złapać tylko podstawy pracy z asemblerem ale mnie wciągnęło.  Sam się dziwię że nie zrobiłem
tego kroku 25 lat temu. Ale wtedy jakoś Basic mi wystarczał. 
ZX81/ZX 48k/Zx48k+/ZX +2/ZX +2A/+3/TC2048/FDD3000/FDD5000/3"/3,5'/5,25'/Beta 48k Apina/D+/GP50s/DIVIDE CF/Masterface/Polbasic SamCoupe QL CPC6128/N100 MSX-SVI738  MSX2-VG8235