URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [trunk/] [gdb-5.0/] [utils/] [amd-udi/] [udi/] [dostip.asm] - Rev 1765
Compare with Previous | Blame | View Log
;******************************************************************************
;* Copyright 1991 Advanced Micro Devices, Inc.
;*
;* This software is the property of Advanced Micro Devices, Inc (AMD) which
;* specifically grants the user the right to modify, use and distribute this
;* software provided this notice is not removed or altered. All other rights
;* are reserved by AMD.
;*
;* AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS
;* SOFTWARE. IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL
;* DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR
;* USE OF THIS SOFTWARE.
;*
;* Comments about this software should be directed to udi@amd.com. If access
;* to electronic mail isn't available, send mail to:
;*
;* Advanced Micro Devices, Inc.
;* 29K Support Products
;* Mail Stop 573
;* 5900 E. Ben White Blvd.
;* Austin, TX 78741
;* 800-292-9263
;*****************************************************************************
;* $Id: dostip.asm,v 1.1.1.1 2001-05-18 11:27:55 markom Exp $
;* $Id: @(#)dostip.asm 2.7, AMD
;******************************************************************************
;*/
IFNDEF DOS386
DOSSEG
.MODEL LARGE
PUBLIC _UDIASMConnect
PUBLIC _UDIASMDisconnect
EXTRN _UDICDisconnect:FAR
EXTRN _UDICConnect:FAR
.CODE
ELSE
;
; Segment ordering and attributes for DOS386. We make sure the
; real mode code and data comes first. The real and
; prot mode data are together so they can be grouped.
;
rmcode segment byte public use16
; We need to mark the first byte in rmcode to figure the real segment value
public rmcode_firstbyte
rmcode_firstbyte label byte
rmcode ends
rmdata segment dword public use16
rmdata ends
pmdata segment dword public use32
pmdata ends
pmcode segment byte public use32
pmcode ends
dgroup group rmdata,pmdata
rmcode segment ; _UDIASMDisconnect will be in rmcode segment
ENDIF
INCLUDE udidos.ah ; TermStruct Definitions from DFE
_UDIASMDisconnect LABEL FAR
;
; Save off important stuff in structure whose address
; is given as third parameter to this function.
mov bx, sp
les bx, ss:8[bx]
mov es:[bx].sss, ss
mov es:[bx].ssp, sp
mov es:[bx].ssi, si
mov es:[bx].sdi, di
mov es:[bx].sbp, bp
mov es:[bx].sds, ds
IFNDEF DOS386
jmp _UDICDisconnect ; real mode, just jump to the C routine
ELSE
jmp rm_UDIDisconnect ; DOS386, jump to the real mode stub
ENDIF
_UDIASMConnect LABEL FAR
;
; Save off important stuff in structure whose address
; is given as third parameter to this function.
mov bx, sp
les bx, ss:12[bx]
mov es:[bx].sss, ss
mov es:[bx].ssp, sp
mov es:[bx].ssi, si
mov es:[bx].sdi, di
mov es:[bx].sbp, bp
mov es:[bx].sds, ds
IFNDEF DOS386
jmp _UDICConnect ; real mode, just jump to the C routine
ELSE
jmp rm_UDIConnect ; DOS386, jump to the real mode stub
ENDIF
IFDEF DOS386
; Note: the rest of this file is just DOS386 support
rmcode ends
;
; Data that needs to be accessed in both real
; mode and protected mode
;
rmdata segment
public code_selector, data_selector, call_prot
public segregblock
; these get filled in by protected mode startup code
code_selector DW ?
data_selector DW ?
call_prot DD ?
segregblock DW ? ; ds value ; seg reg block filled in at startup time
DW ? ; es value
DW ? ; fs value
DW ? ; gs value
public TIPName
TIPName DB 256 DUP(?)
public TIPVecRec
TIPVecRec DB 0,0,0,0 ; will get filled in by main
DD 0 ; next ptr
DD 0 ; prev ptr
DD TIPName ; exeName
; the other entries get added by the udi_table macro below
TIPVecRecEnd LABEL BYTE
rmdata ends
;
; Data that is only accessed in prot mode
;
extrn conventional_memory:DWORD ; set up by dx_map_physical
extrn stack_table: DWORD ; set up by C-level code.
pmdata segment
dos386glue_table LABEL DWORD ; so we can reference it later in the udi_table macro
; the entries get added by the udi_table macro below
pmdata ends
;; The udi_table macro does three things
;; 1) generates real mode entry point for each UDI function
;; This code just sets an index in bl and jumps to rm_common
;; 2) adds an entry into the TIPVecRec to point to the above real mode entry point
;; 3) adds an entry into the dos386glue_table table which is used by the prot.mode stub
;; to call the actual C glue routine.
udi_table MACRO UDIProcName,val
rmcode segment
public rm_&UDIProcName
rm_&UDIProcName LABEL NEAR
mov bl, val ;; bl will indicate which UDI Proc was called
jmp short rm_common
rmcode ends
rmdata segment
ORG TIPVecRec + 16 + 4*val ;; Entry in TIPVecRec (+16 for first 4 fields)
IF val EQ 0
DD _UDIASMConnect ;; special case for Connect
ELSE
IF val EQ 1
DD _UDIASMDisconnect ;; special case for Disconnect
ELSE
DD rm_&UDIProcName ;; normal entry is rm_ stub
ENDIF
ENDIF
rmdata ends
pmdata segment
EXTRN d386_&UDIProcName:NEAR
ORG dos386glue_table + 4*val ;; this builds the jump table that pmstub uses
DD d386_&UDIProcName
pmdata ends
ENDM
udi_table UDIConnect,0
udi_table UDIDisconnect,1
udi_table UDISetCurrentConnection,2
udi_table UDICapabilities,3
udi_table UDIGetErrorMsg,4
udi_table UDIGetTargetConfig,5
udi_table UDICreateProcess,6
udi_table UDISetCurrentProcess,7
udi_table UDIDestroyProcess,8
udi_table UDIInitializeProcess,9
udi_table UDIRead,10
udi_table UDIWrite,11
udi_table UDICopy,12
udi_table UDIExecute,13
udi_table UDIStep,14
udi_table UDIStop,15
udi_table UDIWait,16
udi_table UDISetBreakpoint,17
udi_table UDIQueryBreakpoint,18
udi_table UDIClearBreakpoint,19
udi_table UDIGetStdout,20
udi_table UDIGetStderr,21
udi_table UDIPutStdin,22
udi_table UDIStdinMode,23
udi_table UDIPutTrans,24
udi_table UDIGetTrans,25
udi_table UDITransMode,26
rmcode segment
ASSUME nothing, CS:rmcode ; all we know is that CS=rmcode
; Common real mode stub code
; bl is an index indicating which UDI function was called
; we need to switch to protected mode (ebx will be passed thru unchanged)
rm_common PROC FAR ; UDI always called as far (real mode)
push ds ; save ds
push bp ; and save bp
push si ; and si, di
push di
; note: if anything else gets pushed here, you must
; change the MSCPARAMS macro in dos386c.c
push cs
pop ds ; set ds = cs
ASSUME ds:dgroup
; to switch to protected mode, we push a dword ptr to a block which
; contains the protected mode segment registers to use
; and we push the 48-bit protected address of pmstub
; then we call the call_prot routine which was returned by dx_rmlink_get
push cs ; segment of seg reg block
lea ax, segregblock
push ax ; offset of seg reg block
push code_selector
lea eax, pmstub
push eax
call call_prot
add sp, 10 ; unpop all things we pushed
; ax return code from prot mode passed thru
pop di ; unpop di,si saved earlier
pop si
pop bp ; unpop the BP we saved earlier
pop ds ; unpop the DS we saved earlier
ret ; will do a FAR (real mode) ret to DFE
rm_common ENDP
rmcode ends
pmcode segment
pmstub proc far
; at this point ss:sp -> far return (DF) back to dos-extender
; sp+6 a word of 0
; sp+8 the pushed DS (of rmstub)
; sp+10 parameters
; we pop the far return and save it away
; then we call the real application procedure (the params still on stack)
ASSUME CS:pmcode, DS:dgroup
; first let's switch ss:esp so that ss = ds
; (it will still point to the same physical memory location)
; (we'll save the old ss:esp on the stack in case they're needed)
mov dx, ss
mov ecx, esp
; at this point, ecx contains the physical 32-bit address of sp
; (selector 60h's offset mapped directly to 1meg physical memory)
mov eax, conventional_memory
cmp eax, 0 ; if conventional memory not mapped take other path
je short conv_mem_unmapped
; This is the code that is not DPMI compatible
; we add the ofst of beggining of conventional memory to esp
; to make it SS_DATA relative and then use data_selector as the SS
; thus no stack switch is necessary, we just remap the old stack
add eax, ecx ; this adds esp to conventional_memory
mov ss, data_selector
mov esp, eax
jmp short got_ss_sp
; now ss:esp points to same place as before but using different segment
conv_mem_unmapped:
; This code is DPMI compatible
; we actually switch to a new stack that is in the TIPs DS
; the number and size of these stacks was allocated at startup time.
lea eax, stack_table
chk_stack:
cmp dword ptr [eax], 0
je short no_stack ; stack pointer of 0 means end of table
mov esi, dword ptr [eax] ; get stack pointer
cmp dword ptr [esi+4], 0 ; is it marked free?
je short take_stack
add eax, 4 ; to next stack entry in table
jmp chk_stack
no_stack:
mov eax, 25 ; IPC Limitation error
ret
take_stack:
mov dword ptr [esi+4], 0ffffffffh ; mark stack in use
mov ss, data_selector
mov esp, esi ; get stack pointer from table
; now we have ss = ds, so we can go to C level.
got_ss_sp:
; push the old ss:esp on the stack
push edx ; old ss (need to push as full 32-bit for C convention)
push ecx ; old esp
; bl still contains the UDIProcedure Index (which was set up by the rm stub)
; use this to get to the correct dos386glue_table routine
xor bh, bh
shl bx,1 ; *4 for indexing into DD array
shl bx,1
call dos386glue_table[bx]
; on return, we just need to restore the old ss:esp
pop ecx
pop edx
cmp conventional_memory, 0 ; if we had switched stacks
jne short no_stack_clear
mov dword ptr [esp+4], 0 ; clear the stack in use indicator
no_stack_clear:
; this code is identical whether we switched stacks or not
; we just restore the old ss:sp and return
mov ss, dx
mov esp, ecx
; the stack should look as it did when we entered
; so we just do a far ret
ret
pmstub endp
public GetCS
GetCS PROC NEAR
mov ax, cs
ret
GetCS ENDP
public GetDS
GetDS PROC NEAR
mov ax, ds
ret
GetDS ENDP
public _exp_return
extrn _top:dword
_exp_return PROC FAR
; set the stack pointer back to its initial state as left by dfe
; (leave the ss unchanged)
; then do a far ret which will get us back to the dfe.
; (which will then restore its own stack).
mov ebp, esp
mov eax, [ebp+4] ; errcode
mov ecx, _top
add ecx, 2
mov esp, ecx
ret
_exp_return ENDP
pmcode ends
rmdata segment
;
; Symbol marking end of real mode code & data,
; used at link time to specify the real mode
; code & data size
;
public end_real
end_real label byte
rmdata ends
ENDIF ; end of DOS386 conditional code
END