atarionline.pl Wyświetlanie wartości liczbowych na ekranie (MADS) - Forum Atarum

    Jeśli chcesz wziąć udział w dyskusjach na forum - zaloguj się. Jeżeli nie masz loginu - poproś o członkostwo.

    • :
    • :

    Vanilla 1.1.4 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.

      • 1: CommentAuthoriSiek
      • CommentTime13 Nov 2024 21:11 zmieniony
       
      Cześć, witajcie

      jestem powracającym użytkownikiem Atari 800XL po 35 latach. Jako małe dziecko i podlotek głównie grywałem na nim, a po latach otrzymałem je w prezencie i zapragnąłem coś więcej niż tylko grać.

      Nabyłem zestaw książek o programowaniu na Atari z Retronics i je przeczytałem. Teraz czas na praktykę :)

      Potrzebuje Waszej pomocy!

      Niestety nie jestem programistą i takiego kierunkowego wykształcenia nie posiadam. Mam jakieś podstawy, które staram się wykorzystać ale niestety utknąłem :(

      Używam WUSDN z MADS i Altirra na Windows. Uczę się składać swoje pierwsze programy po przeczytaniu książek. Są to proste rzeczy, które mają mi pomóc najpierw zrozumieć jak to wszystko działa. Niewiele ma to wspólnego ze sztuką prawdziwego programowania jak i optymalizacją kodu. Na to przyjdzie czas, gdy już w pełni zrozumiem co i jak piszę, więc proszę o odrobinę Waszej wyrozumiałości.

      Pisząc kod, wyniki przeglądam w debug'erze przeglądając rejestry i komórki pamięci. Jednak zapragnąłem sobie trochę usprawnić życie, i postanowiłem te informacje wyświetlać na ekranie, aby nie musieć ich wyszukiwać.

      Poniższy program ma za zadanie pomnożyć cyfry 4x5. I wymyśliłem sobie to tak (wiem, że można inaczej ale pierwsze kroki, to pierwsze kroki ;) ):



      org $2000

      DLPTRS = $0230
      wynik = $2100

      BEGIN
      lda #0
      ldy #5
      cld
      clc

      func_mnoz
      adc #4
      dey
      bne func_mnoz

      sta ScreenData

      func_display
      lda #<myDisplayList
      sta DLPTRS
      lda #>myDisplayList
      sta DLPTRS+1

      jmp func_display

      .local myDisplayList
      .byte $42
      .word ScreenData
      .byte $41
      .word myDisplayList
      .endl

      .local ScreenData
      .endl

      END.

      run BEGIN


      i wszystko działa zgodnie z matematyką. Cztery razy pięć to jest dwadzieścia. Taka wartość znajduje się w akumulatorze jak i w komórce pamięci pod adresem $2100 jednakże na ekranie wyświetla się cyfra 4, co jest zgodne z prawdą, ponieważ liczba 20 w kodzie wewnętrznym Atari oznacza cyfrę 4



      Mam prośbę do Was, czy jest jakiś prosty sposób, niewymagający nadmiernego kodu, aby jednak taki wynik wyświetlić sobie w prawidłowy sposób? Oraz, jak to się robi profesjonalnie? (np. w grach - przecież w jakiś sposób Wynik jest wyświetlany na ekranie prawidłowo! :D )

      Dziękuję z góry za Wasz czas i jakąkolwiek chęć odpowiedzi na moje bzdury!

      Pozdrowienia dla wszystkich Atarowców!
      • 2: CommentAuthormono
      • CommentTime13 Nov 2024 22:11 zmieniony
       
      ->link<- Zapis w systemie dziesiętnym.
      • 3: CommentAuthormarok
      • CommentTime14 Nov 2024 00:11
       
      hmm,

      to co niżej zapodam jest znacznie dłuższe od wersji z Atariki (może nawet 2 razy)

      robi dokładnie to samo, z zastrzeżeniem że zapisuje wynik od tyłu i dokładnie tyle umieszcza cyferek ile potrzeba (bez zer z przodu)
      robi użytek z flagi D proc. (tak by trochę wypadało) i pozostawia wolny rejestr X

      wersja do wyświetlania cyfr do 99 byłaby wyraźnie krótsza (ale nadal dłuższa od wersji zaproponowanej wcześniej)

      hex equ $fe
      tmp equ $ff
      nul equ $fd

      ekr equ 88

      org $600

      lda #255

      ldy #0
      sty nul
      ldy #3
      sed
      sta hex
      :4 lsr @
      sta tmp
      clc
      adc #0
      adc tmp
      sta tmp
      adc tmp
      adc tmp
      adc #0
      adc hex
      rol nul
      adc #0
      rol nul
      cld
      @ pha
      and #$f
      ora #$10
      sta (ekr),y
      dey
      pla
      :4 lsr @
      bne @-
      lsr nul
      rol @
      lsr nul
      adc #0
      bne @-

      beq *
      • 4:
         
        CommentAuthorpirx
      • CommentTime14 Nov 2024 06:11
       
      jak widzisz ten problem spędzał sen z oczu każdemu programatorowi
      tutaj bardzo słaba procka, którą męczyłem >20lat temu: ->link<-

      dalej jedzie taka od bajta.
      kurcze, to by można było skrócić @Pecus patrz!!!
      • 5: CommentAuthormarok
      • CommentTime14 Nov 2024 09:11
       
      przy całej ekwilibrystyce z kodem w podanym przykładzie zauważam teraz, że można to łatwym kosztem skrócić o 2 bajty

      piszę jak:
      clc, adr #0 przenieść przed (pierwsze) sta tmp
      adc #0 przed adc hex - można się pozbyć (to 2 bajty)
      • 6: CommentAuthoriSiek
      • CommentTime14 Nov 2024 10:11 zmieniony
       
      @mono @marok @pirx - ślicznie Wam dziękuję.
      W wolnej chwili siądę i przejrzę to wszystko. Postaram się zrozumieć i zaimplementować w swoich projektach bo znacznie wygodniej analizować wynik w zrozumiałej dla siebie formie niż przeglądać różne tabele w celu rozszyfrowania wartości końcowych :)


      jak widzisz ten problem spędzał sen z oczu każdemu programatorowi

      Kurcze sądziłem, że to tylko ja tak mam. Przyznam, że trochę lepiej się poczułem. Może jeszcze coś ze mnie będzie ;)

      Co ważne, gdy już zacznę coś pisać, opierającego się na wartościach liczbowych do wyświetlenia, to postaram się wymyśleć system punktowy nieprzekraczający 65535 (2 bajty) aby uniknąć zabawy z przekroczeniem 16 bitów.

      Z tego co widziałem, wówczas czekać mnie będzie zabawa z wyświetlaniem wartości tekstem (jak w przykładzie gry 1K BLASTER).

      Tak na marginesie, czy tak to się właśnie robi w grach na małe Atari gdzie wartość wyniku przekracza grubo granicę 16 bitów?
      • 7:
         
        CommentAuthorshanti77
      • CommentTime14 Nov 2024 10:11 zmieniony
       
      Wartości , które chce się wyświetlać najlepiej zapisywać w kodzie BCD. W każdej połówce bajtu mamy wtedy zapisaną jedną cyfrę z systemu dziesiętnego (4 bity na cyfrę), prosto wtedy wyświetlić np. SCORE.

      ; 
      sed
      lda score
      adc #1
      sta score
      lda score+1
      adc #0
      sta score+1
      cld


      Wyświetla liczbę z A w pozycji X
      ; 
      ldx #0
      lda score+1
      jsr print
      lda score
      jsr print
      jmp *

      print
      pha
      :4 lsr
      clc
      adc #$10
      sta screen,x
      inx
      pla
      and #15
      adc #$10
      sta screen,x
      inx
      rts



      Do śledzenia zawartości komórek pamięci w Altirze można zastosować polecenie : "wb nazwa_komórki/adres" , albo zatrzymać kod po wykonaniu działania (ja wstawiam zazwyczaj "dta 2").
      • 8: CommentAuthoriSiek
      • CommentTime14 Nov 2024 10:11
       
      @shanti77 również wielkie dzięki za Twoją wskazówkę!

      Do śledzenia zawartości komórek pamięci można zastosować polecenie "wb nazwa_komórki/adres" w Altirze, albo zatrzymać kod po wykonaniu działania (ja wstawiam zazwyczaj "dta 2").

      Tak, do bardziej zaawansowanych programów bez umiejętności posługiwania się trybem DEBUG w Altirze zapewnie się nie obejdzie.

      Powiedz mi proszę, co w tym przypadku da zdefiniowanie dta 2 jako wartość byte = 2?
      • 9: CommentAuthoriSiek
      • CommentTime14 Nov 2024 10:11
       
      @pirx nie ma słabych procedur. Jeśli działa poprawnie to znaczy, że jest dobra. A to, że nie jest optymalnie napisana lub zawiera pokrętną logikę, to inny aspekt :)

      Sam czasami w językach wysokiego poziomu coś napiszę bo mi było łatwiej lub wygodniej. A gdy spojrzy się na to po pewnym czasie to aż dziw, jak coś takiego można było popełnić. A co dopiero muszą sobie pomyśleć inni, którzy na taki kod natrafią ;)
      • 10:
         
        CommentAuthorPecus
      • CommentTime14 Nov 2024 10:11
       
      @pirx ... ja to już kiedyś optymalizowałem i sporo bajtów odzyskałem z tej procki.
      Spojrzałem teraz na nią i na pierwszy rzut oka to nie wiem co ona robi :)
      • 11:
         
        CommentAuthorjhusak
      • CommentTime14 Nov 2024 11:11
       
      @iSiek

      ->link<-

      Jest tam:
      JAM (KIL, HLT)
      These instructions freeze the CPU.

      The processor will be trapped infinitely in T1 phase with $FF on the data bus. — Reset required.

      Instruction codes: 02, 12, 22, 32, 42, 52, 62, 72, 92, B2, D2, F2


      .dta 2 to po prostu wstawienie instrukcji JAM (kill), która normalny procek zatrzymuje, a w emulatorze (może nawet) przechodzi do monitora.
      • 12: CommentAuthoriSiek
      • CommentTime14 Nov 2024 11:11
       
      @jhusak dziękuję za wyjaśnienia i link. Teraz jest to dla mnie bardziej zrozumiałe.
      • 13: CommentAuthormarok
      • CommentTime14 Nov 2024 12:11 zmieniony
       
      jeśli wartość wyniku przekracza grubo granicę 16 bitów

      i jeśli zastosować się do wskazówek Shanti'ego (z trzymaniem wartości w formacie BCD)
      to pewnie można zrobić np. tak:

      cscore    ldx #-1
      clc
      sed
      @ inx
      adc score,x
      sta score,x
      lda #0
      bcs @-

      cld
      rts


      ; dodaj 125236 punkty do score

      lda #$36
      jsr cscore
      lda #$52
      ldx #1-1
      jsr cscore+3
      lda #$12
      ldx #2-1
      jsr cscore+3

      ; dodaj 1000 punkty do score
      lda #$10
      ldx #1-1
      jsr cscore+2



      edit,
      krótsze
      cscore    ldx #-1
      clc
      sed
      inx
      adc score,x
      sta score,x
      cld
      rts



      ; dodaj 125236 punkty do score

      lda #$36
      jsr cscore
      lda #$52
      jsr cscore+3
      lda #$12
      jsr cscore+3
      lda #0
      bcs *-5
      • 14: CommentAuthortebe
      • CommentTime14 Nov 2024 13:11
       
      Conversion of a number in int16 (lo/hi) into a string in CnvStr.

      ->link<-
      • 15: CommentAuthor0xF
      • CommentTime14 Nov 2024 13:11
       
      Nie rób takich rzeczy:
      jsr cscore+3

      szczególnie jak jesteś początkujący. Bardzo szybko się pomylisz.
      Wstaw nową etykietę w odpowiednie miejsce.

      Jeśli mamy 6-cyfrowy wynik w BCD, to dodanie do niego 125236 to będzie:
      clc
      sed
      lda #$36
      adc score
      sta score
      lda #$52
      adc score+1
      sta score+1
      lda #$12
      adc score+2
      sta score+2
      cld
      • 16: CommentAuthor0xF
      • CommentTime14 Nov 2024 13:11
       
      Wiele wartości wyświetlanych na ekranie gra może modyfikować bezpośrednio w pamięci ekranu. Np. zwiększenie 10-cyfrowego wyniku o 1:

      ldx #9
      bne inc_score_2
      inc_score_1
      lda #$10
      sta score,x
      dex
      inc_score_2
      lda score,x
      cmp #$19
      beq inc_score_1
      inc score,x
      • 17: CommentAuthoriSiek
      • CommentTime14 Nov 2024 13:11 zmieniony
       
      @marok Wielkie dzięki, tylko nie do końca rozumiem (szczerze to w ogóle) zastosowanie skoków do procedur z +2 i +3 Dlaczego JSR odwołuje się do etykiety z plusem?

      @tebe Dziękuję. Dość długi kod, więc musze go sobie na spokojnie poczytać i postarać się zrozumieć, i zobaczyć jak to działa w praktyce. Fajnie, że wynik jest skonwertowany na tekst. Łatwiej będzie to wyświetlać na ekranie, nawet kolorki dodać ;)

      @0xF
      Nie rób takich rzeczy:

      jsr cscore+3

      No właśnie nie zamierzam bo kompletnie nie wiem co znaczą i co robią :)

      Dziękuję za Twoje przykłady i je postaram się umiejętnie wykorzystać w nauce.

      Super wszyscy jesteście! Nie sądziłem, że ktokolwiek będzie chciał mi takie podstawy tłumaczyć, a tutaj proszę masa pomocnych dłoni. Już wiem, że dzięki waszej dużej wiedzy, sam się czegoś nauczę!
      • 18: CommentAuthormarok
      • CommentTime16 Nov 2024 09:11
       
      w nawiązaniu do pytania:
      ->link<-

      @iSiek: scoring jest nieliniowy (nie co +10 rośnie; ostatnie 0 w score może być zaledwie "atrapą" - "doklejane")


      więc to nie jest dokładnie to samo (lub wyłącznie to), co obsługuje score
      • 19: CommentAuthorj_g
      • CommentTime16 Nov 2024 12:11 zmieniony
       
      Dla kompilatora etykieta to po prostu adres pamięci, określany na sztywno podczas kompilacji kodu. Jeśli kompilatorowi wyjdzie, że etykieta "cscore" to np. $a0a0, to etykieta "cscore+3" kompilator przy kompilacji podmienia na sztywno na adres $a0a3 (miejsce o 3 bajty dalej w pamięci). Problemem jest to, że jeśli potem zmodyfikujesz kod zaraz po etykiecie "cscore" to skok do "cscore+3" poleci już w maliny. 0xF sugeruje byś dodał w odpowiednie miejsce kolejną etykietę i do niej się odwoływał, a nie do jakiegoś ustawionego na sztywno offsetu (+3). Zwiększa to czytelność kodu i nie musisz potem cały czas pilnować i pamiętać by niczego tam w kodzie nie zmieniać. Z drugiej strony prościej napisać "+3" niż wymyślać nazwę etykiecie i ją wpisywać.

      Oczywiście, jeśli chcesz wiedzieć dokąd prowadzi cscore+3 to musisz wiedzieć, że np. ldx #-1 zajmuje dwa bajty w pamięci, a clc jeden bajt.
      • 20: CommentAuthormarok
      • CommentTime18 Nov 2024 10:11
       
      Lepszego objaśnienia z obiektywną oceną stosowania takiego zapisu sam bym raczej nie napisał - więc dzięki "j_g".


      Kilka innych argumentów, jakie można by jeszcze ("od biedy") przywołać.

      Pisząc blisko przy lewym marginesie w liniach kodu dodawanie licznych etykiet zaburza w mojej percepcji czytelność.

      (Po co pisać blisko? - Niegdyś było to naturalne ze względów pamięciowych, zresztą z tego samego powodu ograniczało się użycie etykiet, dodatkowo istniały realne limity ich liczby. Jest to więc pewien wyniesiony z przeszłości nawyk lub słabo uzasadnialna skłonność do ograniczania objętości źródła. Tym drugim też mogę być "dotknięty", btw.)

      (Jak przy nazywaniu etykiet nie lubię dodawania komentarzy. Konstruowanie "niewstydliwych", czytelnych a zwartych komentów stanowi dla mnie "mission impossible".)

      Jeśli odniesienie do wcześniejszej etykiety jest krótkie (cyfra po +/-) groźba zagrożenia pomyłką wydatnie maleje.

      Przede wszystkim jednak jest to "styl" który w moim odczuciu jest akceptowalny w krótkich "utworach", pisanych możliwie szybko i dla własnego użytku (lub osób które taki styl same nieźle tolerują - tu w miarę istotna uwaga, nie jest tak, że jest to wcale tak rzadkie).

      Zgodzę się jednak, że zwłaszcza osobom, które wchodzą w programowanie jest dobrze unikać podawania w przykadach kodu tak (nie) przygotowanego - "anty wychowawcze".
      (Jednak nawyki zwracania szczególnej uwagi i zachowania pewnej czujności związane z doświadczeniem na własnych błędach, które wynikają ze stosowania takiego "uproszczonego" stylu pisania kodu, trzeba raczej dopiero nabyć.)