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 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 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
     
    Panowie, przypomnę tylko o znacznikach [ code ] [ / code ], co pomaga wyróżnić fragmenty kodu, a więc zwiększyć czytelność.
    • 4: CommentAuthorjpacanowski
    • CommentTime15 Nov 2020 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
     
    Dopisz do tej biblioteki OpenGL(initialize) - przyda się też innym :D