@tukinem, post #21
@Artur Jarosik, post #33
Ktoś chętny przepisania na C lub asm 68k ?
Tak, mogę pomóc w przetłumaczeniu kodu assemblerowego z x86 na 68k, choć wymaga to trochę pracy, bo te architektury różnią się znacząco – x86 (np. Intel) używa modelu CISC, a 68k (Motorola) jest bardziej RISC-podobny. Rejestry, sposób adresowania pamięci i instrukcje są inne, więc nie zawsze jest to tłumaczenie 1:1, a bardziej adaptacja logiki programu.
Jeśli masz konkretny kod w asm x86, pokaż mi go, a postaram się przełożyć go na asm 68k, wyjaśniając przy tym różnice i dostosowując go do tej architektury. Na przykład:
Rejestry x86 (EAX, EBX, ECX) nie mają bezpośrednich odpowiedników w 68k, ale mogę użyć D0-D7 (dane) lub A0-A7 (adresy).
Instrukcje jak MOV w x86 zamienię na MOVE w 68k, uwzględniając składnię i adresowanie.
Podaj mi fragment kodu, a zaczniemy!
@Don_Adan, post #37
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; 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@c64portal, post #28
na A4000/060 100MHz pokazuje 30FPS ale...
nic nie mogę zrobić to cały czas mi wchodzi i wychodzi z menu.
efekt jest taki jak by jakiś klawisz był wciśnięty cały czas, albo odczytywało stan wciśnięcia jakiegoś klawisza. jak przytrzymam ESC to po wejściu do gry nie wychodzi do menu, no ale muszę trzymać ESC. coś jest nie tak
@Artur Jarosik, post #40
CONTEXT_ip equ 0 ; Instruction pointer offset
CONTEXT_sp equ 4 ; Stack pointer offset (A7 w 68k)
CONTEXT_fp equ 8 ; Frame pointer offset (A6 zamiast EBP)
CONTEXT_d2 equ 12 ; Odpowiednik EBX
CONTEXT_d3 equ 16 ; Odpowiednik ECX
CONTEXT_a4 equ 20 ; Odpowiednik ESI
CONTEXT_a5 equ 24 ; Odpowiednik EDI
SECTION .text
_start_:
EXTERN _main_context
; void context_init_main(CONTEXT *main_context)
_context_init_main:
move.l 4(a7), a0 ; A0 = main_context (pierwszy argument ze stosu)
move.l a7, CONTEXT_sp(a0) ; Zapisz aktualny stos (A7)
move.l a6, CONTEXT_fp(a0) ; Zapisz frame pointer (A6 zamiast EBP)
move.l d2, CONTEXT_d2(a0) ; Zapisz D2 (odpowiednik EBX)
move.l d3, CONTEXT_d3(a0) ; Zapisz D3 (odpowiednik ECX)
move.l a4, CONTEXT_a4(a0) ; Zapisz A4 (odpowiednik ESI)
move.l a5, CONTEXT_a5(a0) ; Zapisz A5 (odpowiednik EDI)
rts ; Powrót
; void context_kill_switch(Context *restore_context)
_context_kill_switch:
move.l 4(a7), a0 ; A0 = restore_context
bra go_context ; Skok do wspólnej logiki przywracania
; int context_switch(Process *to, Process *from)
_context_switch:
move.l 8(a7), a0 ; A0 = save_context (drugi argument)
move.l (a7)+, CONTEXT_ip(a0) ; Zdejmij adres powrotu i zapisz jako IP
move.l a7, CONTEXT_sp(a0) ; Zapisz aktualny stos
move.l a6, CONTEXT_fp(a0) ; Zapisz frame pointer
move.l d2, CONTEXT_d2(a0) ; Zapisz D2
move.l d3, CONTEXT_d3(a0) ; Zapisz D3
move.l a4, CONTEXT_a4(a0) ; Zapisz A4
move.l a5, CONTEXT_a5(a0) ; Zapisz A5
move.l (a7), a0 ; A0 = to_context (pierwszy argument)
go_context:
move.l CONTEXT_sp(a0), a7 ; Przywróć stos
move.l CONTEXT_fp(a0), a6 ; Przywróć frame pointer
move.l CONTEXT_d2(a0), d2 ; Przywróć D2
move.l CONTEXT_d3(a0), d3 ; Przywróć D3
move.l CONTEXT_a4(a0), a4 ; Przywróć A4
move.l CONTEXT_a5(a0), a5 ; Przywróć A5
move.l CONTEXT_ip(a0), a1 ; Załaduj nowy IP do A1
jmp (a1) ; Skok do nowego kontekstu
; int context_jump(Context *to)
_context_jump:
move.l 4(a7), a0 ; A0 = to_context
move.l CONTEXT_sp(a0), a7 ; Przywróć stos
move.l CONTEXT_fp(a0), a6 ; Przywróć frame pointer
move.l CONTEXT_ip(a0), a1 ; Załaduj nowy IP
jmp (a1) ; Skok do nowego punktu wejścia
END @BULI, post #42
Gra korzysta z lowlevel.library i jeśli nie ma podpiętego joysticka/pada może generować takie problemy jak u Ciebie
Spróbuj podpiąć coś do portu joysticka