+int Heap_int_ApplyWatchpont(void *Word, bool enabled)
+{
+ #if ARCHDIR_IS_x86
+ static void *active_wps[4];
+ unsigned int dr;
+ for( dr = 2; dr < 4; dr ++ )
+ {
+ if( (enabled && active_wps[dr] == NULL) || active_wps[dr] == Word)
+ break;
+ }
+ if(dr == 4) {
+ return 1;
+ }
+ if( enabled )
+ {
+ active_wps[dr] = Word;
+ switch(dr)
+ {
+ //case 0: ASM("mov %0, %%dr0" : : "r" (Word)); break;
+ //case 1: ASM("mov %0, %%dr1" : : "r" (Word)); break;
+ case 2: ASM("mov %0, %%dr2" : : "r" (Word)); break;
+ case 3: ASM("mov %0, %%dr3" : : "r" (Word)); break;
+ default: ASSERTC(dr,<,4); return 1;
+ }
+ }
+ else
+ {
+ active_wps[dr] = NULL;
+ }
+ Uint32 dr7flag;
+ ASM("MOV %%dr7, %0" : "=r" (dr7flag));
+ dr7flag &= ~(0x2 << (dr*2));
+ dr7flag &= ~(0xF000 << (dr*4));
+ if( enabled ) {
+ dr7flag |= 0x2 << (dr*2);
+ dr7flag |= 0xD000 << (dr*4); // 4 bytes, write
+ Debug("Heap_int_ApplyWatchpont: Watchpoint #%i %p ENABLED", dr, Word);
+ }
+ else {
+ Debug("Heap_int_ApplyWatchpont: Watchpoint #%i %p disabled", dr, Word);
+ }
+ ASM("MOV %0, %%dr7" : : "r" (dr7flag));
+ return 0;
+ #else
+ return 1;
+ #endif
+}
+
+void Heap_int_WatchBlock(tHeapHead *Head, bool Enabled)
+{
+ int rv;
+ rv = Heap_int_ApplyWatchpont( &Head->Size, Enabled );
+ //rv = Heap_int_ApplyWatchpont( &Head->Magic, Enabled );
+ rv = rv + Heap_int_ApplyWatchpont( &Heap_ThisFoot(Head)->Head, Enabled );
+ if(rv && Enabled) {
+ Warning("Can't apply watch on %p", Head);
+ }
+}
+
+int Heap_WatchBlock(void *Ptr)
+{
+ //Heap_int_ApplyWatchpont();
+ tHeapHead *head;
+ if((Uint)Ptr < (Uint)gHeapStart) return 0;
+ if((Uint)Ptr > (Uint)gHeapEnd) return 0;
+ if((Uint)Ptr & (sizeof(Uint)-1)) return 0;
+
+ head = (tHeapHead*)Ptr - 1;
+
+ Heap_int_WatchBlock( head, true );
+
+ return 0;
+}
+