with Ada.Text_IO; use Ada.Text_IO;
with Turbo; use Turbo;
with Turbo.Memory; use Turbo.Memory;

with Debug_Dup_Output;

procedure Memory_Test is

   a12345 : aliased String := "1234567890";
   xyz : String (1 .. 3);
   for xyz'Address use a12345'Address + 3;

   b12345 : aliased String := "1234567890";
   xyz2 : aliased String := "xyz";

--   00001111222233334444
--              <<<<<<     Move
--   00001111222333344444
--      >>>>>>             Move
--   00000111122333344444
--           2222          Fill
--   00000111222233344444

   Cell_Size : constant := 8000;
   Shift_Size : constant := 60;

   Big_Buffer : aliased String (1 .. 5 * Cell_Size) :=
     (
       1                 ..     Cell_Size => '0',
       1 +     Cell_Size .. 2 * Cell_Size => '1',
       1 + 2 * Cell_Size .. 3 * Cell_Size => '2',
       1 + 3 * Cell_Size .. 4 * Cell_Size => '3',
       1 + 4 * Cell_Size .. 5 * Cell_Size => '4'
     );

   Reference_Buffer : constant String (1 .. 5 * Cell_Size) :=
     (
       1                              ..     Cell_Size + Shift_Size => '0',
       1 +     Cell_Size + Shift_Size .. 2 * Cell_Size + Shift_Size => '1',
       1 + 2 * Cell_Size + Shift_Size .. 3 * Cell_Size - Shift_Size => '2',
       1 + 3 * Cell_Size - Shift_Size .. 4 * Cell_Size - Shift_Size => '3',
       1 + 4 * Cell_Size - Shift_Size .. 5 * Cell_Size              => '4'
     );

   Big_Buffer_2 : String (1 .. 5 * Cell_Size) := Reference_Buffer;

   Reference_Buffer_2 : constant String (1 .. 5 * Cell_Size) :=
     (
       1                              ..     Cell_Size + Shift_Size => '0',
       1 +     Cell_Size + Shift_Size .. 2 * Cell_Size              => '1',
       1 + 2 * Cell_Size              .. 3 * Cell_Size              => '2',
       1 + 3 * Cell_Size              .. 4 * Cell_Size - Shift_Size => '3',
       1 + 4 * Cell_Size - Shift_Size .. 5 * Cell_Size              => '4'
     );

begin
   xyz := "xyz";
   if a12345 = "123xyz7890" then
      Put (".");
   else
      New_Line;
      Put_Line ("Check failed: xyz := ""xyz"";");
      Put_Line ("a12345 MUST be ""123xyz7890""");
      Put_Line ("a12345 IS """ & a12345 & """");
   end if;

   Move (xyz2'Address, b12345'Address + 3, 3);
   if b12345 = "123xyz7890" then
      Put (".");
   else
      New_Line;
      Put_Line ("Check failed: Move (xyz2'Address, b12345'Address + 3, 3);");
      Put_Line ("b12345 MUST be ""123xyz7890""");
      Put_Line ("b12345 IS """ & b12345 & """");
   end if;


   Move (Big_Buffer'Address + 3 * Cell_Size - Shift_Size,
         Big_Buffer'Address + 3 * Cell_Size - 2 * Shift_Size,
         Cell_Size + 2 * Shift_Size);

   Move (Big_Buffer'Address +     Cell_Size - Shift_Size,
         Big_Buffer'Address +     Cell_Size,
         Cell_Size + 2 * Shift_Size);

   if Big_Buffer = Reference_Buffer then
      Put (".");
   else
      New_Line;
      Put_Line ("Check failed: Memory.Move");
      Put ("Big_Buffer = "); Debug_Dup_Output (Big_Buffer); New_Line;
      Put ("Ref_Buffer = "); Debug_Dup_Output (Reference_Buffer); New_Line;
   end if;

   Fill_Byte (Big_Buffer_2'Address + 2 * Cell_Size, Cell_Size, Character'Pos ('2'));

   if Big_Buffer_2 = Reference_Buffer_2 then
      Put (".");
   else
      New_Line;
      Put_Line ("Check failed: Memory.Fill_Byte");
      Put ("Big_Buffer = "); Debug_Dup_Output (Big_Buffer_2); New_Line;
      Put ("Ref_Buffer = "); Debug_Dup_Output (Reference_Buffer_2); New_Line;
   end if;

end Memory_Test;
