📄 dostip.asm
字号:
;******************************************************************************;* 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 .CODEELSE;; 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_firstbytermcode_firstbyte label bytermcode endsrmdata segment dword public use16rmdata endspmdata segment dword public use32pmdata endspmcode segment byte public use32pmcode endsdgroup group rmdata,pmdatarmcode segment ; _UDIASMDisconnect will be in rmcode segmentENDIF 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, dsIFNDEF DOS386 jmp _UDICDisconnect ; real mode, just jump to the C routineELSE jmp rm_UDIDisconnect ; DOS386, jump to the real mode stubENDIF_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, dsIFNDEF DOS386 jmp _UDICConnect ; real mode, just jump to the C routineELSE jmp rm_UDIConnect ; DOS386, jump to the real mode stubENDIFIFDEF DOS386 ; Note: the rest of this file is just DOS386 supportrmcode 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 codecode_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 TIPNameTIPName DB 256 DUP(?) public TIPVecRecTIPVecRec 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 belowTIPVecRecEnd LABEL BYTErmdata 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 segmentdos386glue_table LABEL DWORD ; so we can reference it later in the udi_table macro ; the entries get added by the udi_table macro belowpmdata 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,valrmcode segment public rm_&UDIProcNamerm_&UDIProcName LABEL NEAR mov bl, val ;; bl will indicate which UDI Proc was called jmp short rm_commonrmcode endsrmdata 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 ENDIFrmdata endspmdata segment EXTRN d386_&UDIProcName:NEAR ORG dos386glue_table + 4*val ;; this builds the jump table that pmstub uses DD d386_&UDIProcNamepmdata 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,26rmcode 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 DFErm_common ENDPrmcode ends pmcode segmentpmstub 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 segmentconv_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_tablechk_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_stackno_stack: mov eax, 25 ; IPC Limitation error rettake_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 indicatorno_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 retpmstub endp public GetCSGetCS PROC NEAR mov ax, cs retGetCS ENDP public GetDSGetDS PROC NEAR mov ax, ds retGetDS 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 ENDPpmcode endsrmdata segment;; Symbol marking end of real mode code & data,; used at link time to specify the real mode; code & data size; public end_realend_real label bytermdata endsENDIF ; end of DOS386 conditional code END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -