home *** CD-ROM | disk | FTP | other *** search
- ;******************************************************************************
- ;* 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.2 1993/12/23 04:44:45 cassidy 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
-