📄 balib.s
字号:
movel a6@(ARG1),a0 /* source */ movel a6@(ARG2),a1 /* destination */ movel a6@(ARG3),d0 /* count */ /* * Find out if there is an overlap problem. * We have to copy backwards if destination lies within source, * i.e. ((destination - source) > 0 && < nbytes) */ movel a1,d1 /* destination */ subl a0,d1 /* - source */ jls cbFwd /* <= 0 means copy forward */ cmpl d0,d1 /* compare to nbytes */ jcs cbBak /* < nbytes means copy backwards */ /* Copy the whole thing forward, byte by byte */cbFwd: movel d0,d1 /* Set up d1 as the outer loop ctr */ swap d1 /* get upper word into dbra counter */ jra cbFwd3 /* do the test first */cbFwd1: movel #0xffff,d0 /* set to copy another 64K */cbFwd2: moveb a0@+,a1@+ /* move a byte */cbFwd3: dbra d0,cbFwd2 /* inner loop test */ dbra d1,cbFwd1 /* outer loop test */ unlk a6 rts /* Copy the whole thing backward, byte by byte */cbBak: addl d0,a0 /* make a0 point at end of from buffer*/ addl d0,a1 /* make a1 point at end of to buffer */ movel d0,d1 /* Set up d1 as the outer loop ctr */ swap d1 /* get upper word into dbra counter */ jra cbBak3 /* do the test first */cbBak1: movel #0xffff,d0 /* set to copy another 64K */cbBak2: moveb a0@-,a1@- /* move a byte */cbBak3: dbra d0,cbBak2 /* inner loop test */ dbra d1,cbBak1 /* outer loop test */ unlk a6 rts/********************************************************************************* bcopyWords - copy one buffer to another a word at a time** This routine copies the first `nwords' words from* `source' to `destination'.* It is similar to bcopy except that the copy is always performed* a word at a time. This may be desirable if one of the buffers* can only be accessed with word instructions, as in certain word-wide* memory-mapped peripherals. The source and destination must be word-aligned.** SEE ALSO: bcopy (2)** NOMANUAL - manual entry in bLib (1)* void bcopyWords (source, destination, nwords)* char * source; /* pointer to source buffer ** char * destination; /* pointer to destination buffer ** int nwords; /* number of words to copy **/_bcopyWords: link a6,#0 /* put src in a0, dest in a1, and count in d0 */ movel a6@(ARG1),a0 /* source */ movel a6@(ARG2),a1 /* destination */ movel a6@(ARG3),d0 /* count */ asll #1,d0 /* convert count to bytes */ /* * Find out if there is an overlap problem. * We have to copy backwards if destination lies within source, * i.e. ((destination - source) > 0 && < nbytes) */ movel a1,d1 /* destination */ subl a0,d1 /* - source */ jls cwFwd /* <= 0 means copy forward */ cmpl d0,d1 /* compare to nbytes */ jcs cwBak /* < nbytes means copy backwards */ /* Copy the whole thing forward, word by word */cwFwd: asrl #1,d0 /* convert count to words */ movel d0,d1 /* Set up d1 as the outer loop ctr */ swap d1 /* get upper word into dbra counter */ jra cwFwd3 /* do the test first */cwFwd1: movel #0xffff,d0 /* set to copy another 128K */cwFwd2: movew a0@+,a1@+ /* move a word */cwFwd3: dbra d0,cwFwd2 /* inner loop test */ dbra d1,cwFwd1 /* outer loop test */ unlk a6 rts /* Copy the whole thing backward, word by word */cwBak: addl d0,a0 /* make a0 point at end of from buffer*/ addl d0,a1 /* make a1 point at end of to buffer */ asrl #1,d0 /* convert count to words */ movel d0,d1 /* Set up d1 as the outer loop ctr */ swap d1 /* get upper word into dbra counter */ jra cwBak3 /* do the test first */cwBak1: movel #0xffff,d0 /* set to copy another 128K */cwBak2: movew a0@-,a1@- /* move a word */cwBak3: dbra d0,cwBak2 /* inner loop test */ dbra d1,cwBak1 /* outer loop test */ unlk a6 rts/********************************************************************************* bcopyLongs - copy one buffer to another a long at a time** This routine copies the first `nlongs' longs from* `source' to `destination'.* It is similar to bcopy except that the copy is always performed* a long at a time. This may be desirable if one of the buffers* can only be accessed with long instructions, as in certain long-wide* memory-mapped peripherals. The source and destination must be long-aligned.** SEE ALSO: bcopy (2)** NOMANUAL - manual entry in bLib (1)* void bcopyLongs (source, destination, nlongs)* char * source; /* pointer to source buffer ** char * destination; /* pointer to destination buffer ** int nlongs; /* number of longs to copy **/_bcopyLongs: link a6,#0 /* put src in a0, dest in a1, and count in d0 */ movel a6@(ARG1),a0 /* source */ movel a6@(ARG2),a1 /* destination */ movel a6@(ARG3),d0 /* count */ asll #2,d0 /* convert count to bytes */ /* * Find out if there is an overlap problem. * We have to copy backwards if destination lies within source, * i.e. ((destination - source) > 0 && < nbytes) */ movel a1,d1 /* destination */ subl a0,d1 /* - source */ jls clFwd /* <= 0 means copy forward */ cmpl d0,d1 /* compare to nbytes */ jcs clBak /* < nbytes means copy backwards */ /* Copy the whole thing forward, long by long */clFwd: asrl #2,d0 /* convert count to longs */ movel d0,d1 /* Set up d1 as the outer loop ctr */ swap d1 /* get upper word into dbra counter */ jra clFwd3 /* do the test first */clFwd1: movel #0xffff,d0 /* set to copy another 256K */clFwd2: movel a0@+,a1@+ /* move a long */clFwd3: dbra d0,clFwd2 /* inner loop test */ dbra d1,clFwd1 /* outer loop test */ unlk a6 rts /* Copy the whole thing backward, long by long */clBak: addl d0,a0 /* make a0 point at end of from buffer*/ addl d0,a1 /* make a1 point at end of to buffer */ asrl #2,d0 /* convert count to longs */ movel d0,d1 /* Set up d1 as the outer loop ctr */ swap d1 /* get upper word into dbra counter */ jra clBak3 /* do the test first */clBak1: movel #0xffff,d0 /* set to copy another 256K */clBak2: movel a0@-,a1@- /* move a long */clBak3: dbra d0,clBak2 /* inner loop test */ dbra d1,clBak1 /* outer loop test */ unlk a6 rts/********************************************************************************* bfill - fill buffer with character** This routine fills the first `nbytes' characters of the specified buffer* with the specified character.* The fill is optimized by filling 4 bytes at a time if possible,* (see bfillBytes (2) for filling a byte at a time only).** SEE ALSO: bfillBytes (2)** NOMANUAL - manual entry in bLib (1)* void bfill (buf, nbytes, ch)* char * buf; /* pointer to buffer ** int nbytes; /* number of bytes to fill ** char ch; /* char with which to fill buffer **/_bfill: link a6,#0 moveml d2-d3,a7@- /* save regs */ /* put buf in a0, nbytes in d0, and ch in d1 */ movel a6@(ARG1),a0 /* get buf */ movel a6@(ARG2),d0 /* nbytes */ movel a6@(ARG3),d1 /* ch */ /* if length is less than 20, cheaper to do a byte fill */ cmpl #20,d0 /* test count */ jcs fb5 /* do byte fill */ /* Put ch in all four bytes of d1, so we can fill 4 bytes at a crack */ moveb d1,d2 lslw #8,d1 /* move ch into 2nd byte of d1 */ orb d2,d1 /* or ch back into 1st byte of d1 */ movew d1,d2 swap d1 /* get ch-ch into high word of d1 */ orw d2,d1 /* or ch-ch back into low word of d1 */ /* If the buffer is odd-aligned, copy the first byte */ movew a0,d2 btst #0,d2 /* d2 has source */ jeq fb0 /* if even-aligned */ moveb d1,a0@+ /* copy the byte */ subl #1,d0 /* decrement count by 1 */ /* * Since we're copying 4 bytes at a crack, divide count by 4. * Keep the remainder in d0, so we can do those bytes at the * end of the loop. */fb0: movel d0,d3 andl #3,d0 /* remainder in d0 */ asrl #2,d3 /* count /= 4 */ /* * The fastest way to do the fill is with a dbra loop, but dbra * uses only a 16 bit counter. Therefore, break up count into * two pieces, to be used as an inner loop and an outer loop */ movel d3,d2 /* Set up d2 as the outer loop ctr */ swap d2 /* get upper word into dbra counter */ jra fb3 /* do the test first */fb1: movel #0xffff,d3 /* set to fill another 64K */fb2: movel d1,a0@+ /* move 4 bytes */fb3: dbra d3,fb2 /* inner loop test */ dbra d2,fb1 /* outer loop test */ /* do the extras at the end */ jra fb5 /* do the test first */fb4: moveb d1,a0@+ /* move 1 byte */fb5: dbra d0,fb4 /* inner loop test */ moveml a7@+,d2-d3 /* restore regs */ unlk a6 rts/********************************************************************************* bfillBytes - fill buffer with character a byte at a time** This routine fills the first `nbytes' characters of the* specified buffer with the specified character.* It is identical to bfill (2) except that the fill is always performed* a byte at a time. This may be desirable if the buffer* can only be accessed with byte instructions, as in certain byte-wide* memory-mapped peripherals.** SEE ALSO: bfill (2)** NOMANUAL - manual entry in bLib (1)* void bfillBytes (buf, nbytes, ch)* char * buf; /* pointer to buffer ** int nbytes; /* number of bytes to fill ** char ch; /* char with which to fill buffer **/_bfillBytes: link a6,#0 movel d2,a1 /* save d2 in a1 */ /* put src in a0, dest in a1, and count in d0 */ movel a6@(ARG1),a0 /* get destination */ movel a6@(ARG2),d0 /* count */ movel a6@(ARG3),d1 /* ch */ /* Copy the whole thing, byte by byte */ movel d0,d2 /* Set up d2 as the outer loop ctr */ swap d2 /* get upper word into dbra counter */ jra fby3 /* do the test first */fby1: movel #0xffff,d0 /* set to fill another 64K */fby2: moveb d1,a0@+ /* fill a byte */fby3: dbra d0,fby2 /* inner loop test */ dbra d2,fby1 /* outer loop test */ movel a1,d2 /* restore d2 */ unlk a6 rts#endif /* !PORTABLE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -