FreeBE/start.s

133 lines
4.2 KiB
ArmAsm

/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* Startup and relocation code.
*
* See readme.txt for copyright information.
*/
.data
.globl _hdraddr,_reladdr
_hdraddr: .long 0
_reladdr: .long 0
.text
.globl StartDriver, PlugAndPlayInit, OemExt
/* helper for relocating the driver */
#define DO_RELOCATION() \
; \
movl %ebx, _reladdr(%ebx) /* store relocations */ ; \
movl %edx, _hdraddr(%ebx) ; \
; \
movl 876(%edx), %ecx /* get relocation count */ ; \
jecxz 1f ; \
; \
pushl %esi /* get relocation data */ ; \
leal 880(%edx), %esi ; \
cld ; \
; \
0: ; \
lodsl ; \
addl %ebx, (%ebx, %eax) ; \
loop 0b ; \
; \
popl %esi /* relocation is complete */
/* Entry point for the standard VBE/AF interface. When used with our
* extension mechanism, the driver will already have been relocated by
* the OemExt function, so this routine must detect that and do the
* right thing in either case. After sorting out the relocation, it
* chains to a C function called SetupDriver.
*/
PlugAndPlayInit:
movl %ebx, %edx /* save base address in %edx */
movl 576(%ebx), %eax /* retrieve our actual address */
subl $PlugAndPlayInit, %eax /* subtract the linker address */
addl %eax, %ebx /* add to our base address */
cmpl $0, _reladdr(%ebx) /* quit if we are already relocated */
jne 1f
DO_RELOCATION() /* relocate ourselves */
1:
pushl %edx /* do high-level initialization */
call _SetupDriver
popl %edx
ret
/* Driver init function. This is just a wrapper for the C routine called
* InitDriver, with a safety check to bottle out if we are being used
* by a VBE/AF 1.0 program (in that case, we won't have been relocated yet
* so we must give up in disgust).
*/
StartDriver:
pushl %ebx /* check that we have been relocated */
movl 412(%ebx), %eax
subl $StartDriver, %eax
addl %eax, %ebx
cmpl $0, _reladdr(%ebx)
je 0f
call _InitDriver /* ok, this program is using VBE/AF 2.0 */
popl %ebx
ret
0:
movl $-1, %eax /* argh, trying to use VBE/AF 1.0! */
popl %ebx
ret
/* Extension function for the FreeBE/AF enhancements. This will be the
* very first thing called by a FreeBE/AF aware application, and must
* relocate the driver in response. On subsequent calls it will just
* chain to the C function called FreeBEX.
*/
OemExt:
cmpl $0x494E4954, 8(%esp) /* check for FAFEXT_INIT parameter */
jne 2f
pushl %ebx
movl 8(%esp), %ebx /* read driver address from the stack */
movl %ebx, %edx /* save base address in %edx */
movl 580(%ebx), %eax /* retrieve our actual address */
subl $OemExt, %eax /* subtract the linker address */
addl %eax, %ebx /* add to our base address */
cmpl $0, _reladdr(%ebx) /* quit if we are already relocated */
jne 1f
addl %edx, 580(%edx) /* relocate the OemExt pointer */
DO_RELOCATION() /* relocate the rest of the driver */
1:
popl %ebx
movl $0x45583031, %eax /* return FAFEXT_MAGIC1 */
ret
2:
jmp _FreeBEX /* let the driver handle this request */