1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- /*
- * Far call, absolute indirect.
- * The argument is the offset.
- * We use a global structure for the jump params,
- * so this is *not* reentrant or thread safe.
- */
- #include "mem.h"
- #define SSOVERRIDE BYTE $0x36
- #define CSOVERRIDE BYTE $0x2E
- #define RETF BYTE $0xCB
- GLOBL apmjumpstruct+0(SB), $8
- TEXT fortytwo(SB), $0
- MOVL $42, AX
- RETF
- TEXT getcs(SB), $0
- PUSHL CS
- POPL AX
- RET
- TEXT apmfarcall(SB), $0
- /*
- * We call push and pop ourselves.
- * As soon as we do the first push or pop,
- * we can't use FP anymore.
- */
- MOVL off+4(FP), BX
- MOVL seg+0(FP), CX
- MOVL BX, apmjumpstruct+0(SB)
- MOVL CX, apmjumpstruct+4(SB)
- /* load necessary registers from Ureg */
- MOVL ureg+8(FP), DI
- MOVL 28(DI), AX
- MOVL 16(DI), BX
- MOVL 24(DI), CX
- MOVL 20(DI), DX
- /* save registers, segments */
- PUSHL DS
- PUSHL ES
- PUSHL FS
- PUSHL GS
- PUSHL BP
- PUSHL DI
- /*
- * paranoia: zero the segments, since it's the
- * BIOS's responsibility to initialize them.
- * (trick picked up from Linux driver).
- PUSHL DX
- XORL DX, DX
- PUSHL DX
- POPL DS
- PUSHL DX
- POPL ES
- PUSHL DX
- POPL FS
- PUSHL DX
- POPL GS
- POPL DX
- */
- PUSHL $APMDSEG
- POPL DS
- /*
- * The actual call.
- */
- CSOVERRIDE; BYTE $0xFF; BYTE $0x1D
- LONG $apmjumpstruct+0(SB)
- /* restore segments, registers */
- POPL DI
- POPL BP
- POPL GS
- POPL FS
- POPL ES
- POPL DS
- PUSHFL
- POPL 64(DI)
- /* store interesting registers back in Ureg */
- MOVL AX, 28(DI)
- MOVL BX, 16(DI)
- MOVL CX, 24(DI)
- MOVL DX, 20(DI)
- MOVL SI, 4(DI)
- PUSHFL
- POPL AX
- ANDL $1, AX /* carry flag */
- RET
|