atarionline.pl Kod maszynowy w BASIC-u (DATA, strona 6), zmiana lokalizacji - 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: CommentAuthorbartgo
      • CommentTime3 Jan 2024 14:01 zmieniony
       
      Jestem zielony w asemblerze. Mam sobie kod z Bajtka (LINIJKA) - ładuje kod na stronę szóstą, sprawdza sumę kontrolną i uruchamia.

      Chcę wziąć ten kod maszynowy i wsadzić w "słowo" Forth-a. Niestety, nie mogę użyć strony szóstej (są tam bufory do obsługi dyskietki).

      Jakie kroki należałoby wykonać, żeby sprawdzić czy kod można umieścić "gdzieś indziej" i ewentualnie zmodyfikować?

      Chyba:
      - zrobić deasemblację robaczków do mnemoników i danych (jakiś tool w basicu albo ręcznie na kartce)
      - namierzyć które mnemoniki to adresowanie zależne od umiejscowienia w pamięci
      - "zmienić"
      - przemalować kod z powrotem na maszynowy

      Czy dobrze kombinuję? Inne sugestie?
      • 2: CommentAuthorZenon
      • CommentTime3 Jan 2024 16:01
       
      Jeżeli kod jest relokowalny to zmienić linię 10 na inne adresy (wolne), zachowując miedzy nimi tą samą różnicę.
      Zmienić w lini 30 adres początku kodu, stąd Basic uruchomi kod
      A jeżeli nie jest relokowalny to, odcyfrować co autor miał namyśli i pozmieniać adresy. Jednocześnie zmienić w linii 20 wartość sumy kontrolnej
      • 3:
         
        CommentAuthorjhusak
      • CommentTime3 Jan 2024 16:01 zmieniony
       
      Najprościej to przenieść na inny adres, np. większy o 42, zrobić usr(1536+42) i zobaczyć, co z tego wyjdzie. Jak tak samo - znaczy, że kod relokowalny.
      Jednak wydaje mi się, że widzę tam charakterystyczne 33,6, potem 41,6, potem znowu 33,6, co oznaczało by dane bezwzględne.
      Poza tym, jak to uruchomisz w emulatorze, to dezasemblacja, mimo, że jesteś zielony, to będzie dość przejrzysta. Bo asembler to:

      lda #$60 ; load akumulator
      sta 712 ; store akumulator

      i już masz poke (712,$60)

      6502 ma 3 rejestry: a (akumulator) ,x,y, - indeksowe, reszta to prościzna. W jeden wieczór załapiesz.

      Najpierw robisz proste programiki, typu przepisz generator znaków:
      ldy #0
      loop
      lda romgenerator,y
      sta ramgenerator,y
      lda romgenerator+256,y
      sta ramgenerator+256,y
      lda romgenerator+512,y
      sta ramgenerator+512,y
      lda romgenerator+768,y
      sta ramgenerator+768,y
      iny
      bne loop
      rts

      A potem bardziej skomplikowane :)
      • 4: CommentAuthorlzd
      • CommentTime3 Jan 2024 18:01 zmieniony
       

      jhusak:

      Jednak wydaje mi się, że widzę tam charakterystyczne 33,6, potem 41,6, potem znowu 33,6, co oznaczało by dane bezwzględne.

      Jest też kod, który sam siebie modyfikuje, np: 141,33,6, czyli STA $0621 nadpisuje pierwsze wystąpienie 38 w linii 50.

      Biorąc pod uwagę niewielki rozmiar programu, przepisanie go pod inny adres jest chyba najlepszym rozwiązaniem. Przy okazji można spróbować przerobić go na niezależny od pozycji w pamięci.
      • 5: CommentAuthorbartgo
      • CommentTime3 Jan 2024 18:01
       
      Dzięki!

      Czyli przykładowo, jeśli STA $0621 pakuje wartość z A do $21 na stronę 6, mógłbym to przerobić na adresowanie idące od początku miejsca na kod = offset (?) $21 bajtów. Całość raczej nie będzie się zaczynała od początku strony, więc ostatecznie nie będzie tam szóstek, będzie inny kod operacji itp.

      Więc następny krok to muszę odpalić kod pod bejzykiem i deasemblować stronę szóstą, szukając różnych trybów adresowania - deasemblerem który NIE ładuje się na stronę szóstą albo wbudowanym w emulator :)
      • 6: CommentAuthormarok
      • CommentTime3 Jan 2024 20:01
       
      Zmiana postaci kodu na właściwą (cyfr w liniach DATA) pod inny już adres umieszczenia nie musi oznaczać konieczności deasemblacji (choć działając pod emulatorem powinno się z tej sposobności skorzystać - dla pewności czy w dobrym miejscu za każdym razem podmieniamy cyfrę 6 na inną, obraną - i na tym też polega cały "modus operandi" tej transformacji kodu pod inny adres).

      Żeby to zadziałało, po tak prosto przeprowadzonych zmianach, trzeba tylko dopilnować by nowy adres lokalizacji kodu (po przeniesieniu) rozpoczynał się ponownie, jak dla adresu 1536, od początku strony pamięci (tzw. wyrównanie do granicy strony, czyli adres podzielny przez 256).

      W teorii może się zdarzyć, że nie każda wartość cyfrowa 6 powinna być zmieniona, bo może ona odnosić się do młodszej połówki adresu bezpośredniego (a naszym celem jest wyłącznie podmienić starszą połówkę adresu) lub być argumentem dla trybu natychmiastowego adresowania rozkazu, akurat bez związku z adresem lokalizacji programu.

      Taka zmiana na szybko ma szansę okazać się na tak krótkim kodzie ("przypadkowo") całkowicie prawidłową.


      > "Całość raczej nie będzie się zaczynała od początku strony, więc ostatecznie nie będzie tam szóstek"

      nie tylko że nie będzie tam szóstek, ale wszystkie wartości poprzedzające szóstkę (bo taki jest szyk argumentów adresu dla trybu adresowania bezpośredniego, że najpierw idzie młodsza połówka adresu) będą powiększone o jakiś parametr p - stałego przesunięcia od początku strony
      • 7:
         
        CommentAuthorjhusak
      • CommentTime3 Jan 2024 21:01 zmieniony
       
      @bartgo - możesz użyć dis6502 czy to w wersji pod linuksa, czy też interaktywne narzędzie ebiguy:
      ->link<- dla windows.

      Jak zdezasemblujesz, to powinieneś wpaść na pomysł, jak zrobić zmienne na stronie zerowej :)

      Śmieszne (i niezłe), wrzuciłem ten obrazek z kodem do ->link<-
      i w liczbach się w ogóle nie pomylił, tylko zamiast zmiennej I było 1. No i U zamiast O w komentarzu.
      • 8:
         
        CommentAuthorjhusak
      • CommentTime3 Jan 2024 21:01 zmieniony
       
      wyszło:
      0600: 68        PLA
      0601: A9 16 LDA #$16
      0603: 8D 28 02 STA $0228 ;CDTMA2
      0606: A9 06 LDA #$06
      0608: 8D 29 02 STA $0229 ;CDTMA2+1
      060B: A9 08 LDA #$08
      060D: 8D 1A 02 STA $021A ;CDTMV2
      0610: A9 40 LDA #$40
      0612: 8D 0E D4 STA $D40E ;NMIEN
      0615: 60 RTS
      0616: AD DC 02 LDA $02DC ;HELPFG
      0619: F0 2B BEQ $0646
      061B: EE 21 06 INC $0621
      061E: A9 20 LDA #$20
      0620: 8D 26 9C STA $9C26
      0623: EE 29 06 INC $0629
      0626: A9 02 LDA #$02
      0628: 8D 25 9C STA $9C25
      062B: AD 21 06 LDA $0621
      062E: C9 3C CMP #$3C
      0630: D0 0F BNE $0641
      0632: A9 26 LDA #$26
      0634: 8D 21 06 STA $0621
      0637: A9 02 LDA #$02
      0639: 8D 3C 9C STA $9C3C
      063C: A9 25 LDA #$25
      063E: 8D 29 06 STA $0629
      0641: A9 00 LDA #$00
      0643: 8D DC 02 STA $02DC ;HELPFG
      0646: A9 08 LDA #$08
      0648: 8D 1A 02 STA $021A ;CDTMV2
      064B: 60 RTS
      • 9: CommentAuthorbartgo
      • CommentTime3 Jan 2024 22:01 zmieniony
       
      Super pomoc, nie spodziewałem się takiego odzewu :)

      Zajrzałem do Ruszczyca (tym razem nie do Fortha) i chyba łapię:
      - PLA - chyba nie potrzebne, zresztą zaraz akumulator jest nadpisany
      - LDA #$... - nie zmieniam
      - LDA/STA $ - jeśli NIE JEST to strona 6 to są to konkretne operacje których adres musi zostać jak jest (przerwania, ANTIC, obsługa klawiszy itp); jeśli strona 6 to zmieniam żeby wskazywało odpowiednie komórki pamięci (lub jakieś zmienne Forth, zobaczy się)
      - z rozgałęzieniami (BEQ, BNE) pewno poradzę sobie natywnymi instrukcjami asemblera Forth (IF, itp).
      - itd, usiądę na spokojnie to rozbroję
      - niejasne na razie jest tylko dla mnie RTS pod 0615 - nie widzę jak wskoczyć do dalszej części kodu ale ogarnę, to już kwestia prześledzenia


      Dzięki.

      I Zientara się przydaje teraz - PPSO, super!!
      • 10:
         
        CommentAuthormaly_swd
      • CommentTime3 Jan 2024 22:01 zmieniony
       
      Pla na początku jest potrzebne jak uruchamiasz kod z basica przez usr. Coś jest potem chyba ze stosu ściągane. Ale mogę się mylić to było 30 lat temu..
      • 11:
         
        CommentAuthorjhusak
      • CommentTime3 Jan 2024 23:01 zmieniony
       
      Usr() na dzieńdobry wrzuca na stos ile argumentów jest podanych (o ile dobrze pamiętam). Stąd puste pla. Następny fragment od 616 to jest przerwanie, bo do 228 i 229 wpisany jest ten adres na. początku.
      228,229 CDTMA2
      System timer two jump address. Not used by the OS, available to
      user to enter the address of his or her own routine to JMP to when
      the timer two (538, 539; $21A, $21B) count reaches zero.
      Initialized to zero; the address must be user specified. NMI



      Więc ta procedura od 616 wykonuje się na przerwaniach, zapewne co 8 ramek :)

      218,219 CDTMV1
      System timer one value. Counts backwards from 255. This SIO
      timer is decremented every stage one VBLANK. When it reaches
      zero, it sets a flag to jump (JSR) through the address stored in
      locations 550, 551 ($226, $227). Only the realtime clock
      (locations 18-20; $12-14), timer one, and the attract mode
      register (77; $4D) are updated when the VBLANK routine is cut
      short because time-critical code (location 66; $42 set to non-zero
      for critical code) is executed by the OS. Since the OS uses timer
      one for its I/O routines and for timing serial bus operations
      (setting it to different values for timeout routines), you should use
      another timer to avoid conflicts or interference with the operation
      of the system.
      • 12: CommentAuthorbartgo
      • CommentTime3 Jan 2024 23:01
       
      No tak, i już widzę skąd to RTS w środku kodu. Super!

      PLA usuwa liczbę parametrów ze stosu (pewno jest ich zero). Jeśli Forth nie używa tego, do wywalenia.

      Ostatnio tak się podjarałem przy kupnie stacji 1050. Czyli, miesiąc temu :)