home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l360 / 2.ddi / MINITP.@SM / MINITP.ASM
Encoding:
Assembly Source File  |  1991-04-08  |  7.8 KB  |  341 lines

  1.     name    MINITP
  2.     title    MINITP - Microsoft PASCAL Initialization
  3.     subttl    Copyright (C) Micro Focus Ltd 1987
  4.  
  5. ; The only difference between this and the module MINITC is that
  6. ; we swap stacks at the start of the MINITP routine. This is because
  7. ; the PASCAL compiler does not allow the generation of code for split
  8. ; DATA and STACK segments. This means that we must use a STACK within
  9. ; DGROUP. This is of fixed size 8K.
  10.  
  11.     public    __NCLINKM    ; these are routines called from LCOBOL
  12.     public    __NCLINKI    ; from strategic places such as
  13.     public    __NCLINKX    ; exit from a program, startup, closedown
  14.     public    __NCLINKXS    ; etc.
  15.     public    __NCLINKS
  16.     public    __NCLINK
  17.     public    __astart        
  18.     public    _main        ; dummy routine to satisfy ref in LLIBC.LIB
  19.  
  20. ?DF=        1            ; this is special for c startup
  21. ?PLM = 0
  22. memL = 1
  23.  
  24. ; LCOBOL library equates
  25.  
  26. cdataseg    equ    0f8h
  27. bpregz        equ    0a0h
  28. pgdata        equ    68h
  29.  
  30. .xlist
  31.     include    cmacros.inc
  32.     include    msdos.inc
  33.     include    brkctl.inc
  34. .list
  35.     extrn    __cinit:far
  36.     extrn    _exit:far
  37.     extrn    __exit:far
  38.  
  39. ; This module provides an interface for calling Microsoft objects.
  40. ; Link your program as follows
  41. ;    LINK COBOL_objects+MINITP+PASCAL_objects,,,LCOBOL+PASCAL_libraries/m;
  42.  
  43.     page
  44. ;===========================================================================
  45. ;
  46. ;    Segment definitions
  47. ;
  48. ;    The segment order is essentially the same as in XENIX.
  49. ;
  50. ;===========================================================================
  51.  
  52. DOSSEG
  53.  
  54. createSeg    _TEXT,    code,    byte,    public, CODE,    <>
  55. createSeg    C_ETEXT,etext,    byte,    public, ENDCODE,<>
  56.  
  57. createSeg    _DATA,    data,    word,    public, DATA,    DGROUP
  58. createSeg    BSS,    data,    word,    public, BSS,    DGROUP
  59. createSeg    STACK,    stack,    para,    stack,    STACK,    DGROUP
  60.  
  61. defGrp    DGROUP            ; define DGROUP
  62.  
  63.  
  64. ; We must here set up a temporary stack since it is impossible to tell
  65. ; the PASCAL compiler to allocate separate data and stack segments
  66.  
  67. _DATA    segment word public 'DATA'
  68.  
  69. tempstk    db    8192 dup (0)    ; 8k temporary stack
  70.  
  71. _DATA    ends
  72.  
  73. page
  74.  
  75. public    __acrtused        ; trick to force in startup
  76.     __acrtused = 9876h    ; funny value not easily matched in SYMDEB
  77.  
  78.  
  79. _DATA    segment
  80.  
  81. extrn    _edata:byte        ; end of data (start of bss)
  82. extrn    _end:byte
  83. extrn    STKHQQ:word        ; stack high water mark
  84.  
  85. externW _psp            ; psp:0 (paragraph #)
  86. externW __argc
  87. externDP __argv
  88. externDP environ
  89.  
  90. ;    these are used by DOS C memory management (not used in Windows)
  91.  
  92. globalW _asizds,0            ; DS size (in bytes)
  93. globalW _atopsp,0            ; top of stack (heap bottom)
  94.  
  95. labelW    <PUBLIC,_abrktb>        ; segment table for brkctl
  96.     dw    ?
  97.     dw    DGROUP
  98.     db    (MAXSEG-1) * (size segrec) dup (?)
  99.  
  100. labelW    <PUBLIC,_abrktbe>
  101. globalW _abrkp,<offset DGROUP:_abrktb>
  102.  
  103. _ENV    dd    0
  104. _ENVC    dw    0
  105. _ESIZE    dw    0
  106.  
  107. tmpstk    dw    100 dup (0)        ; temporary stack for calling __cinit
  108. endstk    db    ?            ; as need ss=ds for this routine
  109.  
  110. MEMERR    DB    "Insufficient memory",0DH,0AH,"$"
  111.  
  112. _DATA    ends
  113.  
  114. sBegin    code
  115.     assume    cs:_TEXT,ds:DGROUP,es:DGROUP
  116.  
  117. oldsp        dw    0
  118. oldss        dw    0
  119.  
  120. ; The following routine is taken partly from the file CRT0.ASM provided
  121. ; with the MSC C product and does necessary initialization
  122. ; for Microsoft C objects. It will only handle 'L' model objects
  123. ; set up with ss not = ds (i.e. compiled with /Awlf).
  124.  
  125. ; Entry: es=cobol global data segment
  126.  
  127. MINITP    proc    far            ; Initialize msc C
  128.  
  129.     ; This code assumes that COBOL is the main program
  130.     ; since it only copies one COBOL stack frame to the new stack
  131.     ; FIX when PASCAL allows split Stack and DATA segments
  132.     cli                ; change over stacks
  133.     mov    dx,es            ; save CBLRUDAT pointer
  134.     mov    bx,bp            ; calculate diff betw sp and bp in bx
  135.     sub    bx,sp
  136.     mov    ax,ss
  137.     mov    ds,ax            ; ds = old stack segment
  138.     mov    ax,DGROUP
  139.     mov    es,ax            ; es = DGROUP
  140.     mov    ss,ax            ; ss = DGROUP
  141.     mov    si,sp            ; si = source stack pointer
  142.     mov    cx,bpregz+pgdata+1eh    ; stack fudge size to copy
  143.     mov    di,8192
  144.     sub    di,cx            ; di = start of stack
  145.     mov    sp,di            ; set up sp to be new stack pointer
  146.     mov    bp,di
  147.     add    bp,bx            ; bp = new stack frame pointer
  148.    rep  movsb                ; copy old stack to new stack
  149.     mov    es,dx            ; restore CBLRUDAT pointer
  150.     sti
  151.  
  152.     mov    ax,DGROUP        ; ax = msc C data segment
  153.     mov    ds,ax            ; ds = ""    ""
  154.     mov    ds:[STKHQQ],0        ; so as to do no stack checking
  155.     mov    es:[cdataseg],ax    ; set up for native code access
  156.     mov    ax,sp
  157.     add    ax,bpregz+pgdata+1eh    ; stack fudge
  158.     mov    [_atopsp],ax        ; ss relative stack top
  159.     mov    bx,seg STACK
  160.     sub    bx,DGROUP
  161.     mov    cl,4
  162.     shl    bx,cl
  163.     add    ax,bx
  164.     mov    [_abrktb].sz,ax        ; ds relative top of memory
  165.     dec    ax
  166.     mov    [_asizds],ax        ; save DS size - 1
  167.  
  168.     mov    ah,62h
  169.     int    21h            ; set up PSP address
  170.     mov    word ptr [_psp],bx
  171.  
  172.     mov    es,[_psp]
  173.     mov    ax,es:[2ch]        ; ax = pointer to environment
  174.     mov    es,ax
  175.     mov    word ptr [_ENV+2],ax
  176.     xor    di,di            ; es:di -> environment
  177.     xor    bx,bx
  178.     xor    al,al            ; now process environment to C format
  179.     mov    cx,0ffffh        ; always find !
  180. MIC10:
  181.   repnz    scasb                ; find end of next env string
  182.     inc    bx            ; increment string count
  183.     scasb                ; end of environment ?
  184.     jnz    MIC10            ; no -->
  185.  
  186.     mov    word ptr [_ESIZE],di    ; size of environment
  187.     mov    [_ENVC],bx        ; number of environment strings
  188.  
  189.     shr    bx,1            ; allocate space for env vector
  190.     shr    bx,1            ; of pointers
  191.     inc    bx            ; plus space for terminator
  192.     mov    ah,48h
  193.     int    21h
  194.     jnc    MIC20
  195.     mov    ax,offset MEMERR    ; no memory
  196.     jmp    XCABT
  197. MIC20:
  198.     xor    si,si
  199.     push    ds
  200.     mov    word ptr [environ+2],ax    ; pointer to environment struct
  201.     mov    bx,[_ENVC]
  202.     or    bx,bx            ; any env strings ?
  203.     jz    MIC40            ; no -->
  204.     les    di,[_ENV]        ; es:di points to env
  205.     mov    cx,[_ESIZE]
  206.     inc    cx
  207.     mov    ds,ax            ; ds:si points to alloc'd memory
  208.     xor    ax,ax
  209. MIC30:
  210.     mov    [si],di            ; set up ptr to next env string
  211.     mov    [si+2],es        ; in env structure
  212.     add    si,4
  213.   repnz    scasb                ; find next one
  214.     dec    bx
  215.     jnz    MIC30
  216.     mov    [si],bx            ; terminate with nulls
  217.     mov    [si+2],bx
  218.     pop    ds            ; ds = DGROUP again
  219.  
  220. ; zero data area (_BSS & c_common)
  221.  
  222.     push    ds
  223.     pop    es
  224.     cld
  225.     mov    di,offset dgroup:_edata    ; beginning of BSS area
  226.     mov    cx,offset dgroup: _end    ; end of BSS area
  227.     sub    cx,di
  228.     xor    ax,ax
  229.     rep    stosb            ; zero bss
  230.  
  231.     mov    [oldsp],sp        ; save stack for later
  232.     mov    [oldss],ss
  233.     mov    ax,ds            ; therefore need local stack
  234.     mov    ss,ax            ; temporarily
  235.     mov    sp,offset DGROUP:endstk    ; __cinit needs ds = ss
  236.     call    __cinit            ; C initialization
  237.     mov    ss,[oldss]        ; restore real stack
  238.     mov    sp,[oldsp]
  239.  
  240. MIC40:
  241.     ret
  242.     
  243.  
  244. MINITP    endp
  245.  
  246. _main     proc    far
  247. __astart proc    far
  248.     ret
  249. __astart endp
  250. _main     endp
  251.  
  252. page
  253. ;------------------------------------------------------------------------
  254. ;
  255. ;    Fast exit fatal errors - die quick and return (255)
  256.  
  257. labelNP <PUBLIC,_cintDIV>
  258.  
  259. labelNP <PUBLIC,_amsg_exit>
  260.     call    __exit            ; _exit(255)
  261.  
  262. ;**
  263. ;
  264. ; name        XCABT -- Ignominious abort
  265. ;
  266. ; description    This area is entered by direct jump with a message
  267. ;        pointer in DS:DX.  It sends the message to the 
  268. ;        console via DOS function 9 and then aborts.
  269. XCABT    proc    near
  270.     MOV    AH,9            ; print error message
  271.     INT    21H
  272.     MOV    ES,WORD PTR _PSP+2
  273.     MOV    AX,4C01H
  274.     INT    21H
  275. XCABT    endp
  276.  
  277. sEnd
  278.  
  279.  
  280. CSEG    segment    byte public 'CODE'
  281.  
  282.     assume    cs:CSEG,ds:DGROUP
  283.  
  284.     extrn    __GETGLOBES:near
  285.  
  286. installed    db    0
  287.  
  288. __NCLINKM    proc    near        ; Called from LCOBOL on startup
  289.  
  290.     test    installed,1        ; is msc already installed ?
  291.     jnz    nm10            ; yes -->
  292.     or    installed,1
  293.     push    ds
  294.     push    bx
  295.     push    cx
  296.     push    dx
  297.     call    __GETGLOBES        ; es = COBOL global data segment
  298.     call    MINITP            ; initialize msc
  299.     pop    dx
  300.     pop    cx
  301.     pop    bx
  302.     pop    ds
  303. nm10:
  304.     ret
  305.  
  306. __NCLINKM    endp
  307.  
  308. __NCLINKS    proc    near        ; Called from LCOBOL on closedown
  309.  
  310.     test    installed,1        ; is msc already installed ?
  311.     jz    ns10            ; no -->
  312.     push    ds
  313.     push    ax            ; push return code
  314.     mov    ax,DGROUP
  315.     mov    ds,ax
  316.     mov    es,word ptr [environ+2]    ; free allocated environment
  317.     mov    ah,49h
  318.     int    21h
  319.     call    _exit            ; terminate C routines
  320.     pop    ds
  321. ns10:
  322.     ret
  323.  
  324. __NCLINKS    endp
  325.  
  326.  
  327. __NCLINKI  proc near
  328. __NCLINKX  proc near
  329. __NCLINKXS proc near
  330. __NCLINK   proc near
  331.            ret
  332. __NCLINK   endp
  333. __NCLINKXS endp
  334. __NCLINKX  endp
  335. __NCLINKI  endp
  336.  
  337. CSEG    ends
  338.  
  339.     end
  340.