kategoria: Asembler
[#1] Konwersja asm x86 do 68k
Przenoszę temat tutaj może uda się coś przetłumaczyć.

Tutaj jest kod asm MK3

https://github.com/SlasherX5/mk3reboot/tree/main/ASM
1
[#2] Re: Konwersja asm x86 do 68k

@Artur Jarosik, post #1

Wrzucam jeszcze raz skonwertowany x86 różnymi AI

x86

include win95.i



CONTEXT_ip          equ     0
CONTEXT_esp         equ     4
CONTEXT_ebp         equ     8
CONTEXT_ebx         equ     12      
CONTEXT_ecx         equ     16  
CONTEXT_esi         equ     20  
CONTEXT_edi         equ     24  


    BEGIN_CODE
_start_::
EXTERN _main_context : DWORD

    public _context_init_main
_context_init_main proc near
; void context_init_main(CONTEXT *main_context)
    mov     eax,dword ptr 4[esp]            ; eax = save_context
    mov     dword ptr CONTEXT_esp[eax],esp  ; save esp
    mov     dword ptr CONTEXT_ebp[eax],ebp  ; save ebp 
    mov     dword ptr CONTEXT_ebx[eax],ebx  ; save ebx
    mov     dword ptr CONTEXT_ecx[eax],ecx  ; save ecx
    mov     dword ptr CONTEXT_esi[eax],esi  ; save esi
    mov     dword ptr CONTEXT_edi[eax],edi  ; save edi
    ret
_context_init_main endp


    public _context_kill_switch
_context_kill_switch proc near
; void context_kill_switch(Context *restore_context)
    ; put in new context and jump to new ip

    mov     eax,4[esp]                      ; move context to eax
    jmp     go_context

    public _context_switch 
_context_switch proc near
; int context_switch(Process *to,Process *from);

; EAX is scratch    
; return address is in [ESP]
; args in stack before return address 
;
; save current context with the return address as the new ip of the saved
; context, then load a new context and jump to it's new ip. 


    mov     eax,dword ptr 8[esp]            ; eax = save_context
    pop     dword ptr CONTEXT_ip[eax]       ; pop return address into ip 
    mov     dword ptr CONTEXT_esp[eax],esp  ; save esp
    mov     dword ptr CONTEXT_ebp[eax],ebp  ; save ebp 
    mov     dword ptr CONTEXT_ebx[eax],ebx  ; save ebx
    mov     dword ptr CONTEXT_ecx[eax],ecx  ; save ecx
    mov     dword ptr CONTEXT_esi[eax],esi  ; save esi
    mov     dword ptr CONTEXT_edi[eax],edi  ; save edi
    mov     eax,[esp]                       ; move goto context to eax

go_context::     ; put in new context and jump to new ip

    mov     esp, dword ptr CONTEXT_esp[eax] ; now on new stack
    mov     ebp,dword ptr CONTEXT_ebp[eax]  ; restore ebp 
    mov     ebx,dword ptr CONTEXT_ebx[eax]  ; restore ebx
    mov     ecx,dword ptr CONTEXT_ecx[eax]  ; restore ecx
    mov     esi,dword ptr CONTEXT_esi[eax]  ; restore esi
    mov     edi,dword ptr CONTEXT_edi[eax]  ; restore edi

    jmp     dword ptr CONTEXT_ip[eax]       ; launch new context 

_context_switch endp
_context_kill_switch endp

    public _context_jump 
_context_jump proc near

; int local_context_jump(Context *to);
;
; jump to a new entry point within the same context setting new 
; stack and frame to the input 
;
    mov     eax,dword ptr 4[esp]            ; eax = save_context
    mov     esp, dword ptr CONTEXT_esp[eax] ; now on new stack
    mov     ebp,dword ptr CONTEXT_ebp[eax]  ; restore ebp 
    jmp     dword ptr CONTEXT_ip[eax]       ; jump to new entry point 
_context_jump endp

    end
[#3] Re: Konwersja asm x86 do 68k

@Artur Jarosik, post #2

68k
Claude 3.7
; Struktura CONTEXT dla 68k
CONTEXT_ip   EQU  0    ; Adres instrukcji (PC)
CONTEXT_a7   EQU  4    ; Stack pointer (A7/SP)
CONTEXT_a6   EQU  8    ; Frame pointer (A6/FP)
CONTEXT_d2   EQU  12   ; Zachowane rejestry
CONTEXT_d3   EQU  16
CONTEXT_d4   EQU  20
CONTEXT_d5   EQU  24
CONTEXT_d6   EQU  28
CONTEXT_d7   EQU  32
CONTEXT_a2   EQU  36
CONTEXT_a3   EQU  40
CONTEXT_a4   EQU  44

    SECTION TEXT

; void context_init_main(CONTEXT *main_context)
_context_init_main:
    MOVE.L  4(A7),A0         ; A0 = wskaźnik kontekstu (pierwszy parametr)
    MOVE.L  A7,CONTEXT_a7(A0) ; Zapisz wskaźnik stosu
    MOVE.L  A6,CONTEXT_a6(A0) ; Zapisz wskaźnik ramki
    MOVE.L  D2,CONTEXT_d2(A0) ; Zapisz rejestry, które muszą być zachowane
    MOVE.L  D3,CONTEXT_d3(A0)
    MOVE.L  D4,CONTEXT_d4(A0)
    MOVE.L  D5,CONTEXT_d5(A0)
    MOVE.L  D6,CONTEXT_d6(A0)
    MOVE.L  D7,CONTEXT_d7(A0)
    MOVE.L  A2,CONTEXT_a2(A0)
    MOVE.L  A3,CONTEXT_a3(A0)
    MOVE.L  A4,CONTEXT_a4(A0)
    RTS

; void context_kill_switch(CONTEXT *restore_context)
_context_kill_switch:
    MOVE.L  4(A7),A0         ; A0 = wskaźnik kontekstu do przywrócenia
    BRA     go_context       ; Skocz do wspólnego kodu przywracania kontekstu

; int context_switch(CONTEXT *to, CONTEXT *from);
_context_switch:
    MOVE.L  8(A7),A0         ; A0 = wskaźnik kontekstu do zapisania (from)
    MOVE.L  (A7),CONTEXT_ip(A0) ; Zapisz adres powrotu jako nowy IP
    ADDQ.L  #4,A7            ; Skoryguj stos (pominięcie adresu powrotu)
    MOVE.L  A7,CONTEXT_a7(A0) ; Zapisz wskaźnik stosu
    MOVE.L  A6,CONTEXT_a6(A0) ; Zapisz wskaźnik ramki
    MOVE.L  D2,CONTEXT_d2(A0) ; Zapisz rejestry
    MOVE.L  D3,CONTEXT_d3(A0)
    MOVE.L  D4,CONTEXT_d4(A0)
    MOVE.L  D5,CONTEXT_d5(A0)
    MOVE.L  D6,CONTEXT_d6(A0)
    MOVE.L  D7,CONTEXT_d7(A0)
    MOVE.L  A2,CONTEXT_a2(A0)
    MOVE.L  A3,CONTEXT_a3(A0)
    MOVE.L  A4,CONTEXT_a4(A0)
    
    MOVE.L  4(A7),A0         ; A0 = wskaźnik kontekstu do przywrócenia (to)

go_context:
    MOVE.L  CONTEXT_a7(A0),A7 ; Przywróć wskaźnik stosu
    MOVE.L  CONTEXT_a6(A0),A6 ; Przywróć wskaźnik ramki
    MOVE.L  CONTEXT_d2(A0),D2 ; Przywróć rejestry
    MOVE.L  CONTEXT_d3(A0),D3
    MOVE.L  CONTEXT_d4(A0),D4
    MOVE.L  CONTEXT_d5(A0),D5
    MOVE.L  CONTEXT_d6(A0),D6
    MOVE.L  CONTEXT_d7(A0),D7
    MOVE.L  CONTEXT_a2(A0),A2
    MOVE.L  CONTEXT_a3(A0),A3
    MOVE.L  CONTEXT_a4(A0),A4
    
    MOVE.L  CONTEXT_ip(A0),A1 ; Pobierz adres skoku
    JMP     (A1)              ; Skocz do nowego kontekstu

; int context_jump(CONTEXT *to);
_context_jump:
    MOVE.L  4(A7),A0         ; A0 = wskaźnik kontekstu
    MOVE.L  CONTEXT_a7(A0),A7 ; Przywróć wskaźnik stosu
    MOVE.L  CONTEXT_a6(A0),A6 ; Przywróć wskaźnik ramki
    
    MOVE.L  CONTEXT_ip(A0),A1 ; Pobierz adres skoku
    JMP     (A1)              ; Skocz do nowego punktu wejścia
[#4] Re: Konwersja asm x86 do 68k

@Artur Jarosik, post #3

Grok 3

; Definicje offsetów dla struktury kontekstu
CONTEXT_pc    equ     0       ; licznik programu (PC)
CONTEXT_a7    equ     4       ; wskaźnik stosu (A7)
CONTEXT_a6    equ     8       ; wskaźnik bazowy (A6, odpowiednik EBP)
CONTEXT_d2    equ     12      ; rejestr danych D2 (odpowiednik EBX)
CONTEXT_d3    equ     16      ; rejestr danych D3 (odpowiednik ECX)
CONTEXT_d4    equ     20      ; rejestr danych D4 (odpowiednik ESI)
CONTEXT_d5    equ     24      ; rejestr danych D5 (odpowiednik EDI)

    BEGIN_CODE

; void context_init_main(CONTEXT *main_context)
    public _context_init_main
_context_init_main:
    movem.l d2-d5/a6/a7,-(a7)    ; Zapisz rejestry dla bezpieczeństwa
    move.l  4(a7),a0             ; Załaduj main_context (parametr na stosie)
    move.l  a7,(CONTEXT_a7,a0)   ; Zapisz aktualny A7 (wskaźnik stosu)
    move.l  a6,(CONTEXT_a6,a0)   ; Zapisz aktualny A6 (wskaźnik bazowy)
    move.l  d2,(CONTEXT_d2,a0)   ; Zapisz D2 (odpowiednik EBX)
    move.l  d3,(CONTEXT_d3,a0)   ; Zapisz D3 (odpowiednik ECX)
    move.l  d4,(CONTEXT_d4,a0)   ; Zapisz D4 (odpowiednik ESI)
    move.l  d5,(CONTEXT_d5,a0)   ; Zapisz D5 (odpowiednik EDI)
    movem.l (a7)+,d2-d5/a6/a7    ; Przywróć zapisane rejestry
    rts

; void context_kill_switch(Context *restore_context)
    public _context_kill_switch
_context_kill_switch:
    movem.l d2-d5/a6/a7,-(a7)    ; Zapisz rejestry dla bezpieczeństwa
    move.l  4(a7),a0             ; Załaduj restore_context
    bra     go_label             ; Przejdź do etykiety przełączania

; int context_switch(Context *to, Context *from)
    public _context_switch
_context_switch:
    move.l  (a7)+,(CONTEXT_pc,a1) ; Zapisz PC (adres powrotu) do from->pc, symulując pop
    addq.l  #4,a7                 ; Dostosuj stos (symulacja pop)
    move.l  4(a7),a1             ; Załaduj 'from' (parametr na stosie, po pop)
    move.l  (a7),a0              ; Załaduj 'to' (parametr na stosie, po pop)
    move.l  a7,(CONTEXT_a7,a1)   ; Zapisz aktualny A7 do from->a7
    move.l  a6,(CONTEXT_a6,a1)   ; Zapisz aktualny A6 do from->a6
    move.l  d2,(CONTEXT_d2,a1)   ; Zapisz D2 do from->d2
    move.l  d3,(CONTEXT_d3,a1)   ; Zapisz D3 do from->d3
    move.l  d4,(CONTEXT_d4,a1)   ; Zapisz D4 do from->d4
    move.l  d5,(CONTEXT_d5,a1)   ; Zapisz D5 do from->d5
    bra     go_label             ; Przejdź do etykiety przełączania

go_label:
    move.l  (CONTEXT_a7,a0),a7   ; Ustaw nowy wskaźnik stosu z to->a7
    move.l  (CONTEXT_a6,a0),a6   ; Ustaw nowy wskaźnik bazowy z to->a6
    move.l  (CONTEXT_d2,a0),d2   ; Ustaw nowy D2 z to->d2
    move.l  (CONTEXT_d3,a0),d3   ; Ustaw nowy D3 z to->d3
    move.l  (CONTEXT_d4,a0),d4   ; Ustaw nowy D4 z to->d4
    move.l  (CONTEXT_d5,a0),d5   ; Ustaw nowy D5 z to->d5
    jmp     (CONTEXT_pc,a0)      ; Skocz do nowego PC z to->pc

; int local_context_jump(Context *to)
    public _context_jump
_context_jump:
    move.l  4(a7),a0             ; Załaduj 'to' (parametr na stosie)
    move.l  (CONTEXT_a7,a0),a7   ; Ustaw nowy wskaźnik stosu
    move.l  (CONTEXT_a6,a0),a6   ; Ustaw nowy wskaźnik bazowy
    jmp     (CONTEXT_pc,a0)      ; Skocz do nowego PC

    END_CODE
    end
1
[#5] Re: Konwersja asm x86 do 68k

@Artur Jarosik, post #4

ChatGPT O3-mini-high

; Motorola 68k – wersja procedur przełączania kontekstu
        ; Definicje offsetów w strukturze CONTEXT:
CONTEXT_IP      equ     0       ; adres powrotu (instrukcja, do której nastąpi skok)
CONTEXT_SP      equ     4       ; wskaźnik stosu (A7)
CONTEXT_FP      equ     8       ; wskaźnik ramki (A6)
CONTEXT_D2      equ     12      ; symulacja rejestru ebx -> D2
CONTEXT_D3      equ     16      ; symulacja rejestru ecx -> D3
CONTEXT_D4      equ     20      ; symulacja rejestru esi -> D4
CONTEXT_D5      equ     24      ; symulacja rejestru edi -> D5

        ;--------------------------------------------------------------------
        ; void context_init_main(CONTEXT *main_context)
        ;
        ; Zapisuje bieżące wartości rejestrów (stos, ramka, D2-D5) do struktury
        ; głównego kontekstu.
        ; Argument (wskaźnik do CONTEXT) jest przekazywany na stosie pod offsetem 4.
        ;--------------------------------------------------------------------
        PUBLIC _context_init_main
_context_init_main:
        move.l  4(A7), A0            ; A0 = wskaźnik do main_context
        move.l  A7,  CONTEXT_SP(A0)    ; zapisuje aktualny A7 (SP)
        move.l  A6,  CONTEXT_FP(A0)    ; zapisuje aktualny A6 (FP)
        move.l  D2,  CONTEXT_D2(A0)    ; zapisuje D2 (odpowiada ebx)
        move.l  D3,  CONTEXT_D3(A0)    ; zapisuje D3 (odpowiada ecx)
        move.l  D4,  CONTEXT_D4(A0)    ; zapisuje D4 (odpowiada esi)
        move.l  D5,  CONTEXT_D5(A0)    ; zapisuje D5 (odpowiada edi)
        rts

        ;--------------------------------------------------------------------
        ; void context_kill_switch(Context *restore_context)
        ;
        ; Natychmiast przełącza kontekst na wskazany (przekazany jako argument).
        ;--------------------------------------------------------------------
        PUBLIC _context_kill_switch
_context_kill_switch:
        move.l  4(A7), A0            ; A0 = wskaźnik do restore_context
        bra     go_context

        ;--------------------------------------------------------------------
        ; int context_switch(Process *to, Process *from)
        ;
        ; Procedura zapisuje bieżący kontekst ("from") – w tym adres powrotu,
        ; stos, ramkę i rejestry (D2-D5) – a następnie przełącza kontekst na "to".
        ;
        ; Układ stosu przy wywołaniu:
        ;   0(A7)    : adres powrotu
        ;   4(A7)    : wskaźnik do kontekstu docelowego ("to")
        ;   8(A7)    : wskaźnik do kontekstu bieżącego ("from")
        ;--------------------------------------------------------------------
        PUBLIC _context_switch
_context_switch:
        move.l  8(A7), A1            ; A1 = wskaźnik do kontekstu "from"
        move.l  (A7)+, D0            ; pobiera adres powrotu (popuje ze stosu)
        move.l  D0,  CONTEXT_IP(A1)    ; zapisuje adres powrotu w from->ip
        move.l  A7,  CONTEXT_SP(A1)    ; zapisuje aktualny SP
        move.l  A6,  CONTEXT_FP(A1)    ; zapisuje aktualny FP
        move.l  D2,  CONTEXT_D2(A1)    ; zapisuje D2
        move.l  D3,  CONTEXT_D3(A1)    ; zapisuje D3
        move.l  D4,  CONTEXT_D4(A1)    ; zapisuje D4
        move.l  D5,  CONTEXT_D5(A1)    ; zapisuje D5
        move.l  (A7), A1             ; A1 = wskaźnik do kontekstu "to" (pierwszy argument)
go_context:
        move.l  CONTEXT_SP(A1), A7    ; przywraca SP (A7)
        move.l  CONTEXT_FP(A1), A6    ; przywraca FP (A6)
        move.l  CONTEXT_D2(A1), D2    ; przywraca D2
        move.l  CONTEXT_D3(A1), D3    ; przywraca D3
        move.l  CONTEXT_D4(A1), D4    ; przywraca D4
        move.l  CONTEXT_D5(A1), D5    ; przywraca D5
        move.l  CONTEXT_IP(A1), A0    ; pobiera zapisany adres powrotu
        jmp     (A0)                ; skok do nowego punktu wykonania

        ;--------------------------------------------------------------------
        ; int local_context_jump(Context *to)
        ;
        ; Skacze do nowego punktu wejścia w ramach tego samego kontekstu – przywraca
        ; stos i ramkę zapisane w strukturze kontekstu.
        ;--------------------------------------------------------------------
        PUBLIC _context_jump
_context_jump:
        move.l  4(A7), A0            ; A0 = wskaźnik do kontekstu (argument)
        move.l  CONTEXT_SP(A0), A7    ; przywraca SP ze struktury
        move.l  CONTEXT_FP(A0), A6    ; przywraca FP ze struktury
        move.l  CONTEXT_IP(A0), A0    ; pobiera zapisany adres powrotu
        jmp     (A0)                ; skok do zapisanego punktu wejścia

        END
[#6] Re: Konwersja asm x86 do 68k

@Artur Jarosik, post #1

Claude code mi wypluł coś takiego:
; Motorola 68000 version of CONTEXT.ASM
; Context switching implementation for 68K architecture

; Register offset definitions
CONTEXT_pc          EQU     0       ; Program counter
CONTEXT_sp          EQU     4       ; Stack pointer (A7)
CONTEXT_fp          EQU     8       ; Frame pointer (A6)
CONTEXT_d0          EQU     12      ; Data register D0
CONTEXT_d1          EQU     16      ; Data register D1
CONTEXT_d2          EQU     20      ; Data register D2
CONTEXT_d3          EQU     24      ; Data register D3
CONTEXT_d4          EQU     28      ; Data register D4
CONTEXT_d5          EQU     32      ; Data register D5
CONTEXT_d6          EQU     36      ; Data register D6
CONTEXT_d7          EQU     40      ; Data register D7
CONTEXT_a0          EQU     44      ; Address register A0
CONTEXT_a1          EQU     48      ; Address register A1
CONTEXT_a2          EQU     52      ; Address register A2
CONTEXT_a3          EQU     56      ; Address register A3
CONTEXT_a4          EQU     60      ; Address register A4
CONTEXT_a5          EQU     64      ; Address register A5
CONTEXT_SIZE        EQU     68      ; Total context size

    SECTION TEXT

; External references
    XREF    _main_context

; void context_init_main(CONTEXT *main_context)
; Initialize main context by saving current register state
    XDEF    _context_init_main
_context_init_main:
    MOVE.L  4(SP),A0            ; Load context pointer to A0
    MOVE.L  SP,CONTEXT_sp(A0)   ; Save stack pointer
    MOVE.L  A6,CONTEXT_fp(A0)   ; Save frame pointer
    MOVE.L  D0,CONTEXT_d0(A0)   ; Save D0
    MOVE.L  D1,CONTEXT_d1(A0)   ; Save D1
    MOVE.L  D2,CONTEXT_d2(A0)   ; Save D2
    MOVE.L  D3,CONTEXT_d3(A0)   ; Save D3
    MOVE.L  D4,CONTEXT_d4(A0)   ; Save D4
    MOVE.L  D5,CONTEXT_d5(A0)   ; Save D5
    MOVE.L  D6,CONTEXT_d6(A0)   ; Save D6
    MOVE.L  D7,CONTEXT_d7(A0)   ; Save D7
    MOVE.L  A0,CONTEXT_a0(A0)   ; Save A0
    MOVE.L  A1,CONTEXT_a1(A0)   ; Save A1
    MOVE.L  A2,CONTEXT_a2(A0)   ; Save A2
    MOVE.L  A3,CONTEXT_a3(A0)   ; Save A3
    MOVE.L  A4,CONTEXT_a4(A0)   ; Save A4
    MOVE.L  A5,CONTEXT_a5(A0)   ; Save A5
    RTS

; void context_kill_switch(Context *restore_context)
; Switch to a new context without saving current one
    XDEF    _context_kill_switch
_context_kill_switch:
    MOVE.L  4(SP),A0            ; Move context ptr to A0
    BRA.S   go_context          ; Jump to context loading code

; int context_switch(Process *to, Process *from)
; Save current context to "from" and switch to "to"
    XDEF    _context_switch
_context_switch:
    MOVE.L  8(SP),A1            ; A1 = save_context
    MOVE.L  (SP)+,CONTEXT_pc(A1) ; Save return address as PC
    MOVE.L  SP,CONTEXT_sp(A1)   ; Save stack pointer
    MOVE.L  A6,CONTEXT_fp(A1)   ; Save frame pointer
    MOVE.L  D0,CONTEXT_d0(A1)   ; Save D0
    MOVE.L  D1,CONTEXT_d1(A1)   ; Save D1
    MOVE.L  D2,CONTEXT_d2(A1)   ; Save D2
    MOVE.L  D3,CONTEXT_d3(A1)   ; Save D3
    MOVE.L  D4,CONTEXT_d4(A1)   ; Save D4
    MOVE.L  D5,CONTEXT_d5(A1)   ; Save D5
    MOVE.L  D6,CONTEXT_d6(A1)   ; Save D6
    MOVE.L  D7,CONTEXT_d7(A1)   ; Save D7
    MOVE.L  A0,CONTEXT_a0(A1)   ; Save A0
    MOVE.L  A1,CONTEXT_a1(A1)   ; Save A1
    MOVE.L  A2,CONTEXT_a2(A1)   ; Save A2
    MOVE.L  A3,CONTEXT_a3(A1)   ; Save A3
    MOVE.L  A4,CONTEXT_a4(A1)   ; Save A4
    MOVE.L  A5,CONTEXT_a5(A1)   ; Save A5
    MOVE.L  4(SP),A0            ; A0 = to_context

; Common code to load context from A0
go_context:
    MOVE.L  CONTEXT_sp(A0),SP   ; Restore stack pointer
    MOVE.L  CONTEXT_fp(A0),A6   ; Restore frame pointer
    MOVE.L  CONTEXT_d0(A0),D0   ; Restore D0
    MOVE.L  CONTEXT_d1(A0),D1   ; Restore D1
    MOVE.L  CONTEXT_d2(A0),D2   ; Restore D2
    MOVE.L  CONTEXT_d3(A0),D3   ; Restore D3
    MOVE.L  CONTEXT_d4(A0),D4   ; Restore D4
    MOVE.L  CONTEXT_d5(A0),D5   ; Restore D5
    MOVE.L  CONTEXT_d6(A0),D6   ; Restore D6
    MOVE.L  CONTEXT_d7(A0),D7   ; Restore D7
    MOVE.L  CONTEXT_a0(A0),A0   ; Restore A0 - must be last!
    MOVE.L  CONTEXT_a1(A0),A1   ; Restore A1
    MOVE.L  CONTEXT_a2(A0),A2   ; Restore A2
    MOVE.L  CONTEXT_a3(A0),A3   ; Restore A3
    MOVE.L  CONTEXT_a4(A0),A4   ; Restore A4
    MOVE.L  CONTEXT_a5(A0),A5   ; Restore A5
    MOVE.L  CONTEXT_pc(A0),-(SP) ; Push return address
    RTS                         ; Jump to new context

; int context_jump(Context *to)
; Jump to a new entry point within the same context
    XDEF    _context_jump
_context_jump:
    MOVE.L  4(SP),A0            ; A0 = to_context
    MOVE.L  CONTEXT_sp(A0),SP   ; Restore stack pointer
    MOVE.L  CONTEXT_fp(A0),A6   ; Restore frame pointer
    MOVE.L  CONTEXT_pc(A0),-(SP) ; Push return address
    RTS                         ; Jump to new entry point

    END
[#7] Re: Konwersja asm x86 do 68k

@Mirq, post #6

Na pewno 68000 to za mało
[#8] Re: Konwersja asm x86 do 68k

@Artur Jarosik, post #7

; Motorola 68040 version of CONTEXT.ASM
; Context switching implementation for 68040 architecture
; Uses 68040-specific instructions where appropriate

; Register offset definitions
CONTEXT_pc          EQU     0       ; Program counter
CONTEXT_sp          EQU     4       ; Stack pointer (A7)
CONTEXT_fp          EQU     8       ; Frame pointer (A6)
CONTEXT_d0          EQU     12      ; Data register D0
CONTEXT_d1          EQU     16      ; Data register D1
CONTEXT_d2          EQU     20      ; Data register D2
CONTEXT_d3          EQU     24      ; Data register D3
CONTEXT_d4          EQU     28      ; Data register D4
CONTEXT_d5          EQU     32      ; Data register D5
CONTEXT_d6          EQU     36      ; Data register D6
CONTEXT_d7          EQU     40      ; Data register D7
CONTEXT_a0          EQU     44      ; Address register A0
CONTEXT_a1          EQU     48      ; Address register A1
CONTEXT_a2          EQU     52      ; Address register A2
CONTEXT_a3          EQU     56      ; Address register A3
CONTEXT_a4          EQU     60      ; Address register A4
CONTEXT_a5          EQU     64      ; Address register A5
; 68040 FPU registers
CONTEXT_fp0         EQU     68      ; FP register FP0 (12 bytes)
CONTEXT_fp1         EQU     80      ; FP register FP1 (12 bytes)
CONTEXT_fp2         EQU     92      ; FP register FP2 (12 bytes)
CONTEXT_fp3         EQU     104     ; FP register FP3 (12 bytes)
CONTEXT_fp4         EQU     116     ; FP register FP4 (12 bytes)
CONTEXT_fp5         EQU     128     ; FP register FP5 (12 bytes)
CONTEXT_fp6         EQU     140     ; FP register FP6 (12 bytes)
CONTEXT_fp7         EQU     152     ; FP register FP7 (12 bytes)
CONTEXT_fpsr        EQU     164     ; FPU status register
CONTEXT_fpcr        EQU     168     ; FPU control register
; 68040 MMU registers
CONTEXT_tc          EQU     172     ; Translation Control Register
CONTEXT_srp         EQU     176     ; Supervisor Root Pointer
CONTEXT_urp         EQU     180     ; User Root Pointer
CONTEXT_dtt0        EQU     184     ; Data Transparent Translation 0
CONTEXT_dtt1        EQU     188     ; Data Transparent Translation 1
CONTEXT_itt0        EQU     192     ; Instruction Transparent Translation 0
CONTEXT_itt1        EQU     196     ; Instruction Transparent Translation 1
CONTEXT_SIZE        EQU     200     ; Total context size

    SECTION TEXT

; External references
    XREF    _main_context

; void context_init_main(CONTEXT *main_context)
; Initialize main context by saving current register state
    XDEF    _context_init_main
_context_init_main:
    MOVEA.L 4(SP),A0            ; Load context pointer to A0
    
    ; Save integer registers
    MOVE.L  SP,CONTEXT_sp(A0)   ; Save stack pointer
    MOVE.L  A6,CONTEXT_fp(A0)   ; Save frame pointer
    MOVEM.L D0-D7/A0-A5,(CONTEXT_d0,A0) ; Save all data and address registers in one instruction

    ; Save FPU registers (using 68040 FMOVEM instruction)
    FMOVEM.X FP0-FP7,(CONTEXT_fp0,A0)  ; Save all FP registers
    FMOVE.L  FPSR,CONTEXT_fpsr(A0)     ; Save FP status register
    FMOVE.L  FPCR,CONTEXT_fpcr(A0)     ; Save FP control register
    
    ; Save MMU registers (privileged, would need to be in supervisor mode)
    ; These would normally be saved only when in supervisor mode
    ; and using MOVEC instructions for each register
    ; MOVEC TC,D0
    ; MOVE.L D0,CONTEXT_tc(A0)
    ; MOVEC SRP,D0
    ; MOVE.L D0,CONTEXT_srp(A0)
    ; etc.
    
    RTS

; void context_kill_switch(Context *restore_context)
; Switch to a new context without saving current one
    XDEF    _context_kill_switch
_context_kill_switch:
    MOVEA.L 4(SP),A0            ; Move context ptr to A0
    BRA     go_context          ; Jump to context loading code

; int context_switch(Process *to, Process *from)
; Save current context to "from" and switch to "to"
    XDEF    _context_switch
_context_switch:
    MOVE.L  8(SP),A1            ; A1 = save_context
    MOVE.L  (SP)+,CONTEXT_pc(A1) ; Save return address as PC
    MOVE.L  SP,CONTEXT_sp(A1)   ; Save stack pointer
    MOVE.L  A6,CONTEXT_fp(A1)   ; Save frame pointer
    
    ; Save all registers in one instruction (68040 optimization)
    MOVEM.L D0-D7/A0-A5,(CONTEXT_d0,A1) ; Save all data and address registers
    
    ; Save FPU registers (using 68040 FMOVEM instruction)
    FMOVEM.X FP0-FP7,(CONTEXT_fp0,A1)  ; Save all FP registers
    FMOVE.L  FPSR,CONTEXT_fpsr(A1)     ; Save FP status register
    FMOVE.L  FPCR,CONTEXT_fpcr(A1)     ; Save FP control register
    
    ; Save MMU registers if in supervisor mode (privileged)
    ; These would use MOVEC instructions for each register
    
    MOVEA.L 4(SP),A0            ; A0 = to_context

; Common code to load context from A0
go_context:
    ; 68040 cache instruction to flush caches before context switch
    CPUSHA  BC                  ; Push and invalidate both caches
    
    ; Restore MMU registers if in supervisor mode (privileged)
    ; These would use MOVEC instructions for each register
    
    ; Restore FPU registers (using 68040 FMOVEM instruction)
    FMOVEM.X (CONTEXT_fp0,A0),FP0-FP7  ; Restore all FP registers
    FMOVE.L  CONTEXT_fpsr(A0),FPSR     ; Restore FP status register
    FMOVE.L  CONTEXT_fpcr(A0),FPCR     ; Restore FP control register
    
    ; Restore integer registers
    MOVE.L  CONTEXT_fp(A0),A6   ; Restore frame pointer
    
    ; We need to save A0 temporarily because MOVEM will overwrite it
    LEA     CONTEXT_d0(A0),A1   ; Get address of register save area
    MOVEA.L A0,A2               ; Save A0 temporarily
    MOVEA.L CONTEXT_sp(A0),SP   ; Restore stack pointer
    MOVEM.L (A1),D0-D7/A0-A5    ; Restore all data and address registers
    
    ; Jump to the stored PC
    MOVE.L  CONTEXT_pc(A2),-(SP) ; Push saved PC as return address
    RTS                         ; Jump to new context

; int context_jump(Context *to)
; Jump to a new entry point within the same context
    XDEF    _context_jump
_context_jump:
    MOVEA.L 4(SP),A0            ; A0 = to_context
    MOVEA.L CONTEXT_sp(A0),SP   ; Restore stack pointer
    MOVEA.L CONTEXT_fp(A0),A6   ; Restore frame pointer
    MOVE.L  CONTEXT_pc(A0),-(SP) ; Push return address
    RTS                         ; Jump to new entry point

    END
[#9] Re: Konwersja asm x86 do 68k

@Artur Jarosik, post #1

Stary juz jestem, wiec moze cos zle kojarze. Ale w tych zrodlach to ASM chyba PC-towy (bo wyglada na 3 bajtowy) byl uzywany w zasadzie tylko do opisu struktury.
A nie do programowania.
Tak jakby napisac:

dc.w $0001, $0002


albo

Start1
 dc.l "FORM"
End1
 dc.w End1-Start1


Niby to ASM, ale da sie to zapisac, pewnie na rozne sposoby, bez uzycia ASM.
Jedynie jezeli to jest rzeczywiscie 3 bajtowy ASM to przy konwersji pewnie dobrze byloby zamienic 3 bajtowe wartosci na 4 bajtowe wartosci, wstawiajac 0 na poczatku.
Bo odczytywanie 4 bajtow jest szybsze niz 3 bajtow na 68k.

A np. cos takiego (https://github.com/SlasherX5/mk3reboot/blob/main/ASM/CHARS/INDIAN/MKINDA.PSI) wyglada na jakas grafike:

;CNOP 0, 4
WOLF20_IMG:
	DB 0BDH, 007H, 000H, 043H, 078H, 005H, 000H, 084H, 041H, 05EH, 001H, 0A0H, 021H, 014H, 041H, 000H
	DB 08CH, 040H, 0C4H, 015H, 0E0H, 018H, 002H, 0C1H, 084H, 008H, 041H, 080H, 018H, 040H, 081H, 008H
....



ktora byc moze sie konwertuje po prostu binarnie na

dc.b $BD,$07,$43,$78......


Albo na cos takiego, jesli to jakis dziwny endian zapisu jest.

dc.b $DB,$70,$34,$87......


Pewnie wystarczy konwerter tekstu z .PSI na .BIN napisac.
I zobaczyc czy to jest jakas 256 kolorowa grafika chunky.
[#10] Re: Konwersja asm x86 do 68k

@Artur Jarosik, post #2

Jak mawiał pewien prezydent: "[...] nie idźcie tą drogą!".
Bo za niedługo wielu z nas straci pracę przez tego demona ej-aj.
[#11] Re: Konwersja asm x86 do 68k

@bfgmatik, post #10

I tak ci co mają stracić pracę to ją stracą. Taka jest cena postępu. Nie inaczej było z mechanizacją, a potem robotyzacją przemysłu. I do tej pory zawsze udało się gdzieś tych pracowników upchnąć. Przesunąć w inny obszar. A jak będzie? Kto to wie. Gorzej, że wygląda na to, że mało kto się realnie zajmuje tym by na to się przygotować. A boimy się o górników...
[#12] Re: Konwersja asm x86 do 68k

@Don_Adan, post #9

Byłeś blisko, ale lekko sprostuję

"0BDH" to jest bajt $BD.

Skąd taki zapis? Na początku liczby szesnastkowej dodaje się zero, aby kompilator nie wziął samej wartości BDH jako nazwy zmiennej. Dlaczego na końcu dodaje się "H"? bo to wartość szesnastkowa.

Przykład:
MOV ah,0a0h ; asm x86

move.b #$a0,d0 ; asm 68k


Wiedzę zaczerpnąłem z książki "Tworzenie gier 2D i 3D w języku Turbo Pascal", gdzie jest osobny rozdział o asm x86. W takich sprawach nie ufam AI

Ostatnia aktualizacja: 08.04.2025 07:43:32 przez tukinem
1
[#13] Re: Konwersja asm x86 do 68k

@Artur Jarosik, post #5

BTW: ja ostatnio trochę bawiłem się ChatGPT O3-mini-high w kontekście assemblera m68060.
muszę przyznać że byłem bardzo pozytywnie zaskoczony wynikami jaki kod generował i jak podpowiadał optymalizacje zwłaszcza dla 060. po wklejaniu procedur umiał powiedzieć co robią, do czego służą i jak można je poprawić.

a wątek ciekawy. ciekaw jestem co z tego wyjdzie.
3
[#14] Re: Konwersja asm x86 do 68k

@Don_Adan, post #9

Czyli mozesz sobie przerobic taki pilk zrodlowy na cos takiego:

cnop 0,4.  ; uzywa sie jesli nastepne dane musza zaczynac sie od adresu podzielnego przez 4.
WOLF20_IMG
 dc.b $BD,$07,$00,$43,$78......


albo na cos takiego, mniej miejsca/pamieci zuzywa ( po przerobieniu na plik binarny)

cnop 0,4
WOLF20_IMG
 incbin ram:WOLF20_IMG



Wszystko, zalezy co jest bardziej uniwersalne dla kompilatora jakiego uzywasz.
[#15] Re: Konwersja asm x86 do 68k

@Don_Adan, post #14

No i widac, ze to jest program, ktory dzialal na sprzecie gdzie ilosc pamieci miala znaczenie, dlatego sa te cale overlaye i zamiana kontextu.
I byl w ten sposob robiony.
Pewnie dzialal na 4MB, max 8MB pamieci.
Teraz pewnie przerobia go na 128+MB pamieci, i wywala doczytywanie danych z dysku.
Jak dla mnie to Amigowa wersja powinna tez dzialac na 4, max 8 MB fast.
plus c2p dla AGA i ewentualnie RTG.
[#16] Re: Konwersja asm x86 do 68k

@Don_Adan, post #15

Na PC MK3 wymagał chyba 8 MB RAM. U mnie na 4 MB po intro wyskakiwały literki na trybie tekstowym i był błąd.

C2P jak C2P, ale dźwięk i muzykę byłoby też trzeba dograć odpowiednio do Pauli.
[#17] Re: Konwersja asm x86 do 68k

@tukinem, post #16

Na PC MK3 wymagał chyba 8 MB RAM. U mnie na 4 MB po intro wyskakiwały literki na trybie tekstowym i był błąd.


Tak, zgadza się. Natomiast np. mój znajomy sprytnie odpalał pow WIN95 w trybie MSDOS z pamięcią wirtualną mając 4MB
[#18] Re: Konwersja asm x86 do 68k

@tukinem, post #16

Te 4MB RAM to byl bodaj narzut samego Windowsa 95, czyli 4+4 MB w przypadku PC-ta z Windowsem.
Zreszta te oryginalne zrodla wygladaja jak adoptowane z PSX.
A Playstation mialo bodaj 2MB RAM + 512KB plus 1MB RAM VRAM.
Wiec 4 MB, max 8MB RAM, powinno wystarczyc, jesli dane beda doczytywane, a nie wczytywane od razu wszystkie do pamieci.
[#19] Re: Konwersja asm x86 do 68k

@Don_Adan, post #18

MK3 pod DOS wymagał 8MB:
[#20] Re: Konwersja asm x86 do 68k

@Jacques, post #19

Masz racje, czyli 12MB wersja Windows, a 8MB wersja DOS.

A czytajac to:

"Mortal Kombat 3 is a singleplayer and multiplayer side view fighting game in the Mortal Kombat series.

The DOS and Windows version are not the same. The Windows version is a direct port from the PlayStation version, it has loading between fights and it has loading times every time Shang Tsung morphs.The DOS version of the game stands out as the superior option overall due to its smoother experience with no loading times."

To wyglada na to ze, w wersji na Windows 95 gra potrzebowala jeszcze wiecej RAMu.
Czyli pewnie 6-8MB RAM-u zuzywal wtedy sam Windows.
2
[#21] Re: Konwersja asm x86 do 68k

@Don_Adan, post #20

No i tak jak pisałem, wersję DOS kumpel uruchomił pod Windows 95 na kompie z 4MB, korzystając z trybu MSDOS i pamięci wirtualnej (udając, ze komp ma 8+ MB). Choć pewnie doczytywania było sporo i spowolnień z tym związanych
1
[#22] Re: Konwersja asm x86 do 68k

@Jacques, post #21

Pomysł fajny, tylko, że Win95 na 4MB ramu to był ledwo klikalny, więc jeśli rzeczywiści sztuka (a jest to sztuka/wyczyn- doceniam) odpalenia wersji MS-DOS mu się powiodła to gra musiała permanentnie zaczytywać dane z VM i mielić dyskiem niemiłosiernie
[#23] Re: Konwersja asm x86 do 68k

@BULI, post #22

No musiała, nawet MK2 na 4MB na PC też mocno mielił
[#24] Re: Konwersja asm x86 do 68k

@Jacques, post #23

MK2 mi działał całkiem znośnie na 4 MB i 40 MHz, ale przy ładowaniu Kintaro był zawsze zwis. Wyświetlała się plansza, nazwy postaci i paski które już nie dały rady się napełnić na starcie może by pomogło przegrzebanie autoexec.bat lub config.sys ale byłem zbyt gówniarz wtedy na takie machloje
[#25] Re: Konwersja asm x86 do 68k

@tukinem, post #24

Przypomniałem sobie, że jakiś czas temu grałem w MK3 pod DosBoxem (WarpOs) na mojej Amidze 4000 i działało to bardzo ładnie, wersja pod DOSa była naprawdę szybka i w pełni grywalna ok, racja
[#26] Re: Konwersja asm x86 do 68k

@Artur Jarosik, post #2

Jezeli to jest jedyny kod x86 w tej grze to cos takiego jest raczej latwe do napisania w ASM 68k.
Problem wedlug mnie jest taki, ze to jest uzywane na PC do obslugi hunku typu Overlayed.
(tak mi sie przynajmniej wydaje)
Amiga tez cos takiego potrafi.

"Overlaid executables

The HUNK_OVERLAY type was intended to reduce the amount of RAM needed to run a program. Executables with an overlay structure have a root node which is in memory at all times, and the rest of the program is split into smaller modules which are loaded and unloaded automatically when needed.

The Overlay format works by adding little stubs to code so that when they branch into a sub-module, it calls an overlay manager, which loads the requisite module. Commodore defined a standard overlay manager so that C code could automatically have these stubs inserted, and also generate an overlay table, which the standard overlay manager knew how to read."

Tylko o ile mnie pamiec nie myli (info z EAB) to zaden wspolczesny kompilator generujacy kod Amigowy nie potrafi tych hunkow wygenerowac.
A jezeli mam racje to nie ma sensu podchodzic w ten sposob do robienia konwersji MK3.
A trzeba po prostu usunac hunki typu Overlayed z wersji PC-towej Win, byc moze uzywajac w tym celu wersji PC-towej DOS.
Wiec wedlug mnie sprobuj skompilowac zrodla MK3 na format Amigowego exeka.
A w miejsce kodu wstaw po prostu placeholdery

_context_init_main:
        dc.w $4afc ; illegal
        rts
_context_kill_switch:
         dc.w $4afc ; illegal
         rts
_context_switch:
        dc.w  $4afc ; illegal
        rts
_go_context
        dc.w $4afc ; illegal
        rts

_context_jump:
        dc.w $4afc ; illegal
        rts


A jezeli wspolczesne kompilatory Amigowe potrafia jednak tworzyc hunki typu Overlayed (w co mocno watpie) to napisanie takich 5 procedur powinno byc dosc proste.

Ale sprawdz najpierw czy kompilator wygeneruje Amigowy kod 68k, jezeli wstawisz tam placeholdery.
2
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem