atarionline.pl Jak połączyć plik .s z plikiem .c w jedną binarkę? - 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: CommentAuthorlizard1982
      • CommentTime14 Nov 2020 19:11 zmieniony
       
      Witam,

      Jak skompilować plik .s razem z plikiem .c do binarki *.tos ?

      Chcę połączyć plik .s z plikiem .c w jedną binarkę, ale nie wiem jak...

      Korzystam z vasm oraz vbcc.

      Męczę się już z tym od paru godzin...

      [PLIK MAIN.C]
      extern void wait1(void);
      extern void exit1(void);

      int main()
      {
      wait1();
      exit1();

      return 0;
      }

      [PLIK GEMDOS.S]
      GEMDOS equ 1
      GEMDOS__getchar equ 1
      GEMDOS__writestr equ 9
      GEMDOS__supervisor equ 32

      section text

      _wait1
      move.w #GEMDOS__getchar,-(A7)
      trap #GEMDOS
      addq.l #2,A7
      rts

      _exit1
      clr.l -(a7)
      trap #1

      public _wait1
      public _exit1

      Mam tak, ale to nie działa...
      vbcc -quiet test.c -o="test.s"
      vasm -nocase -devpac -m68000 -Faout -phxass -no-opt -o GEMDOS.o GEMDOS.s
      vasm -nocase -devpac -m68000 -Faout -phxass -no-opt -o test.o test.s
      vlink -b ataritos -o ppp.tos GEMDOS.o test.o

      Jeszcze mam pytanie jak z poziomu asemblera pobrać parametr podany przy wywołaniu funkcji w C ?
      • 2: CommentAuthorbob_er
      • CommentTime15 Nov 2020 14:11 zmieniony
       
      Ja tej sztuki dokonałem tutaj: ->link<- Też używałem VASM i VBCC w wersjach w miarę nowych (być może najnowszych).

      U mnie jest mała różnica, bo kod napisany w ASM ładuję z zewnętrznego pliku (pliki DLL w grze), ale równie dobrze można binarkę taką przerobić na statyczną tablicę. Wtedy nic nie musisz doładowywać, i wszystko siedzi w pamięci.

      Zatem pokolei, jak tego dokonałem:
      1. ASM - Na tym etapie nie znamy docelowego umiejscowienia w pamięci, więc kod trzeba było pisać w sposób relokowalny, czyli odpadają rozkazy typu JMP i JSR. Kod w ASM powinien również przywrócić zawartość rejestrów.
      2. Kod taki asembluję do gołego RAWa, bez żadnych nagłówków. Czyli VASM z opcjami "-Fbin -m68000".
      3. W pliku C musisz mieć (w ten czy inny sposób) adres, gdzie zasemblowany blok mieć będziesz. To będzie zapewne adres jakiejś tablicy.
      4. By wywołać jakąś funkcję ASM z kodu w C używam takiej konstrukcji:
      a) najpierw deklaruję funkcję w C:
      void asm_init(__reg("a0") uint32_t* code, __reg("d0") uint16_t seek, __reg("a1") uint16_t* func_params) = "\tadd.l (a0,d0),a0\n\tjsr (a0)\n";

      b) a potem już wywołanie:
      asm_init(s_dll, ASM_INIT, func_params);

      s_dll - adres miejsca w pamięci, gdzie siedzi kod ASM,
      ASM_INIT - numer funkcji, to opiszę niżej, bo sprawa rozwojowa :).
      func_params - adres na strukturę z parametrami, która będzie przekazana do ASM. Robiłem to w ten sposób, ponieważ zauważyłem, że używanie większej ilości rejestrów do parametrów nie działało. Być może to była specyfika wersji VBCC, na której robiłem rozeznanie.
      5. Numer funkcji. To jest taki mój wymysł, który akurat potrzebny był. U mnie chodziło o to, że w ASM był napisany kod, który zajmował się tylko wyświetlaniem (które trochę inaczej się robi w HIRES i LORES). Zatem tak naprawdę potrzebowałem większej ilości dostępnych funkcji. Początek mojego pliku ASM wyglądał tak:
      dc.l func_init
      dc.l func_clear
      dc.l func_close
      itd...

      Te funkcje miały zatem indeksy:
      #define ASM_INIT 0
      #define ASM_CLEAR 4
      #define ASM_CLOSE 8
      itd...

      Stąd też rozkaz ADC w kodzie w C (punkt 4a).

      To chyba tyle czarnej magii :).
      Nie wiem, czy jasno to opisałem - jeśli nie - pytaj dalej.

      btw: miałem o tym tekst jakiś większy napisać, ale uprzedziłeś pytaniem :).

      edit: znacznik 'code'
      • 3:
         
        CommentAuthorKaz
      • CommentTime15 Nov 2020 15:11
       
      Panowie, przypomnę tylko o znacznikach [ code ] [ / code ], co pomaga wyróżnić fragmenty kodu, a więc zwiększyć czytelność.
      • 4: CommentAuthorjpacanowski
      • CommentTime15 Nov 2020 15:11 zmieniony
       
      Dzięki za CENNE informację :)

      Poradziłem sobie, czego efektem jest ten działający kod :)

      [PLIK MAIN.C]
      #include "gemdos.h"
      #include "types.h"

      int main() {

      write_str("Hello world\0");
      getchar(); //czekaj na klawisz
      pterm();

      return 0;
      }


      [PLIK GEMDOS.H]
      #ifndef _GEMDOS_H_
      #define _GEMDOS_H_

      extern void write_str(const u8 *s);
      extern s32 getchar(void);
      extern void pterm(void);

      #endif


      [PLIK GEMDOS.S]
      _write_str
      move.l (4,a7), a0
      pea (a0)
      move.w #GEMDOS__writestr,-(A7)
      trap #GEMDOS
      addq.l #6,A7
      rts

      _getchar
      move.w #GEMDOS__getchar,-(A7)
      trap #GEMDOS
      addq.l #2,A7
      rts

      _pterm
      clr.l -(a7)
      trap #1


      Lecę dalej rozwijać swoją małą bibliotekę do Atari :D
      • 5:
         
        CommentAuthortdc
      • CommentTime19 Nov 2020 05:11
       
      Dopisz do tej biblioteki OpenGL(initialize) - przyda się też innym :D