Yeah, for each individual tile making undo / redo seems easy, but if user makes lots of changes, then he must wait alot before undo reaches the stage where he started to draw these tiles.
I tried and its very slow.

Its better to create group of undos.
And i have found idea to create stack_of_[tile+tile_coord]_lists

In c++ something like this: stack< list<unsigned long> > undolist;
Actually instead if unsigned long there was a simple struct (record) which just contains tile_id and its XYZ coordinate.
This way each modification is actually a group. Pop a list from stack, loop through each of its item, get XYZ and tile ID. Put these tile_ids back at these XYZ coords on map. And do this for each LIST item in stack.

Atm im trying to implement this system. Undo first.
Dunno how to do this in Delphi without generics but i will try this in a DLL again.
I already can successfully receive and send block_data to / from C++ DLL.