Unit MEM16; { Author: Paul VanderSpek Date: 03-20-1993 This source code is being released as Free-Ware. You may use this code in your Programs and modify it to fit your needs. The only restrictions are that you may not distribute the source code in modified Form or Charge For the source code itself. } Interface Procedure Move16(Var Source,Dest;Count:Word); Procedure FillChar16(Var X; Count: Word; Value:Byte); Implementation Procedure Move16(Var Source,Dest;Count:Word); Assembler; Asm PUSH DS LDS SI,SOURCE LES DI,DEST MOV AX,COUNT MOV CX,AX SHR CX,1 REP MOVSW TEST AX,1 JZ @end MOVSB @end:POP DS end; Procedure FillChar16(Var X; Count: Word; Value:Byte); Assembler; Asm LES DI,X MOV CX,COUNT SHR CX,1 MOV AL,ValUE MOV AH,AL REP StoSW TEST COUNT,1 JZ @end StoSB @end: end; end. { These routines are twice as fast as the normal Move and FillChar routines sInce they use MOVSW and StoSW instead of MOVSB and StoSB. They work in exactly the same way, so you can just replace Move and FillChar With them. } { > This source code is being released as Free-Ware. You may use > this code in your Programs and modify it to fit your needs. The > only restrictions are that you may not distribute the source > code in modified form or Charge For the source code itself. I'm sorry to say that I'm not impressed, since hundreds of people already have invented this wheel. Besides, your move routine has at least one serious flaw: it assumes that source and destinaton do not overlap. Which is not always the case; if you have a Variable of the Type String as the source, and you want to copy a few Characters furtheron in this Variable, you'll mess up the result. > SHR CX,1 > REP MOVSW > TEST AX,1 > JZ @end > MOVSB > @end:POP DS The TEST AX, 1 instruction is superfluous. If the number of Bytes in the CX register is odd, the SHR CX, 1 instruction will set the carry bit. It's more convenient to test this bit. Here's how: SHR CX, 1 JNC @1 MOVSB REP MOVSW @1: > Have Fun, No fun if source and destination overlap, as said earlier. Here follows a memory move routine With 16-bit moves and overlap check: } Procedure MoveMem(Var source, target; size : Word); Assembler; Asm PUSH DS LDS SI, source LES DI, target MOV CX, size CLD { If an overlap of source and target could occur, copy data backwards } CMP SI, DI JAE @2 ADD SI, CX ADD DI, CX DEC SI DEC DI STD SHR CX, 1 JAE @1 MOVSB @1: DEC SI DEC DI JMP @3 @2: SHR CX, 1 JNC @3 MOVSB @3: REP MOVSW POP DS end; { MoveMem } { > For I := 0 to 200 do > Move(Buffer,Mem[$A000:0000],320); Looks weird to me. Why moving all that stuff 200 times to the first line of the screen ? > For I := 100 to 200 do > Move(Buffer[320*I],Mem[$A000:(I*320)],320); This could be done via Move(Buffer[320*StartLine], Mem[$a000:320*StartLine], 320*NumberOfLines) ; which should somehow be faster. Also note that TP's Move Procedure Uses a LODSB instruction, which is twice as slow as a LODSW instruction on 286+ computers, With big buffers. So here is a replacement Move proc, which works fine EXCEPT if the two buffers overlap and destination is at a greater address than source, which anyway is not the Case here. } Procedure FastMove(Var Src, Dst ; Cnt : Word) ; Assembler ; Asm Mov DX, DS { Sauvegarde DS } Mov CX, Cnt LDS SI, Src LES DI, Dst ClD { A priori, on va du dbut vers la fin } ShR CX, 1 { On va travailler sur des mots } Rep MovSW { Copie des mots } JNC @Done { Pas d'octet restant (Cnt pair) ? } MovSB { Copie dernier octet } @Done: Mov DS, DX { Restauration DS } end ; { Well, just a note : this proc works twice faster than TP's Move _only_ if Src and Dst are Word aligned, which is the Case if : - they are Variables allocated on the heap, - they are declared in the stack, - $a+ is specified, - you use it as described in your examples of code :-) }