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

  1.     name    LINITC
  2.     title    LINITC - Lattice C Initialization
  3.     subttl    Copyright (C) Micro Focus Ltd 1987
  4.  
  5.     public    __NCLINKM    ; these are routines called from LCOBOL
  6.     public    __NCLINKI    ; from strategic places such as
  7.     public    __NCLINKX    ; exit from a program, startup, closedown
  8.     public    __NCLINKXS    ; etc.
  9.     public    __NCLINKS
  10.     public    __NCLINK
  11.     public    _MAIN        ; dummy routine to satisfy ref in LC.LIB
  12.  
  13.     .8087
  14.  
  15. CBLRUDAT segment para public 'CBL_DATA'
  16.  
  17.     include cblrudat.equ
  18.  
  19. CBLRUDAT ends
  20.  
  21.     include    handle.equ
  22.  
  23. ; This module provides an interface for calling Lattice V3.2x objects.
  24. ; Link your program as follows
  25. ;    LINK COBOL_objects+LINITC+LINITIO+C_objects,,,LCOBOL+LC+C_libraries/m;
  26.  
  27.  
  28. ;**
  29. ;
  30. ; Assembly parameters
  31. ;
  32. STKMIN    EQU    128            ; default paragraphs for stack
  33. ENVMIN    EQU    64            ; default paragraphs for environment
  34. HEAPMIN    EQU    128            ; default paragraphs for heap
  35.  
  36.  
  37.     extrn    LINITIO:far
  38.  
  39.  
  40. DGROUP    GROUP    DATA,NDATA,UDATA
  41.  
  42. CSEG    segment byte public 'CODE'
  43.  
  44.     assume    cs:CSEG,ds:DGROUP
  45.  
  46.     extrn    __GETGLOBES:near
  47.     extrn    __MFGETENV:near
  48.  
  49. installed    db    0
  50.  
  51. __NCLINKM    proc    near        ; Called from LCOBOL on startup
  52.  
  53.     test    installed,1        ; is lattice c already installed ?
  54.     jnz    nm10            ; yes -->
  55.     or    installed,1
  56.     push    ds
  57.     push    bx
  58.     push    cx
  59.     push    dx
  60.     call    LINITC            ; initialize lattice
  61.     call    LINITIO            ; initialize lattice IO library
  62.     pop    dx
  63.     pop    cx
  64.     pop    bx
  65.     pop    ds
  66. nm10:
  67.     ret
  68.  
  69. __NCLINKM    endp
  70.  
  71. __NCLINKS    proc    near        ; Called from LCOBOL on closedown
  72.  
  73.     test    installed,1        ; is lattice c already installed ?
  74.     jz    ns10            ; no -->
  75.     push    ds
  76.     mov    ax,dgroup    
  77.     mov    ds,ax
  78.     mov    es,word ptr [environ+2]    ; free allocated environment
  79.     mov    ah,49h
  80.     int    21h
  81.     mov    es,word ptr [_MBASE+2]    ; free allocated pool memory
  82.     mov    ah,49h
  83.     int    21h
  84.     pop    ds
  85. ns10:
  86.     ret
  87.  
  88. __NCLINKS    endp
  89.  
  90.  
  91. __NCLINKI  proc near
  92. __NCLINKX  proc near
  93. __NCLINKXS proc near
  94. __NCLINK   proc near
  95.            ret
  96. __NCLINK   endp
  97. __NCLINKXS endp
  98. __NCLINKX  endp
  99. __NCLINKI  endp
  100.  
  101.  
  102. ; The following routine is taken partly from the file C.ASM provided
  103. ; with the Lattice C product and does necessary initialization
  104. ; for Lattice C objects. It will only handle 'L' model programs
  105. ; so to use this and INITIO you must compile your lattice C programs with
  106. ; the -ml option.
  107.  
  108. ; The pool size allocated in this module is by default 64k, but if
  109. ; the environment variable POOL is set then this value will be used.
  110. ; so to allocate 150k of pool size type the following to your DOS 
  111. ; prompt
  112. ;     set pool=150
  113.  
  114. LINITC    proc    near            ; Initialize lattice C
  115.  
  116.     mov    ax,DGROUP        ; ax = lattice C data segment
  117.     mov    ds,ax            ; ds = ""
  118.     call    __GETGLOBES        ; es = COBOL global data segment
  119.     mov    es:[cdataseg],ax    ; set up for native code access
  120.     mov    ax,sp
  121.     add    ax,bpregz+pgdata+14h    ; stack fudge
  122.     mov    [_TOP],ax        ; ss relative stack top
  123.     mov    ah,30h            ; get DOS version
  124.     int    21h
  125.     mov    [_DOS],ax        ; DOS version number
  126.  
  127.     mov    ah,62h
  128.     int    21h            ; set up PSP address
  129.     mov    word ptr [_PSP+2],bx
  130.     mov    es,bx
  131. ;
  132. ; Initialize various size items
  133. ;
  134.     SUB    _TSIZE,bx        ; size of basic block
  135.     SUB    _PSIZE,bx        ; size of program section    
  136.     SUB    _DSIZE,SEG DATA        ; size of initialized data
  137.     SUB    _NSIZE,SEG NDATA    ; size of near data
  138.     SUB    _USIZE,SEG UDATA    ; size of uninitialized data
  139.     SUB    _SSIZE,SEG STACK    ; size of stack
  140.     SUB    _CSIZE,SEG CX_CONST    ; size of constants
  141.     SUB    _FDSIZE,SEG CX_FAR    ; size of far initialized data
  142.     SUB    _FBSIZE,SEG CX_BSS    ; size of far uninitialized data
  143.  
  144.     mov    ax,es:[2ch]        ; ax = pointer to environment
  145.     mov    word ptr [_ENV+2],ax
  146.     mov    es,ax
  147.     xor    di,di            ; es:di -> environment
  148.     xor    bx,bx
  149.     xor    al,al            ; now process environment to C format
  150.     mov    cx,0ffffh        ; always find !
  151. LIC10:
  152.   repnz    scasb                ; find end of next env string
  153.     inc    bx            ; increment string count
  154.     scasb                ; end of environment ?
  155.     jnz    LIC10            ; no -->
  156.  
  157.     mov    word ptr [_ESIZE],di    ; size of environment
  158.     mov    [_ENVC],bx        ; number of environment strings
  159.  
  160.     shr    bx,1            ; allocate space for env vector
  161.     shr    bx,1            ; of pointers
  162.     inc    bx            ; plus space for terminator
  163.     mov    ah,48h
  164.     int    21h
  165.     jnc    LIC20
  166.     mov    ax,offset MEMERR    ; no memory
  167.     jmp    XCABT
  168. LIC20:
  169.     xor    si,si
  170.     push    ds
  171.     mov    word ptr [environ+2],ax    ; pointer to environment struct
  172.     mov    bx,[_ENVC]
  173.     or    bx,bx            ; any env strings ?
  174.     jz    LIC40            ; no -->
  175.     les    di,[_ENV]        ; es:di points to env
  176.     mov    cx,[_ESIZE]
  177.     inc    cx
  178.     mov    ds,ax            ; ds:si points to alloc'd memory
  179.     xor    ax,ax
  180. LIC30:
  181.     mov    [si],di            ; set up ptr to next env string
  182.     mov    [si+2],es        ; in env structure
  183.     add    si,4
  184.   repnz    scasb                ; find next one
  185.     dec    bx
  186.     jnz    LIC30
  187.     mov    [si],bx            ; terminate with nulls
  188.     mov    [si+2],bx
  189.     pop    ds            ; ds = DGROUP again
  190.  
  191. LIC40:                    ; allocate space for memory pool
  192.     mov    ax,ds
  193.     mov    es,ax
  194.     mov    bx,offset DGROUP:str_pool ; ds:bx -> "POOL"
  195.     mov    di,offset DGROUP:str_poolsz ; es:di -> area to be returned
  196.     mov    cl,10
  197.     call    __MFGETENV        ; get env var.
  198.     jc    LIC45            ; no such name
  199.     xor    ch,ch            ; cl = length of result buffer
  200.     xor    ax,ax            ; dx;ax to contain result
  201.     xor    dx,dx
  202.     xor    bx,bx
  203.     mov    si,10            ; for multiplication by 10
  204. LIC42:
  205.     mul    si            ; size = size * 10
  206.     mov    bl,es:[di]        ; size = size + digit
  207.     sub    bl,'0'
  208.     inc    di            ; next digit
  209.     add    ax,bx
  210.     adc    dx,0
  211.     loop    LIC42
  212.     mov    si,1024            ; result is in nK
  213.     mul    si            ; ... so multiply by 1024 to get bytes
  214.     mov    cl,4             ; calculate num paras
  215.     ror    dx,cl            ; to allocate
  216.     shr    ax,cl
  217.     or    ax,dx
  218.     mov    poolsize,ax        ; set up poolsize
  219.  
  220. LIC45:
  221.     mov    bx,poolsize        ; allocate pool
  222.     mov    ah,48h
  223.     int    21h
  224.     jnc    LIC50
  225.     mov    ax,offset DGROUP:MEMERR    ; got memory ?
  226.     jmp    XCABT
  227.  
  228. LIC50:
  229.     mov    word ptr [_MBASE+2],ax    ; base of memory pool
  230.     mov    ax,poolsize        ; set up MNEED
  231.     mov    cl,4
  232.     rol    ax,cl
  233.     mov    bx,ax
  234.     and    ah,0fh
  235.     mov    word ptr [_MNEED+2],ax
  236.     and    bx,0fff0h
  237.     mov    word ptr [_MNEED],bx
  238.     mov    bx,poolsize
  239.     mov    word ptr [_MSIZE],bx
  240.     mov    [_STACK],200h        ; stack size
  241.  
  242. ;
  243. ; initialize 8087 numeric data processor
  244. ;
  245.     FNINIT                ; reset
  246.     FNSTSW    _NDPSW            ; get status
  247.     MOV    AX,100            ; this is just for delay
  248.     MOV    DX,AX
  249.     IMUL    DX
  250.     TEST    _NDPSW,0B8BFH        ; 8087 will reset all these
  251.     JNZ    LIC_x
  252.     INC    _NDP            ; indicate ndp present
  253.  
  254. LIC_x:
  255.     ret
  256.  
  257. LINITC    endp
  258.  
  259. ;**
  260. ;
  261. ; name        XCABT -- Ignominious abort
  262. ;
  263. ; description    This area is entered by direct jump with a message
  264. ;        pointer in DS:DX.  It sends the message to the 
  265. ;        console via DOS function 9 and then aborts.
  266. XCABT    proc    near
  267.     MOV    AH,9            ; print error message
  268.     INT    21H
  269.     MOV    ES,WORD PTR _PSP+2
  270.     MOV    AX,4C01H
  271.     INT    21H
  272. XCABT    endp
  273.  
  274. _MAIN    proc    near            ; dummy _MAIN procedure
  275.     ret
  276. _MAIN    endp
  277.  
  278. CSEG    ends
  279.  
  280. ;**
  281. ;
  282. ;  The "CODE" segments are followed by those with class "FAR_DATA", which
  283. ;  in turn are followed by segments in the "CONST" class.  The following
  284. ;  statements are dummy segments that force this ordering when this startup
  285. ;  module is linked first.
  286. ;
  287. CX_FAR    SEGMENT    PARA 'FAR_DATA'
  288. CX_FAR    ENDS
  289.  
  290. CX_CONST SEGMENT PARA 'CONST'
  291. CX_CONST ENDS    
  292.  
  293.     PAGE
  294. ;**
  295. ;
  296. ;  DGROUP always includes the segments named DATA, UDATA, and NDATA.
  297.  
  298. ;  The argument strings and the argument vector are placed at the high-order
  299. ;  end of the stack.  This is necessary because the command processor passes
  300. ;  and unparsed command line, but C main programs conventionally expect to
  301. ;  receive a "vector" of pointers to the command arguments.  The startup
  302. ;  routine treats the command line as a sequence of arguments separated by
  303. ;  white space.  If an argument contains white space, the entire argument
  304. ;  must be enclosed in double quotes.  Within such a quoted argument, a
  305. ;  double quote can be "escaped" by preceding it with a backslash.
  306. ;
  307. ;  The external variable "environ" contains
  308. ;  a pointer to this vector, and the pointer is also passed as the third 
  309. ;  argument to the main program.  Note that the vector may move as a result
  310. ;  of calls to "putenv" or "rmvenv", but when that happens, "environ" is
  311. ;  updated.
  312. ;
  313. ;  The heap (i.e. the space used by the memory allocator) resides above the
  314. ;  environment and is also initialized by the startup routine.  Any space not
  315. ;  immediately needed for the heap (as defined by _MNEED) is returned to DOS.
  316. ;  For the S and P models, the heap size is limited by the FAR_BSS class of
  317. ;  data items.  That is, if this class is not empty, then the heap cannot be
  318. ;  expanded by getting more space from DOS.
  319. ;  
  320. ;  At the end of the startup routine, memory is organized in the following 
  321. ;  sequence:
  322. ;
  323. ;    -- code --
  324. ;    -- FAR_DATA --
  325. ;    -- CONST --
  326. ;    -- DATA --
  327. ;    -- NDATA --
  328. ;    -- UDATA --
  329. ;    -- FAR_BSS --
  330. ;    -- stack --
  331. ;    -- arguments --
  332. ;    -- environment --
  333. ;    -- heap --
  334. ;
  335. ;  FOR PROPER OPERATION OF THE STANDARD MEMORY ALLOCATOR, THIS SEQUENCE IS
  336. ;  EXTREMELY IMPORTANT.  IF YOU TAMPER WITH THE STARTUP ROUTINE OR INTRODUCE
  337. ;  SEGMENTS AND CLASSES THAT DO NOT FOLLOW LATTICE CONVENTIONS, CHECK THE
  338. ;  LOAD MAP CAREFULLY.
  339. ;
  340. ;**
  341.  
  342. ;**
  343. ;
  344. ; This segment contains all initialized static data.
  345. ;
  346. DATA    SEGMENT PARA PUBLIC 'DATA'
  347. ;
  348. ; External data items
  349. ;
  350.     EXTRN    _STACK:WORD        ; stack size needed by user
  351.     EXTRN    _MNEED:DWORD        ; heap size needed by user
  352.  
  353. poolsize    dw    1000h        ; pool size in paragraphs
  354. str_pool    db    "POOL",00    ; pool environment string
  355. str_poolsz    db    10 dup(' ')    ; value of pool environment string
  356.  
  357. ;
  358. ; These items provide information about DOS and the memory model.  The 
  359. ; _DOS word contains the major version number in its low order byte and
  360. ; the minor number in its high order byte.  If you are only interested 
  361. ; in the major number, you can reference _DOS as a byte instead of a word.
  362. ;
  363.     PUBLIC    _MODEL,_DOS
  364. _MODEL    DW    3            ; L model indicator
  365. _DOS    DW    0            ; DOS major/minor version number
  366. ;
  367. ; Information about some objects that are passed by this process's parent.
  368. ; The addresses are all represented as far pointers.
  369. ;
  370.     PUBLIC    _ENV,_ENVL,_PSP,_CMD
  371. _ENV    DD    0            ; address of original environment
  372. _ENVL    DW    0            ; size of original environment (bytes)
  373. _PSP    DD    0            ; address of program segment prefix
  374. _CMD    DW    80H            ; address of original command line
  375.     DW    0
  376. ;
  377. ; The following item gives the size of the "basic block" for this process.
  378. ; The basic block is a contiguous memory area that includes the program,
  379. ; data, stack, and heap.  As the heap grows, this value changes.  It is
  380. ; administered by the low-level memory allocator (sbrk/rbrk).
  381. ;
  382.     PUBLIC    _TSIZE
  383. _TSIZE    DW    SEG HIGH        ; size of basic block in paragraphs
  384. ; The following item gives the size of the program section, which is the
  385. ; area from the Program Segment Prefix to DGROUP.
  386. ;
  387. ;
  388.     PUBLIC    _PSIZE
  389. _PSIZE    DW    DGROUP
  390. ;
  391. ; The following items give the base address and size of the CONST section.
  392. ;
  393.     PUBLIC    _CBASE,_CSIZE
  394. _CBASE    DW    0            ; address of CONST section
  395.     DW    SEG CX_CONST
  396. _CSIZE    DW    DGROUP            ; CONST size in paragraphs
  397. ;
  398. ; The following items give the base address and size of the initialized 
  399. ; far data section.
  400. ;
  401.     PUBLIC    _FDBASE,_FDSIZE
  402. _FDBASE    DW    0            ; address of FAR_DATA section
  403.     DW    SEG CX_FAR
  404. _FDSIZE    DW    SEG CX_CONST        ; FAR_DATA size in paragraphs
  405. ;
  406. ; The following items give the base address and size of the uninitialized
  407. ; far data section.
  408. ;
  409.     PUBLIC    _FBBASE,_FBSIZE
  410. _FBBASE    DW    0            ; address of FAR_BSS section
  411.     DW    SEG CX_BSS
  412. _FBSIZE    DW    SEG STACK        ; FAR_BSS size in paragraphs
  413. ;
  414. ; The following items give the base address and size of the initialized
  415. ; data section (i.e. the DATA segment) contained within DGROUP.
  416. ;
  417.     PUBLIC    _DBASE,_DSIZE
  418. _DBASE    DW    0            ; address of DATA section
  419.     DW    DGROUP
  420. _DSIZE    DW    SEG NDATA        ; DATA size in paragraphs
  421. ;
  422. ; The following items give the base address and size of the near data
  423. ; section (i.e. the NDATA segment) contained within DGROUP.
  424.     PUBLIC    _NBASE,_NSIZE
  425. _NBASE    DW    OFFSET DGROUP:NDATA    ; address of near data section
  426.     DW    DGROUP
  427. _NSIZE    DW    SEG UDATA        ; NDATA size in paragraphs
  428. ;
  429. ; The following items give the base address and size of the uninitialized
  430. ; data section (i.e. the UDATA segment) contained within DGROUP.
  431.     PUBLIC    _UBASE,_USIZE
  432. _UBASE    DW    OFFSET DGROUP:UDATA    ; address of uninitialized data
  433.     DW    DGROUP
  434. _USIZE    DW    SEG CX_BSS        ; UDATA size in paragraphs
  435. ;
  436. ; The following items give the base address and size of the stack section.
  437. ; This section is a part of the data group for the S and P models, but
  438. ; it stands alone for the D and L models.
  439. ;
  440.     PUBLIC    _SBASE,_SSIZE,_TOP
  441. _SBASE    DW    0            ; address of stack section
  442.     DW    STACK
  443. _SSIZE    DW    SEG HIGH        ; STACK size in paragraphs
  444. _TOP    DW    0            ; top of stack (relative to SS)
  445. ;
  446. ; The following items define the environment area.  For the S and P
  447. ; models, this area is part of the data group, but it stands alone
  448. ; for the D and L models.  As part of the initialization procedure, the
  449. ; original environment is copied to this new area, with unused space
  450. ; at the end for growth.
  451. ;
  452.     PUBLIC    _EBASE,_ESIZE
  453. _EBASE    DD    0            ; address of environment section
  454. _ESIZE    DW    0            ; size of environment area in bytes
  455. ;
  456. ; The following items define the heap area.  For the S and P models, this
  457. ; area is part of the data group, but it stands alone for the D and L models.
  458. ;
  459.     PUBLIC    _MBASE,_MSIZE,_MUSED
  460. _MBASE    DD    0            ; address of memory pool           
  461. _MSIZE    DW     0             ; number of paragraphs in pool
  462. _MUSED    DW    0            ; number of paragraphs used
  463. ;
  464. ; The process arguments are moved to the top of the stack as an array
  465. ; of null-terminated strings.  Then an "argument vector" is constructed 
  466. ; just below the argument strings.  The vector contains a pointer to each
  467. ; successive string.  The end of the vector is marked by a null pointer.
  468. ; Also, the last string is followed by a null string.
  469. ;
  470.     PUBLIC    _ARG,_ARGV,_ARGC
  471. _ARG    DW    0            ; pointer to arg array in stack
  472.     DW    STACK
  473. _ARGV    DW    0            ; pointer to arg vector in stack
  474.     DW    STACK
  475. _ARGC    DW    1            ; argument count
  476. ;
  477. ; The environment passed by this process's parent is copied to an area
  478. ; just above the stack and below the heap.  The size of this area is
  479. ; determined by _ENEED, which should contain a value large enough to
  480. ; account for environment growth resulting from calls to "putenv".  If
  481. ; _ENEED is 0, then the startup routine computes a reasonable value.
  482. ;
  483.     PUBLIC    environ,_ENVC
  484. environ    DD    0            ; environment vector pointer
  485. _ENVC    DW    0            ; environment count
  486.  
  487. ;
  488. ; The following items are used by the floating point subsystem.
  489. ;
  490.     PUBLIC    _FPA,_FPERR
  491.     PUBLIC    _NDP,_NDPSW,_NDPCW
  492.     PUBLIC    _SIGFPE
  493. _FPA    DQ    0            ; floating point accumulator
  494. _FPERR    DW    0            ; floating point error code
  495. _NDP    DB    0            ; non-zero if 8087 is installed
  496. _NDPSW    DW    0FFFFH            ; 8087 status word
  497. _NDPCW    DW    0            ; 8087 control word
  498. _SIGFPE    DD    0            ; Floating point error signal
  499. ;
  500. ; The following item contains the main error code returned by the most
  501. ; recent DOS call made through the standard library.  That is, each time
  502. ; the standard library calls a DOS service function, it checks the return
  503. ; code and places it here.  For DOS 3, the CXSERR routine obtains the
  504. ; extended error information and places it in several other items that
  505. ; you can find in CXSERR.ASM.
  506. ;
  507. ; Note that _OSERR, unlike the UNIX error code in errno, is not "sticky".  
  508. ; That is, _OSERR gets reset to zero when the DOS service is successful.
  509. ;
  510.     PUBLIC    _OSERR
  511. _OSERR    DW    0            ; DOS error code
  512.  
  513. ;
  514. ; Abort messages for the startup routine
  515. ;
  516. ARGERR    DB    "Stack overflow during arg parsing",0DH,0AH,"$"
  517. DOSERR    DB    "Incompatible DOS version",0DH,0AH,"$"
  518. STKERR    DB    "Invalid stack size",0DH,0AH,"$"
  519. MEMERR    DB    "Insufficient memory",0DH,0AH,"$"
  520. ENVERR    DB    "Corrupted environment",0DH,0AH,"$"
  521. HEPERR    DB    "Insufficient memory for specified heap size",0DH,0AH,"$"
  522.  
  523. DATA    ENDS
  524.  
  525.  
  526. ;**
  527. ;
  528. ; This segment contains all data items that are explicitly declared as
  529. ; "near".
  530. ;
  531. NDATA    SEGMENT    PARA PUBLIC 'DATA'
  532. NDATA    ENDS
  533.  
  534. ;**
  535. ;
  536. ; Uninitialized data
  537. ;
  538. UDATA    SEGMENT    PARA PUBLIC 'DATA'
  539. UDATA    ENDS
  540.  
  541. ;**
  542. ;
  543. ; This is a dummy segment that establishes the position of the uninitialized
  544. ; far data items in the D and L models.
  545. ;
  546. CX_BSS    SEGMENT    PARA PUBLIC 'FAR_BSS'
  547. CX_BSS    ENDS
  548.  
  549. ;**
  550. ;
  551. ; This is the default stack segment, and it also defines the default 
  552. ; environment and heap areas.  The size may be larger or smaller after the
  553. ; startup routine finishes, because you are allowed to change the stack,
  554. ; heap, and environment sizes via the command line or via global variables.
  555. ;
  556. STACK    SEGMENT STACK PARA 'STACK'
  557.     DB    (STKMIN+ENVMIN+HEAPMIN)*16 DUP (?)
  558. STACK    ENDS
  559.  
  560. ;**
  561. ;
  562. ; This is a dummy segment that establishes the position of the uninitialized
  563. ; far data items in the S and P models.
  564. ;
  565. CX_BSS    SEGMENT    PARA PUBLIC 'FAR_BSS'
  566. CX_BSS    ENDS
  567.  
  568. ;**
  569. ;
  570. ; This is a dummy segment that defines the high end of the basic block (i.e.
  571. ; the last segment in memory).
  572. ;
  573. HIGH    SEGMENT    PARA PUBLIC 'HIGH'
  574. HIGH    ENDS
  575.  
  576.     end
  577.