home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 137_01 / llsup.asm < prev    next >
Assembly Source File  |  1985-03-10  |  5KB  |  209 lines

  1. ;
  2. ; llsup.asm
  3. ;
  4. ; a component of lsup.c
  5. ;
  6. ; Copyright 1984 (c) A. Skjellum. All rights reserved.
  7. ; version of 25-Mar-84
  8. ;
  9. ; This routine makes no assumptions about the behavior of the
  10. ; C compiler in use.
  11. ;
  12. ; all procedures are "near"
  13. ;
  14.  
  15. dseg    segment para public 'data'
  16. dseg    ends
  17.  
  18. cseg    segment para public 'code'
  19.     assume    cs:cseg,ds:dseg
  20.  
  21. ;
  22. ; linc:        increment a long pointer by 1 byte
  23. ;
  24. ; expects:    es:bx with long pointer to increment
  25. ; returns:    pointer incremented.
  26. ; consumes:    es, bx, f, ax
  27. ;
  28.     public    linc
  29. linc    proc    near
  30.     inc    bx        ; increment low part of word
  31.     or    bx,bx        ; is it zero now?
  32.     jnz    linc_exit    ; no, we are done
  33.     mov    ax,es
  34.     add    ax,1000h    ; another 64k of paragraphs
  35.     mov    es,ax        ; store back to es
  36. linc_exit:
  37.     ret            ; return
  38. linc    endp
  39.  
  40. ;
  41. ; ldec:        decrement a long pointer by 1 byte
  42. ;
  43. ; expects:    es:bx with long pointer to decrement
  44. ; returns:    pointer decremented.
  45. ; consumes:    es, bx, f, ax
  46. ;
  47.     public    ldec
  48. ldec    proc    near
  49.     or    bx,bx        ; zero currently ?
  50.     dec    bx        ; decrement it
  51.     jnz    ldec_exit    ; just decrement low end and exit...
  52.     mov    ax,es        ; get segment register
  53.     sub    ax,1000h    ; remove 64k of paragraphs
  54.     mov    es,ax        ; store back to es
  55. ldec_exit:
  56.     ret            ; return
  57. ldec    endp
  58.  
  59. ;
  60. ; ladd:        add a constant to a long pointer
  61. ;
  62. ; expects:    es:bx with long pointer's original value
  63. ;        ax with unsigned constant to be added
  64. ; returns:    pointer with constant added
  65. ; consumes:    es, bx, f, ax
  66. ;
  67.     public    ladd
  68. ladd    proc    near
  69.     add    bx,ax        ; add in offset
  70.     jnc    ladd_exit    ; no carry, so we are done.
  71.     mov    ax,es
  72.     add    ax,1000h    ; add 64k of paragraphs
  73.     mov    es,ax        ; and store back to es
  74. ladd_exit:
  75.     ret
  76. ladd    endp
  77.  
  78. ;
  79. ; lsub:        subtract a constant from a long pointer
  80. ;
  81. ; expects:    es:bx with long pointer's original value
  82. ;        ax with unsigned constant to be subtracted
  83. ; returns:    pointer with constant subtracted
  84. ; consumes:    es, bx, f, ax
  85. ;
  86.     public    lsub
  87. lsub    proc    near
  88.     sub    bx,ax        ; subtract offset
  89.     jnb    lsub_exit    ; no borrow, so we are done.
  90.     mov    ax,es
  91.     sub    ax,1000h    ; subtract 64k of paragraphs
  92.     mov    es,ax        ; and store back to es
  93. lsub_exit:
  94.     ret
  95. lsub    endp
  96.  
  97. ;
  98. ; lsum:        add a signed offset to a long pointer
  99. ;
  100. ; expects:    es:bx with long pointer
  101. ;        ax with signed offset
  102. ; returns:    pointer with constant added (signed)
  103. ; consumes:    es, bx, f, ax
  104. ;
  105.     public    lsum
  106. lsum    proc    near
  107.     or    ax,ax        ; negative?
  108.     jm    lsum_neg
  109.     call    ladd        ; do addition
  110.     ret            ; and exit
  111. lsum_neg:
  112.     and    ax,07fffh    ; and out sign flag
  113.     jnz    lsum_neg_ok
  114.     mov    ax,8000h    ; -32768 value (don't treat as 0)
  115. lsum_neg_ok:
  116.     call    lsub
  117.     ret
  118. lsum    endp
  119.  
  120. ;
  121. ; lcopy:    copy from one long pointer to another,
  122. ;        up to 1024k bytes of data
  123. ;
  124. ; expects:    ds:si with src  address
  125. ;        es:di with dest address
  126. ;        ds|cx with length (dx is high order, cx is low order)
  127. ;        
  128. ; returns:    block copied
  129. ;        ds, es intact
  130. ; consumes:    ax, cx, f
  131. ;
  132. ;
  133. ;     this routine uses a copy downward method, to produce
  134. ;    correct copying for overlapping regions
  135. ;
  136.     public    lcopy
  137. lcopy    proc    near
  138.     ;
  139.     ; convert dx into segment form:
  140.     ;
  141.     push    dx        ; save original form of dx
  142.     push    cx        ; save low order of long count
  143.     and    dx,15        ; smallest meaningful value
  144.     xchg    dh,dl        ; switch upper and lower parts
  145.     mov    cl,4
  146.     shl    dh,cl        ; effect is shift left by 12 bits
  147.     pop    cx        ; and recover low order of long count
  148.     ;
  149.     mov    ax,es
  150.     add    ax,dx
  151.     mov    es,ax
  152.     mov    ax,ds
  153.     add    ax,dx
  154.     mov    ds,ax        ; gross adjustment of segments
  155.     pop    dx        ; recover original form of dx
  156.     ;    
  157.     add    di,cx        ; adjust dest. ptr to end of area
  158.     jnc    no_dest_adj    
  159.     mov    ax,es
  160.     add    ax,1000h    ; add offset
  161.     mov    es,ax        ; and store back to segment register
  162. no_dest_adj:
  163.     ;
  164.     ; do same work for source pointer:
  165.     ;
  166.     add    si,cx        ; do the addition
  167.     jnc    no_mor_adj    ; no more adjustment needed if no carry
  168.     mov    ax,ds
  169.     add    ax,1000h    ; do the adjustment
  170.     mov    ds,ax        ; and store back to ds
  171.     ;
  172.     ; at this stage: 
  173.     ;
  174.     ;    es:di is at the last byte of the dest. area
  175.     ;    ds:si is at the last byte of the src.  area
  176.     ;
  177. no_mor_adj:
  178.     std            ; set direction flag for moves
  179. lc_loop:
  180.     or    si,si        ; is si zero ?
  181.     lodsb             ; get byte ds:[si], decrement si
  182.     jnz    no_ds_adj    ; no need to adjust if non-zero at start
  183.     mov    ax,ds
  184.     sub    ax,1000h
  185.     mov    ds,ax        ; adjust pointer for next load
  186. no_ds_adj:
  187.     or    di,di        ; is di zero ?
  188.     stosb            ; set byte es:[di] = al, decrement di
  189.     jnz    no_es_adj    ; no need to adjust if non-zero at start
  190.     mov    ax,es
  191.     sub    ax,1000h    
  192.     mov    es,ax        ; adjust pointer for next store
  193. no_es_adj:
  194.     loop    lc_loop        ; copy whole block (--cx, jnz lc_loop)
  195.     dec    dx        ; work on outer loop
  196.     or    dx,dx
  197.     jnz    lc_loop        ; loop over dx counts too
  198.     ;
  199.     ; we are done
  200.     ;
  201.     inc    si
  202.     inc    di        ; restore to original calling values
  203.     ret            ; exit
  204. lcopy    endp
  205.  
  206. cseg    ends
  207.     end
  208.