I can not decipher your code without runnable version to test, but here is the last version of my playing with my Lazarus code. It has not all pieces and only rotation hard coded in procedure without shadowing the current buffer for collision detection.
I attach that as zip file.
Maybe you like this, so you do not worry about shadowing the screen contents (from Turbo Pascal FAQ):
Q: How can I read a text character from the screen (e.g. xy 5,2)?
A: The code for the task is given below
Uses Dos;
(* Read an individual character from the screen *)
function VDCHXYFN (column, row : byte) : char;
var regs : registers;
videocolumns : byte;
videobase : word;
offset : word;
begin
{ Get the video base address }
FillChar (regs, SizeOf(regs), 0);
regs.ah := $0F; Intr ($10, regs);
if regs.al = 7 then videobase := $B000 else videobase := $B800;
{}
{ Get the screen width }
FillChar (regs, SizeOf(regs), 0);
regs.ah := $0F;
Intr ($10, regs);
videocolumns := regs.ah;
{}
{ Get the character }
offset := (((row-1)*videocolumns)+(column-1))*2;
vdchxyfn := chr(mem[videobase:offset]);
end; (* vdchxyfn *)
begin
writeln ('Character at 5, 2 is ascii ', Ord(VDCHXYFN(5,2)));
end.
--------------------------------------------------------------------