home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / ASM / LCFUNCS.ZIP / LATTICE.MAC < prev    next >
Encoding:
Text File  |  1987-03-21  |  18.8 KB  |  623 lines

  1.  
  2. ; LATTICE.MAC - Macros for utilizing Lattice C library
  3.  
  4. ; Macro Include file for interfacing Assembler programs with the
  5. ; Lattice C 2.17 library.  (Small Model Only)
  6.  
  7. ; NOTE: This library of macros is for those of us crazies who want
  8. ; to write in assembler, yet use the many functions of the Lattice C
  9. ; library.  Most people do it the other way around, that is, access
  10. ; assembler language routines from a C program.  It should be a simple
  11. ; task to modify this for other libraries, such as Microsoft or MIX C.
  12. ; The most important details to look for are the names of the segments
  13. ; assumed by the library modules.  I've seen at least one C compiler that
  14. ; always pushes the number of arguments on the stack before the function
  15. ; call.  The best way to modify this library is to write a C program in
  16. ; the target language, and inspect the output (hopefully ASM source).
  17. ; If possible turn Optimization off.  If the compiler does optimization,
  18. ; it makes it more difficult to figure out what registers are really
  19. ; required for each function call because the compiler will generally try
  20. ; to hold the contents of a particular register for as long as possible.
  21. ;
  22. ; Written By Mark E Johnson               February 1987 ( March 20, 1987 )
  23. ;            Johnson Bros. Wholesale Liquor Company
  24. ;            2341 University Avenue
  25. ;            St. Paul MN  55116
  26. ;            TEL. 612-646-2736
  27.  
  28.         .XLIST
  29.  
  30. ; To use these routines, put the line 'include lattice.mac'
  31. ; at the top of your assembler program.  If you aren't using any
  32. ; of the math functions, insert the line 'NOMATH=1' before the
  33. ; 'include lattice.mac'.  Then your program will be about 4K smaller.
  34.  
  35. ; Use the small model (LCS) only!
  36. ; after assembly link just like a Lattice C program:
  37.  
  38. ; LINK C+myprog, myprog,, LCM+LC
  39. ; EXE2BIN myprog.exe myprog.com
  40.  
  41. ; WHERE C    = Lattice C.ASM assembled for COM files
  42. ;       LCM  = Lattice Math library (Optional)
  43. ;       LC   = Lattice Standard IO Library
  44.  
  45. ; NOTE that C functions do not clean up the stack on return
  46. ;      It is up to you to do so.  In this program I do this
  47. ;      by MOVing BP,SP before pushing arguments, and after
  48. ;      the call, MOVe SP,BP. Another way to do this is to
  49. ;      do as many pops after the function call as pushes before
  50. ;      the function call.   Another way is to add a constant
  51. ;      to SP after the function call.
  52.  
  53. ; *********************** MACROS IN THIS FILE *************************
  54.  
  55. ; PSEG    MACRO                          ; Macro to start code segment
  56. ; ENDPS   MACRO                          ; Macro to end code segment
  57. ; DSEG    MACRO                          ; Macro to start a data segment
  58. ; ENDDS   MACRO                          ; Macro to end a data segment
  59.  
  60. ; loaddbl MACRO                          ; Load double into registers
  61. ; pushdbl MACRO                          ; Load Double onto stack
  62. ; storedbl MACRO                         ; Store registers to Double
  63. ; _fopen  MACRO    fname, fmode, fp      ; Open named file
  64. ; _fclose MACRO    fp                    ; Close file
  65. ; _printf MACRO    fp, format, arg       ; Display variable to device
  66. ; _print  MACRO    fp, arg               ; Print Text string to fp
  67. ; _printd MACRO    fp, format, number    ; Display Double float to device
  68. ; _sscanf MACRO    ss, format, number    ; Obtain variable from string
  69. ; _scanf  MACRO    fp, format, number    ; Read variable from device
  70. ; _fgetc  MACRO    fp                    ; Read character from device to AL
  71. ; _fputc  MACRO    fp                    ; Output character in AL to device
  72. ; _fread  MACRO    buffer, blksiz, numblks, fp  ; Read device into buffer
  73. ; _fwrite MACRO    buffer, blksiz, numblks, fp  ; Write buffer to device
  74.  
  75. ; _add    MACRO    op1, op2, dest        ; Add Op1 and Op2
  76. ; _sub    MACRO    op1, op2, dest        ; Subtract Op2 from Op1
  77. ; _mul    MACRO    op1, op2, dest        ; Multiply Op1 by Op2
  78. ; _div    MACRO    op1, op2, dest        ; Divide Op1 by Op2
  79.  
  80. ; _atan   MACRO    source, dest          ; Calculate Arc-Tangent
  81. ; _cos    MACRO    source,dest           ; Calculate cosine
  82. ; _exp    MACRO    source, dest          ; Calculate exponential F(x)
  83. ; _log    MACRO    source, dest          ; Calculate Natural Log
  84. ; _sin    MACRO    source,dest           ; Calculate Sine in radians
  85. ; _pow    MACRO    x, y, dest            ; pow(x,y) = x ^y
  86. ; _sqrt   MACRO    source, dest          ; Calculate Square root
  87. ; _tan    MACRO    source,dest           ; calculate Tangent
  88. ; comp    MACRO    arg1, arg2            ; Compare two Double floats
  89. ; _DtoI   MACRO    dbl, int              ; Convert Double float to Int
  90. ; _ItoD   MACRO    int, dbl              ; Convert Int to Double float
  91. ; _DtoL   MACRO    dbl, long             ; Convert Double float to Long-Int
  92. ; _LtoD   MACRO    long, dbl             ; Convert Long-Int to Double float
  93.  
  94. ; ***************   SAMPLE PROGRAM   *******************************
  95. ;
  96. ;  skeleton of a program
  97. ;  this example inputs a number, then prints the square root
  98. ;
  99. ;        include   lattice.mac
  100. ;        PSEG                        ; Program segment MUST start with PSEG
  101. ;
  102. ; _MAIN  proc      near              ; you MUST have a procedure _MAIN !!!
  103. ;
  104. ;        _fopen    fname, imode, fp1
  105. ;        _fopen    fname, omode, fp2
  106. ;        _printf   fp2,mess1         ; Print opening message
  107. ;        _scanf    fp1,Dfmt,num1     ; Read double precision number
  108. ;        _sqrt     num1,num1         ; Obtain square root
  109. ;        _printd   fp2,mess2,num1    ; print message and number
  110. ;        ret
  111. ;
  112. ; _MAIN  endp
  113. ;
  114. ;        ENDPS                       ; You MUST have an ENDPS
  115. ;
  116. ;        DSEG                        ; Data MUST go into DSEG
  117. ; fp1    dw        ?
  118. ; fp2    dw        ?
  119. ; fname  db        'CON:',0
  120. ; imode  db        'r',0
  121. ; omode  db        'w',0
  122. ; Sfmt   db        '%s',0
  123. ; mess1  db        'Enter Decimal number ',0
  124. ; Dfmt   db        '%lf',0
  125. ; mess2  db        0ah,'Square root is %lf',0
  126. ; num1   db        8 dup (?)
  127. ;
  128. ;        ENDDS                       ; End of data segment (MUST have!)
  129. ;        end
  130.  
  131. ; ******************************************************************
  132.  
  133. MSDOS   EQU      2
  134.  
  135. COM     EQU      0     ; Generate a Com file
  136. LPROG   EQU      0
  137. LDATA   EQU      0
  138.  
  139. ;
  140. ; The following symbols are established via LPROG and LDATA as follows:
  141. ;
  142. S8086   EQU      1
  143. D8086   EQU      0
  144. P8086   EQU      0
  145. L8086   EQU      0
  146.  
  147.         .LIST
  148. ; Functions defined in LC.LIB and LCM.LIB
  149.         extrn    fprintf:near
  150.         extrn    fscanf:near
  151.         extrn    sscanf:near
  152.         extrn    fopen:near
  153.         extrn    fclose:near
  154.         extrn    fputc:near
  155.         extrn    fgetc:near
  156.         extrn    fread:near
  157.         extrn    fwrite:near
  158.  
  159.         IFNDEF   NOMATH
  160.         extrn    cxa55:near   ; double Add
  161.         extrn    cxm55:near   ; double Multiply
  162.         extrn    cxs55:near   ; double Subtract
  163.         extrn    cxd55:near   ; double Divide
  164.         extrn    cxc55:near   ; Compare two doubles
  165.         extrn    cxv50:near   ; convert double to int
  166.         extrn    cxv05:near   ; convert int to double
  167.         extrn    cxv53:near   ; convert Double to long int
  168.         extrn    cxv35:near   ; convert Long int to Double
  169.         extrn    atan:near    ; Arctangent
  170.         extrn    cos:near     ; Cosine
  171.         extrn    exp:near     ; Exponential function of X
  172.         extrn    log:near     ; Natural log
  173.         extrn    pow:near     ; Power
  174.         extrn    sin:near     ; Sine in radians
  175.         extrn    sqrt:near    ; square root
  176.         extrn    tan:near     ; Tangent
  177.         ENDIF
  178.  
  179.         .XLIST
  180.  
  181.  
  182. DSEG    MACRO                          ; Macro to start a data segment
  183. DGROUP  group   DATA
  184. DATA    segment word public 'DATA'
  185.         assume  DS:DGROUP
  186. ENDM
  187.  
  188.  
  189. ENDDS   MACRO                          ; Macro to end a data segment
  190. DATA    ENDS
  191. ENDM
  192.  
  193.  
  194. PSEG    MACRO                          ; Macro to start code segment
  195. PGROUP  group    PROG
  196. PROG    segment  byte public 'PROG'
  197.         assume   CS:PGROUP
  198. ENDM
  199.  
  200.  
  201. ENDPS   MACRO                          ; Macro to end code segment
  202. PROG    ENDS
  203. ENDM
  204.  
  205. loaddbl MACRO                          ; Load double into registers
  206.         mov      ax,ds:word ptr [si+6]
  207.         mov      bx,ds:word ptr [si+4]
  208.         mov      cx,ds:word ptr [si+2]
  209.         mov      dx,ds:word ptr [si]
  210. ENDM
  211.  
  212. pushdbl MACRO                          ;Load Double onto stack
  213.         loaddbl
  214.         push     ax
  215.         push     bx
  216.         push     cx
  217.         push     dx
  218. ENDM
  219.  
  220. storedbl MACRO                         ; Store registers to Double
  221.         mov      ds:word ptr [si+6],ax
  222.         mov      ds:word ptr [si+4],bx
  223.         mov      ds:word ptr [si+2],cx
  224.         mov      ds:word ptr [si],dx
  225. ENDM
  226.  
  227. ; Open a file for input or output
  228. ; format: _fopen(iname, imode, fp1)
  229. ; iname   db     'CON:',0
  230. ; imode   db     'r',0
  231. ; fp1     dw     ?
  232. ;
  233. _fopen  MACRO    fname, fmode, fp      ; Open named file
  234.         mov      bp,sp
  235.         mov      ax,offset &fmode        ;"w" or "r" or See page 3-18
  236.         push     ax
  237.         mov      ax,offset &fname
  238.         push     ax
  239.         call     fopen
  240.         mov      ds:word ptr &fp,ax
  241.         mov      sp,bp
  242. ENDM
  243.  
  244. ; Close a previously opened file
  245. ; format _fclose(fp1)
  246. ;
  247. _fclose MACRO    fp                    ; Close file
  248.         mov      bp,sp
  249.         push     word ptr ds:&fp
  250.         call     fclose
  251.         mov      sp,bp
  252. ENDM
  253.  
  254. ; Uses fprintf to display a string
  255. ; format: _printf(fp, arg)
  256. ; fp      dw     0    (filled in by fopen)
  257. ; fmt     db     '%s',0
  258. ; arg     db     'This is a string',0
  259. ;
  260. _printf MACRO    fp,  arg              ; Display variable to device
  261.         mov      bp,sp
  262.         mov      ax,offset &arg
  263.         push     ax
  264.         push     word ptr ds:&fp
  265.         call     fprintf
  266.         mov      sp,bp
  267. ENDM
  268.  
  269. ; Print a literal string to fp
  270. ; Example:  _print   'Hello world'
  271. ;
  272. _print  MACRO    fp, arg               ; Print Text string to fp
  273.         LOCAL    saddr
  274.         ENDPS
  275.         DSEG
  276. saddr   db       string,'0'
  277.         ENDDS
  278.         PSEG
  279.         _printf  fp,saddr
  280. ENDM
  281.  
  282. _printi MACRO    fp, format, value     ; Display an int, or character
  283.         mov      bp,sp
  284.         push     ds:word ptr &value
  285.         mov      ax,offset &format
  286.         push     ax
  287.         push     ds:word ptr &fp
  288.         call     fprintf
  289.         mov      sp,bp
  290. ENDM
  291.  
  292.  
  293.         IFNDEF   NOMATH
  294. ; Uses printf to output a Double precision number
  295. ; format: _print1(fp, fmt, num1);
  296. ; fp      dw     0   (filled in by fopen)
  297. ; fmt     db     '%lf',0
  298. ; number  db     8 dup (0)
  299. ;
  300. _printd MACRO    fp, format, number    ; Display Double float to device
  301.         mov      bp,sp
  302.         mov      si,offset &number
  303.         pushdbl
  304.         mov      ax,offset &format
  305.         push     ax
  306.         push     word ptr ds:&fp
  307.         call     fprintf
  308.         mov      sp,bp
  309. ENDM
  310.         ENDIF
  311.  
  312. ; perform SSCANF function ( ptr  <-- input string )
  313. ; Format: _sscanf(string, fmt, number)
  314. ; string  db     '1.2323',0
  315. ; fmt     db     '%lf',0
  316. ; number  db     8 dup (?)
  317. ;
  318. _sscanf MACRO    ss, format, number    ; Obtain variable from string
  319.         mov      bp,sp
  320.         mov      ax,offset &number
  321.         push     ax
  322.         mov      ax,offset &format
  323.         push     ax
  324.         mov      ax,offset &ss
  325.         push     ax
  326.         call     sscanf
  327.         mov      sp,bp
  328. ENDM
  329.  
  330. ; Input a double precision number ( or any other simple data type )
  331. ; Format: _scanf(fp, fmt, number);
  332. ; fp      dw     0   (filled in by fopen)
  333. ; fmt     db     '%lf',0
  334. ; number  db     8 dup (?)
  335. ;
  336. _scanf  MACRO    fp, format, number    ; Read variable from device
  337.         mov      bp,sp
  338.         mov      ax,offset &number
  339.         push     ax
  340.         mov      ax,offset &format
  341.         push     ax
  342.         push     word ptr ds:&fp
  343.         call     fscanf
  344.         mov      sp,bp
  345. ENDM
  346.  
  347. ; FGETC - Read a character from *fp
  348. ;         Character returned in AL
  349. ;
  350. _fgetc  MACRO    fp                    ; Read character from device
  351.         mov      bp,sp
  352.         push     word ptr ds:&fp
  353.         call     fgetc
  354.         mov      sp,bp
  355. ENDM
  356.  
  357. ; FPUTC - Put a character to *fp
  358. ;         Character is in AL
  359. ;
  360. _fputc  MACRO    fp                    ; Output character to device
  361.         mov      bp,sp
  362.         sub      ah,ah
  363.         push     word ptr ds:&fp
  364.         push     ax
  365.         call     fputc
  366.         mov      sp,bp
  367. ENDM
  368.  
  369. ; FREAD - Read a block of data from *fp, into area pointed by BUFER
  370. ;         Returns actual number of bytes read in AX
  371. ; Format: _fread(*bufloc, 128, 8, *fp)
  372. ; bufloc  dw     ?
  373. ;
  374. _fread  MACRO    buffer, blksiz, numblks, fp  ; Read device into buffer
  375.         mov      bp,sp
  376.         push     word ptr ds:&fp
  377.         mov      ax,ds:word ptr &numblks
  378.         push     ax
  379.         mov      ax,ds:word ptr &blksiz
  380.         push     ax
  381.         mov      ax,ds:word ptr &buffer       ; Get address of area
  382.         push     ax
  383.         call     fread
  384.         mov      sp,bp
  385. ENDM
  386.  
  387. ; FWRITE - Read a block of data from *fp, BUFFER points to data area
  388. ;          Returns actual number of bytes read in AX
  389. ; Format:  _fwrite(*bufloc, 128, 8, *fp)
  390. ; bufloc   dw    ?
  391. ;
  392. _fwrite MACRO    buffer, blksiz, numblks, fp  ; Write buffer to device
  393.         mov      bp,sp
  394.         push     word ptr ds:&fp
  395.         mov      ax,ds:word ptr &numblks
  396.         push     ax
  397.         mov      ax,ds:word ptr &blksiz
  398.         push     ax
  399.         mov      ax,ds:word ptr &buffer
  400.         push     ax
  401.         call     fwrite
  402.         mov      sp,bp
  403. ENDM
  404.  
  405.         IFNDEF   NOMATH
  406.  
  407. ;Add two doubles, dest=op1+op2
  408. ;
  409. _add    MACRO    op1, op2, dest        ; Add Op1 and Op2
  410.         mov      si,offset &op1
  411.         loaddbl
  412.         mov      si, offset &op2
  413.         push     si
  414.         call     cxa55
  415.         mov      si, offset &dest
  416.         storedbl
  417. ENDM
  418.  
  419. ; Subtract two doubles: dest=op1-op2
  420. ;
  421. _sub    MACRO    op1, op2, dest        ; Subtract Op2 from Op1
  422.         mov      si,offset &op1
  423.         loaddbl
  424.         mov      si, offset &op2
  425.         push     si
  426.         call     cxs55
  427.         mov      si, offset &dest
  428.         storedbl
  429. ENDM
  430.  
  431. ; Multiply two doubles:  dest=op1*op2
  432. ;
  433. _mul    MACRO    op1, op2, dest        ; Multiply Op1 by Op2
  434.         mov      si,offset &op1
  435.         loaddbl
  436.         mov      si, offset &op2
  437.         push     si
  438.         call     cxm55
  439.         mov      si, offset &dest
  440.         storedbl
  441. ENDM
  442.  
  443. ; Divide two doubles: dest=op1/op2
  444. ;
  445. _div    MACRO    op1, op2, dest        ; Divide Op1 by Op2
  446.         mov      si,offset &op1
  447.         loaddbl
  448.         mov      si, offset &op2
  449.         push     si
  450.         call     cxd55
  451.         mov      si, offset &dest
  452.         storedbl
  453. ENDM
  454.  
  455. ; ****** High Level Mathematical Functions ******
  456. ; ******      Grouped Alphabetically       ******
  457.  
  458. _atan   MACRO    source, dest          ; Calculate Arc-Tangent
  459.         mov      bp,sp
  460.         mov      si,offset &source     ; setup for the ATAN function
  461.         pushdbl
  462.         call     atan
  463.         mov      si,offset &dest
  464.         storedbl
  465.         mov      sp,bp
  466. ENDM
  467.  
  468. _cos    MACRO    source,dest           ; Calculate cosine
  469.         mov      bp,sp
  470.         mov      si,offset &source
  471.         pushdbl
  472.         call     cos
  473.         mov      si,offset &dest
  474.         storedbl
  475.         mov      sp,bp
  476. ENDM
  477.  
  478. _exp    MACRO    source, dest          ; Calculate exponential F(x)
  479.         mov      bp,sp
  480.         mov      si,offset &source
  481.         pushdbl
  482.         call     exp
  483.         mov      si,offset &dest
  484.         storedbl
  485.         mov      sp,bp
  486. ENDM
  487.  
  488. _log    MACRO    source, dest          ; Calculate Natural Log
  489.         mov      bp,sp
  490.         mov      si,offset &source
  491.         pushdbl
  492.         call     log
  493.         mov      si,offset &dest
  494.         storedbl
  495.         mov      sp,bp
  496. ENDM
  497.  
  498. _pow    MACRO    x, y, dest          ; pow(x,y) = x ^y
  499.         mov      bp,sp
  500.         mov      si,offset &y
  501.         pushdbl
  502.         mov      si,offset &x
  503.         pushdbl
  504.         call     pow
  505.         mov      si,offset &dest
  506.         storedbl
  507.         mov      sp,bp
  508. ENDM
  509.  
  510. _sin    MACRO    source,dest           ; Calculate Sine in radians
  511.         mov      bp,sp
  512.         mov      si,offset &source
  513.         pushdbl
  514.         call     sin
  515.         mov      si,offset &dest
  516.         storedbl
  517.         mov      sp,bp
  518. ENDM
  519.  
  520. ; Square root: dest=sqrt(source)
  521. ;
  522. _sqrt   MACRO    source, dest          ; Calculate Square root
  523.         mov      bp,sp
  524.         mov      si,offset &source
  525.         pushdbl
  526.         call     sqrt
  527.         mov      si,offset &dest
  528.         storedbl
  529.         mov      sp,bp
  530. ENDM
  531.  
  532. _tan    MACRO    source,dest           ; calculate Tangent
  533.         mov      bp,sp
  534.         mov      si,offset &source
  535.         pushdbl
  536.         call     tan
  537.         mov      si,offset &dest
  538.         storedbl
  539.         mov      sp,bp
  540. ENDM
  541.  
  542.  
  543. ;Compare two floating point numbers
  544. ;Results are in Flags, and can be acted upon with conditional jumps:
  545. ;                      ==  JZ
  546. ;                      !=  JNZ
  547. ;                      >   JG
  548. ;                      <   JL
  549. ;                      >=  JGE
  550. ;                      <=  JLE
  551. ;
  552. COMP    MACRO    arg1, arg2            ; Compare two Double floats
  553.         mov      bp,sp
  554.         mov      si,offset &arg1
  555.         loaddbl
  556.         mov      si,offset &arg2
  557.         push     si
  558.         call     cxc55
  559.         mov      sp,bp
  560. ENDM
  561.  
  562. ; Convert double to integer
  563. ;
  564. _dtoi   MACRO    dbl, int              ; Convert Double float to Int
  565.         mov      bp,sp
  566.         mov      si,offset &dbl
  567.         loaddbl
  568.         call     cxv50
  569.         mov      ds:word ptr &int,ax
  570.         mov      sp,bp
  571. ENDM
  572.  
  573. ; Convert integer to double
  574. ;
  575. _itod   MACRO    int, dbl              ; Convert Int to Double float
  576.         mov      bp,sp
  577.         mov      ax,ds:word ptr &int
  578.         call     cxv05
  579.         push     ax
  580.         push     bx
  581.         push     cx
  582.         push     dx
  583.         mov      si,offset &dbl
  584.         storedbl                     ; ax->6, bx->4
  585.         mov     sp,bp
  586. ENDM
  587.  
  588. ; Convert Double to Long Int
  589. ;
  590. _dtol   MACRO    dbl, long             ; Convert Double float to Long-Int
  591.         mov      bp,sp
  592.         mov      si,offset &dbl
  593.         loaddbl
  594.         call     cxv53
  595.         mov      si,offset &long
  596.         mov      ds:word ptr &long,bx
  597.         mov      ds:word ptr &long+2,ax
  598.         mov      sp,bp
  599. ENDM
  600.  
  601. ; Convert Long Int to double
  602. ;
  603. _ltod   MACRO    long, dbl             ; Convert Long-Int to Double float
  604.         mov      bp,sp
  605.         mov      ax,offset &dbl + 2
  606.         mov      bx,offset &dbl
  607.         call     cxv35
  608.         mov      si,offset &dbl
  609.         storedbl
  610.         mov      sp,bp
  611. ENDM
  612.  
  613.         ENDIF
  614.  
  615. CPSIZE  EQU      2            ; CPSIZE -> code pointer size (2 or 4)
  616. DPSIZE  EQU      2            ; DPSIZE -> data pointer size (2 or 4)
  617.  
  618.         .LIST
  619. ; User's _MAIN starts here.
  620.  
  621.         PUBLIC   _MAIN
  622.  
  623.