Browse Source

+ accelerated xor/and/orput hline routines for the 16bpp linear framebuffer modes

git-svn-id: trunk@40888 -
nickysn 6 years ago
parent
commit
d7d9588569
2 changed files with 128 additions and 4 deletions
  1. 108 0
      packages/graph/src/go32v2/graph.pp
  2. 20 4
      packages/graph/src/go32v2/vesa.inc

+ 108 - 0
packages/graph/src/go32v2/graph.pp

@@ -200,6 +200,114 @@ const
 {$endif fpc}
 {$endif fpc}
    end ['EAX'];
    end ['EAX'];
 
 
+  procedure seg_xorword(segment : word;ofs : longint;count : longint;w : word);
+    begin
+      asm
+         push edi
+         mov edi, [ofs]
+         mov ecx, [count]
+         movzx edx, word ptr [w]
+         { load segment }
+         push es
+         mov ax, [segment]
+         mov es, ax
+         { fill eax }
+         mov eax, edx
+         shl eax, 16
+         or eax, edx
+         test edi, 3
+         jz @@aligned
+         xor word ptr es:[edi], ax
+         add edi, 2
+         dec ecx
+         jz @@done
+@@aligned:
+         mov edx, ecx
+         shr ecx, 1
+@@lp:    xor dword ptr es:[edi], eax
+         add edi, 4
+         dec ecx
+         jnz @@lp
+         test edx, 1
+         jz @@done
+         xor word ptr es:[edi], ax
+@@done:  pop es
+         pop edi
+      end;
+    end;
+
+  procedure seg_orword(segment : word;ofs : longint;count : longint;w : word);
+    begin
+      asm
+         push edi
+         mov edi, [ofs]
+         mov ecx, [count]
+         movzx edx, word ptr [w]
+         { load segment }
+         push es
+         mov ax, [segment]
+         mov es, ax
+         { fill eax }
+         mov eax, edx
+         shl eax, 16
+         or eax, edx
+         test edi, 3
+         jz @@aligned
+         or word ptr es:[edi], ax
+         add edi, 2
+         dec ecx
+         jz @@done
+@@aligned:
+         mov edx, ecx
+         shr ecx, 1
+@@lp:    or dword ptr es:[edi], eax
+         add edi, 4
+         dec ecx
+         jnz @@lp
+         test edx, 1
+         jz @@done
+         or word ptr es:[edi], ax
+@@done:  pop es
+         pop edi
+      end;
+    end;
+
+  procedure seg_andword(segment : word;ofs : longint;count : longint;w : word);
+    begin
+      asm
+         push edi
+         mov edi, [ofs]
+         mov ecx, [count]
+         movzx edx, word ptr [w]
+         { load segment }
+         push es
+         mov ax, [segment]
+         mov es, ax
+         { fill eax }
+         mov eax, edx
+         shl eax, 16
+         or eax, edx
+         test edi, 3
+         jz @@aligned
+         and word ptr es:[edi], ax
+         add edi, 2
+         dec ecx
+         jz @@done
+@@aligned:
+         mov edx, ecx
+         shr ecx, 1
+@@lp:    and dword ptr es:[edi], eax
+         add edi, 4
+         dec ecx
+         jnz @@lp
+         test edx, 1
+         jz @@done
+         and word ptr es:[edi], ax
+@@done:  pop es
+         pop edi
+      end;
+    end;
+
 {************************************************************************}
 {************************************************************************}
 {*                   720x348x2 Hercules mode routines                   *}
 {*                   720x348x2 Hercules mode routines                   *}
 {************************************************************************}
 {************************************************************************}

+ 20 - 4
packages/graph/src/go32v2/vesa.inc

@@ -1807,11 +1807,27 @@ end;
     LogLn('Offs: '+strf(offs)+' -- '+hexstr(offs,8));
     LogLn('Offs: '+strf(offs)+' -- '+hexstr(offs,8));
     {$endif logging2}
     {$endif logging2}
     case CurrentWriteMode of
     case CurrentWriteMode of
-      AndPut,
-      XorPut,
+      XorPut:
+        begin
+          if UseNoSelector then
+            seg_xorword(get_ds,PtrUInt(LFBPointer)+PtrUInt(offs)+PtrUInt(LinearPageOfs),HLength,Word(CurrentColor))
+          else
+            seg_xorword(WinWriteSeg,offs+LinearPageOfs,HLength,Word(CurrentColor));
+        end;
       OrPut:
       OrPut:
-        { todo: optimized And/Xor/Or put }
-        HLineDefault(x-StartXViewPort,x2-StartXViewPort,y-StartYViewPort);
+        begin
+          if UseNoSelector then
+            seg_orword(get_ds,PtrUInt(LFBPointer)+PtrUInt(offs)+PtrUInt(LinearPageOfs),HLength,Word(CurrentColor))
+          else
+            seg_orword(WinWriteSeg,offs+LinearPageOfs,HLength,Word(CurrentColor));
+        end;
+      AndPut:
+        begin
+          if UseNoSelector then
+            seg_andword(get_ds,PtrUInt(LFBPointer)+PtrUInt(offs)+PtrUInt(LinearPageOfs),HLength,Word(CurrentColor))
+          else
+            seg_andword(WinWriteSeg,offs+LinearPageOfs,HLength,Word(CurrentColor));
+        end;
       NormalPut:
       NormalPut:
         begin
         begin
           if UseNoSelector then
           if UseNoSelector then