home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / cbgi111 / src / lib / blt.asm next >
Encoding:
Assembly Source File  |  1990-06-15  |  15.4 KB  |  558 lines

  1. ;************************ BLT.ASM ****************************************
  2. ;  BLock Transfer functions.  These routines provide basic block transfer
  3. ; functions at a byte (really word) level.  They are optimised to do word
  4. ; aligned 16 bit transfers to the destination to take any advantage 
  5. ; possible performance increase a 16 bit bus might give (if it is 
  6. ; available).  This should not affect 8 bit adapters and buses 
  7. ; significantly.  
  8. ;  Note that the word alignment is on the destination of the transfer
  9. ; operation.  This is based on the assumption that the video adapter will
  10. ; usually be the destination rather than the source and since there are
  11. ; (almost always) more wait states for accessing the video memory there is
  12. ; a greater penalty for misaligned access to it.
  13. ;
  14. ;    V 1.00 17/04/90 R. Adsett  Original
  15. ;    V 1.01 23/04/90 R. Adsett  Remove header dependancies
  16. ;    V 1.02 15/06/90 R. Adsett  Eliminate DOSSEG ordering.
  17. ;
  18. ;  (C) Robert Adsett 1989, 1990
  19. ;*************************************************************************
  20.  
  21. ideal
  22. model tiny
  23.  
  24. codeseg
  25.  
  26. public    _copy_mem        ;Copy using a wrap on the source.
  27. public    _xor_mem        ;Xor the source with the destination using 
  28.                 ;  a wrap on the source.
  29. public    _or_mem            ;Or the source with the destination using 
  30.                 ;  a wrap on the source.
  31. public    _and_mem        ;And the source with the destination using 
  32.                 ;  a wrap on the source.
  33. public    _neg_mem        ;Copy the negated source using a wrap on 
  34.                 ;  the source.
  35. public    _set_mem        ;Set area to this value.  Note that it 
  36.                 ; treats 0 as 64K!!!!
  37.  
  38. ;********************** COPY_MEM *****************************************
  39. ;    Copy source to destination, wrapping the source as necessary to fill
  40. ; the destination.  
  41. ;    Prototype:
  42. ;    void copy_mem(
  43. ;        void far *source,    /* Source image.        */
  44. ;        unsigned src_size,    /* Number of bytes in source.    */
  45. ;        void far *destination,    /* Destination image.        */
  46. ;        unsigned dest_size    /* Number of bytes in the    */
  47. ;                    /*   destination.        */
  48. ;        );
  49. ;*************************************************************************
  50.  
  51. proc    _copy_mem
  52.  arg    source:dword, src_size:word, destination:dword, dest_size:word
  53.  
  54.      
  55.     push    bp
  56.     mov    bp,sp            ;Standard entry.
  57.  
  58.     push    ds            ;We're using all of these so save
  59.     push    si            ;  them.
  60.     push    di
  61.  
  62.     cld                ;Let's go forward.
  63.     les    di, [destination]    ;Load destination address.
  64.     mov    ax, [src_size]        ;Load size of source.
  65.     mov    bx, [dest_size]        ;Load size of destination.
  66.  
  67. copy_loop_top:                ;Top of copy loop.
  68.     lds    si, [source]        ;Load source address.
  69.     cmp    ax, bx            ;Compare source and destination 
  70.                     ;  sizes.
  71.     jl    small_src        ;Is source smaller?
  72.  
  73.     mov    cx, bx            ;Destination is smaller, copy
  74.                     ;  only that many bytes.
  75.     jmp    copy
  76.  
  77. small_src:
  78.     mov    cx, ax            ;Copy all of the source.
  79.  
  80. copy:
  81.     test    di, 1            ;Is destination on a word
  82.                     ;  boundary?
  83.     jz    copy_word        ;Yes.
  84.  
  85.     movsb                ;Let's get aligned.  Copy a single
  86.                     ;  byte.
  87.     dec    cx            ;One less in loop.
  88.     dec    bx            ;One less in total to copy.
  89.  
  90. copy_word:                ;Word aligned copy.
  91.     mov    dx, cx            ;Save copy of loop variable so we
  92.                     ;  can check for trailing bytes.
  93.     shr    cx, 1            ;How many words?
  94.     rep    movsw            ;Copy away.
  95.  
  96.     test    dx, 1            ;One last byte to copy?
  97.     jz    loop_end_test        ;Nope.
  98.  
  99.     movsb                ;Copy last byte.
  100.  
  101. loop_end_test:
  102.     sub    bx, dx            ;Copied all these bytes.
  103.     cmp    bx, 0            ;Is that all?
  104.     jne    copy_loop_top        ;Nope, restart at source's
  105.                     ;  beginning.
  106.  
  107.     pop    di            ;Restore important registers.
  108.     pop    si
  109.     pop    ds
  110.  
  111.     pop    bp            ;Standard exit.
  112.     ret
  113. endp
  114.  
  115. ;*********************** XOR_MEM *****************************************
  116. ;    Xor the source with the destination, wrapping the source as necessary 
  117. ; to fill the destination.  
  118. ;    Prototype:
  119. ;    void xor_mem(
  120. ;        void far *source,    /* Source image.        */
  121. ;        unsigned src_size,    /* Number of bytes in source.    */
  122. ;        void far *destination,    /* Destination image.        */
  123. ;        unsigned dest_size    /* Number of bytes in the    */
  124. ;                    /*   destination.        */
  125. ;        );
  126. ;*************************************************************************
  127.  
  128. proc    _xor_mem
  129.  arg    source:dword, src_size:word, destination:dword, dest_size:word
  130.  
  131.      
  132.     push    bp
  133.     mov    bp,sp            ;Standard entry.
  134.  
  135.     push    ds            ;We're using all of these so save
  136.     push    si            ;  them.
  137.     push    di
  138.  
  139.     cld                ;Let's go forward.
  140.     les    di, [destination]    ;Load destination address.
  141.     mov    bx, [dest_size]        ;Load size of destination.
  142.  
  143. cp_xor_loop_top:            ;Top of xor loop.
  144.     mov    ax, [src_size]        ;Load size of source.  This 
  145.                     ;  register gets reused.
  146.     lds    si, [source]        ;Load source address.
  147.     cmp    ax, bx            ;Compare source and destination 
  148.                           ;  sizes.
  149.     jl    cp_xor_small_src    ;Is source smaller?
  150.  
  151.     mov    cx, bx            ;Destination is smaller, xor
  152.                           ;  only that many bytes.
  153.     jmp    cp_xor
  154.  
  155. cp_xor_small_src:
  156.     mov    cx, ax            ;Xor all of the source.
  157.  
  158. cp_xor:
  159.     test    di, 1            ;Is destination on a word
  160.                          ;  boundary?
  161.     jz    cp_xor_word        ;Yes.
  162.  
  163.     ;Let's get aligned.  Xor a single byte.
  164.  
  165.     mov    al, [byte ptr ds:si]    ;Read single byte of source.
  166.     xor    [byte ptr es:di], al    ;Xor into destination.
  167.     inc    si            ;Next source byte.
  168.     inc    di            ;Next destination byte.
  169.     dec    cx            ;One less in loop.
  170.     dec    bx            ;One less in total to xor.
  171.  
  172. cp_xor_word:                ;Word aligned xor.
  173.     mov    dx, cx            ;Save copy of loop variable so we
  174.                           ;  can check for trailing bytes.
  175.     shr    cx, 1            ;How many words?
  176.  
  177. xor_loop:                ;Xor away.
  178.     mov    ax, [word ptr ds:si]    ;Read source word.
  179.     xor    [word ptr es:di], ax    ;Xor into destination.
  180.     inc    si            ;Next source word.
  181.     inc    si
  182.     inc    di            ;Next destination word.
  183.     inc    di
  184.     loop    xor_loop        ;Next word.
  185.  
  186.     test    dx, 1            ;One last byte to xor.
  187.     jz    cp_xor_loop_end_test    ;Nope.
  188.  
  189.     mov    al, [byte ptr ds:si]    ;Load and xor last byte.
  190.     xor    [byte ptr es:di], al
  191.     inc    si
  192.     inc    di
  193.  
  194. cp_xor_loop_end_test:
  195.     sub    bx, dx            ;Xor'd all these bytes.
  196.     cmp    bx, 0             ;Is that all?
  197.     jne    cp_xor_loop_top        ;Nope, restart at source's
  198.                            ;  beginning.
  199.  
  200.     pop    di            ;Restore important registers.
  201.     pop    si
  202.     pop    ds
  203.  
  204.     pop    bp            ;Standard exit.
  205.     ret
  206. endp
  207.  
  208. ;************************ OR_MEM *****************************************
  209. ;    Or the source with the destination, wrapping the source as necessary 
  210. ; to fill the destination.  
  211. ;    Prototype:
  212. ;    void or_mem(
  213. ;        void far *source,    /* Source image.        */
  214. ;        unsigned src_size,    /* Number of bytes in source.    */
  215. ;        void far *destination,    /* Destination image.        */
  216. ;        unsigned dest_size    /* Number of bytes in the    */
  217. ;                    /*   destination.        */
  218. ;        );
  219. ;*************************************************************************
  220.  
  221. proc    _or_mem
  222.  arg    source:dword, src_size:word, destination:dword, dest_size:word
  223.  
  224.      
  225.     push    bp
  226.     mov    bp,sp            ;Standard entry.
  227.  
  228.     push    ds            ;We're using all of these so save
  229.     push    si            ;  them.
  230.     push    di
  231.  
  232.     cld                ;Let's go forward.
  233.     les    di, [destination]    ;Load destination address.
  234.     mov    bx, [dest_size]        ;Load size of destination.
  235.  
  236. cp_or_loop_top:                ;Top of or loop.
  237.     mov    ax, [src_size]        ;Load size of source.  This 
  238.                     ;  register gets reused.
  239.     lds    si, [source]        ;Load source address.
  240.     cmp    ax, bx            ;Compare source and destination 
  241.                           ;  sizes.
  242.     jl    cp_or_small_src        ;Is source smaller?
  243.  
  244.     mov    cx, bx            ;Destination is smaller, or
  245.                           ;  only that many bytes.
  246.     jmp    cp_or
  247.  
  248. cp_or_small_src:
  249.     mov    cx, ax            ;Or all of the source.
  250.  
  251. cp_or:
  252.     test    di, 1            ;Is destination on a word
  253.                          ;  boundary?
  254.     jz    cp_or_word        ;Yes.
  255.  
  256.     ;Let's get aligned.  Or a single byte.
  257.  
  258.     mov    al, [byte ptr ds:si]    ;Read single byte of source.
  259.     or    [byte ptr es:di], al    ;Or into destination.
  260.     inc    si            ;Next source byte.
  261.     inc    di            ;Next destination byte.
  262.     dec    cx            ;One less in loop.
  263.     dec    bx            ;One less in total to or.
  264.  
  265. cp_or_word:                ;Word aligned or.
  266.     mov    dx, cx            ;Save copy of loop variable so we
  267.                           ;  can check for trailing bytes.
  268.     shr    cx, 1            ;How many words?
  269.  
  270. or_loop:                ;Or away.
  271.     mov    ax, [word ptr ds:si]    ;Read source word.
  272.     or    [word ptr es:di], ax    ;Or into destination.
  273.     inc    si            ;Next source word.
  274.     inc    si
  275.     inc    di            ;Next destination word.
  276.     inc    di
  277.     loop    or_loop            ;Next word.
  278.  
  279.     test    dx, 1            ;One last byte to or.
  280.     jz    cp_or_loop_end_test    ;Nope.
  281.  
  282.     mov    al, [byte ptr ds:si]    ;Load and or last byte.
  283.     or    [byte ptr es:di], al
  284.     inc    si
  285.     inc    di
  286.  
  287. cp_or_loop_end_test:
  288.     sub    bx, dx            ;Or'd all these bytes.
  289.     cmp    bx, 0             ;Is that all?
  290.     jne    cp_or_loop_top        ;Nope, restart at source's
  291.                            ;  beginning.
  292.  
  293.     pop    di            ;Restore important registers.
  294.     pop    si
  295.     pop    ds
  296.  
  297.     pop    bp            ;Standard exit.
  298.     ret
  299. endp
  300.  
  301. ;************************ AND_MEM ****************************************
  302. ;    And the source with the destination, wrapping the source as necessary 
  303. ; to fill the destination.  
  304. ;    Prototype:
  305. ;    void and_mem(
  306. ;        void far *source,    /* Source image.        */
  307. ;        unsigned src_size,    /* Number of bytes in source.    */
  308. ;        void far *destination,    /* Destination image.        */
  309. ;        unsigned dest_size    /* Number of bytes in the    */
  310. ;                    /*   destination.        */
  311. ;        );
  312. ;*************************************************************************
  313.  
  314. proc    _and_mem
  315.  arg    source:dword, src_size:word, destination:dword, dest_size:word
  316.  
  317.      
  318.     push    bp
  319.     mov    bp,sp            ;Standard entry.
  320.  
  321.     push    ds            ;We're using all of these so save
  322.     push    si            ;  them.
  323.     push    di
  324.  
  325.     cld                ;Let's go forward.
  326.     les    di, [destination]    ;Load destination address.
  327.     mov    bx, [dest_size]        ;Load size of destination.
  328.  
  329. cp_and_loop_top:            ;Top of and loop.
  330.     mov    ax, [src_size]        ;Load size of source.  This 
  331.                     ;  register gets reused.
  332.     lds    si, [source]        ;Load source address.
  333.     cmp    ax, bx            ;Compare source and destination 
  334.                           ;  sizes.
  335.     jl    cp_and_small_src    ;Is source smaller?
  336.  
  337.     mov    cx, bx            ;Destination is smaller, and
  338.                           ;  only that many bytes.
  339.     jmp    cp_and
  340.  
  341. cp_and_small_src:
  342.     mov    cx, ax            ;And all of the source.
  343.  
  344. cp_and:
  345.     test    di, 1            ;Is destination on a word
  346.                          ;  boundary?
  347.     jz    cp_and_word        ;Yes.
  348.  
  349.     ;Let's get aligned.  And a single byte.
  350.  
  351.     mov    al, [byte ptr ds:si]    ;Read single byte of source.
  352.     and    [byte ptr es:di], al    ;And into destination.
  353.     inc    si            ;Next source byte.
  354.     inc    di            ;Next destination byte.
  355.     dec    cx            ;One less in loop.
  356.     dec    bx            ;One less in total to and.
  357.  
  358. cp_and_word:                ;Word aligned and.
  359.     mov    dx, cx            ;Save copy of loop variable so we
  360.                           ;  can check for trailing bytes.
  361.     shr    cx, 1            ;How many words?
  362.  
  363. and_loop:                ;And away.
  364.     mov    ax, [word ptr ds:si]    ;Read source word.
  365.     and    [word ptr es:di], ax    ;And into destination.
  366.     inc    si            ;Next source word.
  367.     inc    si
  368.     inc    di            ;Next destination word.
  369.     inc    di
  370.     loop    and_loop        ;Next word.
  371.  
  372.     test    dx, 1            ;One last byte to and.
  373.     jz    cp_and_loop_end_test    ;Nope.
  374.  
  375.     mov    al, [byte ptr ds:si]    ;Load and and last byte.
  376.     and    [byte ptr es:di], al
  377.     inc    si
  378.     inc    di
  379.  
  380. cp_and_loop_end_test:
  381.     sub    bx, dx            ;And'd all these bytes.
  382.     cmp    bx, 0             ;Is that all?
  383.     jne    cp_and_loop_top        ;Nope, restart at source's
  384.                            ;  beginning.
  385.  
  386.     pop    di            ;Restore important registers.
  387.     pop    si
  388.     pop    ds
  389.  
  390.     pop    bp            ;Standard exit.
  391.     ret
  392. endp
  393.  
  394. ;************************ NEG_MEM ****************************************
  395. ;    Binary invert source and copy to the destination, wrapping the source
  396. ; as necessary to fill the destination.  Does not actually modify the 
  397. ; source, so that the calling routine does not have to protect the source.
  398. ;    Prototype:
  399. ;    void neg_mem(
  400. ;        void far *source,    /* Source image.        */
  401. ;        unsigned src_size,    /* Number of bytes in source.    */
  402. ;        void far *destination,    /* Destination image.        */
  403. ;        unsigned dest_size    /* Number of bytes in the    */
  404. ;                    /*   destination.        */
  405. ;        );
  406. ;*************************************************************************
  407.  
  408. proc    _neg_mem
  409.  arg    source:dword, src_size:word, destination:dword, dest_size:word
  410.  
  411.      
  412.     push    bp
  413.     mov    bp,sp            ;Standard entry.
  414.  
  415.     push    ds            ;We're using all of these so save
  416.     push    si            ;  them.
  417.     push    di
  418.  
  419.     cld                ;Let's go forward.
  420.     les    di, [destination]    ;Load destination address.
  421.     mov    bx, [dest_size]        ;Load size of destination.
  422.  
  423. cp_neg_loop_top:            ;Top of neg loop.
  424.     mov    ax, [src_size]        ;Load size of source.  This 
  425.                     ;  register gets reused.
  426.     lds    si, [source]        ;Load source address.
  427.     cmp    ax, bx            ;Compare source neg destination 
  428.                           ;  sizes.
  429.     jl    cp_neg_small_src    ;Is source smaller?
  430.  
  431.     mov    cx, bx            ;Destination is smaller, neg
  432.                           ;  only that many bytes.
  433.     jmp    cp_neg
  434.  
  435. cp_neg_small_src:
  436.     mov    cx, ax            ;Neg all of the source.
  437.  
  438. cp_neg:
  439.     test    di, 1            ;Is destination on a word
  440.                          ;  boundary?
  441.     jz    cp_neg_word        ;Yes.
  442.  
  443.     ;Let's get aligned.  Neg a single byte.
  444.  
  445.     mov    al, [byte ptr ds:si]    ;Read single byte of source.
  446.     neg    al            ;Negate the byte.
  447.     mov    [byte ptr es:di], al    ;Copy to destination.
  448.     inc    si            ;Next source byte.
  449.     inc    di            ;Next destination byte.
  450.     dec    cx            ;One less in loop.
  451.     dec    bx            ;One less in total to neg.
  452.  
  453. cp_neg_word:                ;Word aligned neg.
  454.     mov    dx, cx            ;Save copy of loop variable so we
  455.                           ;  can check for trailing bytes.
  456.     shr    cx, 1            ;How many words?
  457.  
  458. neg_loop:                ;Neg away.
  459.     mov    ax, [word ptr ds:si]    ;Read source word.
  460.     neg    ax            ;Negate word.
  461.     mov    [word ptr es:di], ax    ;Copy to destination.
  462.     inc    si            ;Next source word.
  463.     inc    si
  464.     inc    di            ;Next destination word.
  465.     inc    di
  466.     loop    neg_loop        ;Next word.
  467.  
  468.     test    dx, 1            ;One last byte to neg.
  469.     jz    cp_neg_loop_end_test    ;Nope.
  470.  
  471.     mov    al, [byte ptr ds:si]    ;Load neg and last byte.
  472.     neg    al
  473.     mov    [byte ptr es:di], al
  474.     inc    si
  475.     inc    di
  476.  
  477. cp_neg_loop_end_test:
  478.     sub    bx, dx            ;Neg'd all these bytes.
  479.     cmp    bx, 0             ;Is that all?
  480.     jne    cp_neg_loop_top        ;Nope, restart at source's
  481.                            ;  beginning.
  482.  
  483.     pop    di            ;Restore important registers.
  484.     pop    si
  485.     pop    ds
  486.  
  487.     pop    bp            ;Standard exit.
  488.     ret
  489. endp
  490.  
  491. ;************************ SET_MEM ****************************************
  492. ;    Set memory to value.  Assumes lower byte is mapped into higher byte.
  493. ; NOTE:!!!!!!! If the number of bytes to set is zero, then 64K will be
  494. ; set.  This is NOT intutive but it is the only way the string 
  495. ; instructions will modify 64K.  This is also the only 'blt' instruction
  496. ; for which this matters.  None of the others should ever need to deal
  497. ; with a block that large.
  498. ;    Prototype:
  499. ;    void set_mem(
  500. ;        void far *destination,    /* Destination image.        */
  501. ;        unsigned dest_size,    /* Number of bytes in the    */
  502. ;                    /*   destination.        */
  503. ;        unsigned value        /* Value to set words/bytes to.    */
  504. ;        );
  505. ;*************************************************************************
  506.  
  507. proc    _set_mem
  508.  arg    destination:dword, dest_size:word, value:word
  509.  
  510.      
  511.     push    bp
  512.     mov    bp,sp            ;Standard entry.
  513.     push    di            ;Save this register, we're using
  514.                     ;  it.
  515.  
  516.     cld                ;Let's go forward.
  517.     mov    ax, [word value]    ;Value to set memory to.
  518.     les    di, [destination]    ;Load destination address.
  519.     mov    cx, [dest_size]         ;Load size of destination.
  520.  
  521.     loop    set_first_byte        ;Prepare to set first byte.  If
  522.                     ;  cx is 0, it will be set to
  523.                     ;  0xffff so that a full 64K will
  524.                     ;  be set.  Sheesh, the lengths
  525.                     ;  we go to ;)
  526.  
  527. set_first_byte:
  528.     stosb                ;Set first byte to value.
  529.  
  530.     test    di, 1            ;Is the remaining word aligned?
  531.     jz    set_word
  532.  
  533.     loop    set_second_byte        ;Nope, make it so.
  534.  
  535. set_second_byte:
  536.     stosb                ;Set second byte to value.
  537.  
  538. set_word:                ;Set word aligned.
  539.     mov    dx, cx            ;Save count to identify trailing
  540.                     ;  bytes.
  541.     shr    cx, 1            ;Number of words to set.
  542.  
  543.     rep    stosw            ;Set them all.
  544.  
  545.     test    dx, 1            ;One byte left?
  546.     jz    set_end            ;Nope
  547.  
  548.     stosb                ;Set last byte.
  549.  
  550. set_end:
  551.     pop    di            ;Restore register.
  552.  
  553.     pop    bp            ;Standard exit.
  554.     ret
  555. endp
  556.  
  557. end
  558.