; This file contains all assembler functions
; Copyright 2000 Jarno Paananen and Jurjen Katsman

BITS 32

%ifdef M_TARGET_ELF

  %macro EXTERNSYMBOL 1
    EXTERN %1
  %endmacro

  %macro GLOBALLABEL 1
    GLOBAL %1
    %1:
  %endmacro  

%else

  %macro EXTERNSYMBOL 1
    EXTERN _%1
    %define %1 _%1
  %endmacro

  %macro GLOBALLABEL 1
    GLOBAL _%1
    _%1:
    %define %1 _%1
  %endmacro    


%endif


EXTERNSYMBOL temp1
EXTERNSYMBOL temp2
EXTERNSYMBOL temp3
EXTERNSYMBOL temp4
EXTERNSYMBOL tmpptr1
EXTERNSYMBOL saveFS
EXTERNSYMBOL saveGS
EXTERNSYMBOL saveESP

SECTION .text

EXTERNSYMBOL farbank

; this is used for all "do nothing" trampolines
GLOBALLABEL basictramp
        pushad
        push fs
        push gs
        mov [temp1], edx
        mov [temp2], esp
        mov fs, [saveFS]
        mov gs, [saveGS]
        mov esp, [saveESP]

        call farbank

        mov esp, [temp2]
        pop gs
        pop fs
        popad
        retf

EXTERNSYMBOL farshowp

GLOBALLABEL farshowptramp
        pushad
        push fs
        push gs
        mov [temp1], edx
        mov [temp2], esp
        mov fs, [saveFS]
        mov gs, [saveGS]
        mov esp, [saveESP]

        call farshowp

        mov esp, [temp2]
        pop gs
        pop fs
        popad
        retf

EXTERNSYMBOL farmalloc

GLOBALLABEL farmalloctramp
        pushad
        push fs
        push gs
        mov [temp1], edx
        mov [temp2], esp
        mov fs, [saveFS]
        mov gs, [saveGS]
        mov esp, [saveESP]

        call farmalloc

        mov esp, [temp2]
        pop gs
        pop fs
        popad

        xor eax, eax
        mov edx, [tmpptr1]
        clc
        retf


EXTERNSYMBOL fardoint

GLOBALLABEL fardointtramp
        pushad
        push fs
        push gs
        mov [temp1], eax
        mov [temp2], esp
        mov [temp3], esi
        mov [temp4], ecx
        mov fs, [saveFS]
        mov gs, [saveGS]
        mov esp, [saveESP]

        call fardoint

        mov esp, [temp2]
        pop gs
        pop fs
        popad

        mov eax, [temp1]
        retf

EXTERNSYMBOL quitaddress
GLOBALLABEL jumptramp
        jmp [quitaddress]

GLOBALLABEL savesegs
        mov [saveFS], fs
        mov [saveGS], gs
        ret


EXTERNSYMBOL relocofs
EXTERNSYMBOL exeofs
EXTERNSYMBOL fixupsize
GLOBALLABEL reloc
        pushad
        mov esi,[relocofs]
        mov edi,[exeofs]
        mov edx,[fixupsize]
        dec edx
.Relocloop:
        xor ebx,ebx
.Bla:
        shl ebx,7
        mov al,[esi]
        inc esi
        dec edx
        rol al,4
        movzx ecx,al
        and ecx,127
        add ebx,ecx
        test al,128
        jnz .Bla
        mov eax,[exeofs]
        add edi,ebx
        or edx,edx
        js .addressreloc
        cmp byte [esi],0
        jnz .addressreloc
        mov ax,ds
        add word [edi],ax
        inc esi
        dec edx
        jmp .next
.addressreloc:
        add [edi],eax
.next:           
        or edx,edx
        jns .Relocloop
        popad
        ret

EXTERNSYMBOL startip
EXTERNSYMBOL runexe
EXTERNSYMBOL startsp
EXTERNSYMBOL herzcount
EXTERNSYMBOL mustime
EXTERNSYMBOL balmodeinfo
EXTERNSYMBOL exerunning
GLOBALLABEL startdemo
        pushad
        mov eax,esp
        mov [saveESP],eax
        mov eax,[startip]
        mov [runexe],eax       
        mov ebx,[startsp]
        mov esp,ebx
                
        mov bx,cs
        mov eax, basictramp
        push eax
        push bx
        mov eax, basictramp
        push eax
        push bx
        mov eax, farshowptramp
        push eax
        push bx
        mov eax, basictramp
        push eax
        push bx
        mov eax, basictramp
        push eax
        push bx

        mov eax, herzcount
        push eax
        mov eax, mustime
        push eax

        mov eax, fardointtramp
        push eax
        push bx
        mov eax, farmalloctramp
        push eax
        push bx

        mov esi, balmodeinfo
        mov bx,ds
        mov es,bx
        mov fs,bx
        mov gs,bx

        xor ebx,ebx
        mov bx,cs
        mov [runexe+4],ebx
                
        xor eax, eax
        xor edi, edi
        mov dword[quitaddress], retadr
        mov dword[exerunning],1
        call far [runexe]
retadr:         
        mov esp,[saveESP]
        popad
        mov fs,[saveFS]
        mov gs,[saveGS]
        mov dword[exerunning],0
        ret
