Date: Mon, 3 Aug 92 02:50:34 -0500 From: rcharif AT math DOT utexas DOT edu Posted-Date: Mon, 3 Aug 92 02:50:34 -0500 To: dj AT ctron DOT com Cc: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: BUG in paging patch Reply-To: rcharif AT math DOT utexas DOT edu I am terribly sorry but I just discovered a bug in the modification that rendered the current eip skip routine useless. This has been corrected and a new version of the files is on math.utexas.edu. (See previous message). And again sorry for the inconvenience. Here is the diff again -------------- CUT HERE ---------------------------- diff -c3 orig/build.h a/build.h *** orig/build.h Mon Aug 3 01:15:32 1992 --- a/build.h Sun Aug 2 20:42:40 1992 *************** *** 13,15 **** --- 13,30 ---- */ /* moved to makefile */ + + #ifdef DEBUG_ON + + static char *_pFileName = __FILE__; + + extern unsigned long fDebug; + #define DEBUG(n) if (fDebug & n) + + #define DEBUG_POUT 1 + #define DEBUG_PIN 2 + #define DEBUG_POUT_DATA_DIRTY 4 + #define DEBUG_POUT_DISCARD 8 + #define DEBUG_SKIP_EIP 16 + + #endif diff -c3 orig/control.c a/control.c *** orig/control.c Tue Jul 7 17:29:14 1992 --- a/control.c Sun Aug 2 23:16:38 1992 *************** *** 38,43 **** --- 38,47 ---- extern transfer_buffer[]; extern word32 transfer_linear; + #ifdef DEBUG + unsigned long fDebug = 0; // Debug messages mask, see build.h + #endif + TSS *tss_ptr; int debug_mode = 0; int self_contained; *************** *** 186,192 **** --- 190,200 ---- usage(char *s) { + #ifdef DEBUG + printf("Usage: %s [-debug ] [program [options . . . ]]\n", s); + #else printf("Usage: %s [program [options . . . ]]\n", s); + #endif _exit(1); } *************** *** 350,355 **** --- 358,373 ---- if (emu_fn) free(emu_fn); emu_fn = strdup(val); } + else if (stricmp(sw, "debug") == 0) { + + if (!strcmpi(val, "all")) + fDebug = 0xffffffffL; + else + sscanf(val, "%li", (unsigned long *)&fDebug); + + printf("\nMessage Debugging enabled in go32 environment variable. Flag value = %lx\n" + , fDebug); + } } #if ! DEBUGGER #if ! TOPLINEINFO *************** *** 447,452 **** --- 465,485 ---- argc--; } + #ifdef DEBUG + // set debug flags. syntaxe go32 [-debug ] pgm_name + if (!strncmpi(argv[1], "-debug", 6)) { + + if (!strcmpi(argv[2], "all")) + fDebug = 0xffffffffL; + else + sscanf(argv[2], "%li", (unsigned long *)&fDebug); + + argv += 2; + argc -= 2; + printf("\nMessage Debugging enabled. Flag value = %lx\n", fDebug); + } + #endif + #if TOPLINEINFO for (i=0; i<80; i++) poke(screen_seg, i*2, 0x0720); *************** *** 490,496 **** *path = 0; if (stat(argv0, &stbuf)) /* not found */ { ! fprintf(stderr, "%s.exe version 1.07 Copyright (C) 1991 DJ Delorie\n", argv0); debug_mode = 1; if (argv[1] == 0) --- 523,529 ---- *path = 0; if (stat(argv0, &stbuf)) /* not found */ { ! fprintf(stderr, "%s.exe version 1.07 Copyright (C) 1991 DJ Delorie\n\r", argv0); debug_mode = 1; if (argv[1] == 0) diff -c3 orig/makefile a/makefile *** orig/makefile Sat Aug 1 19:58:24 1992 --- a/makefile Sun Aug 2 18:22:34 1992 *************** *** 1,16 **** # History:25,17 AFLAGS = /mx /zi /zd ! CFLAGS = -ms -M .c.obj: ! tcc $(CFLAGS) -DDEBUGGER=1 -DTOPLINEINFO=1 -DSOURCE_LIST -c $* ! -mv $*.obj d$*.obj ! tcc $(CFLAGS) -DDEBUGGER=0 -DTOPLINEINFO=1 -c $* .asm.obj: ! tasm $(AFLAGS) /DDEBUGGER=1 /DTOPLINEINFO=1 $*; ! mv $*.obj d$*.obj tasm $(AFLAGS) /DDEBUGGER=0 /DTOPLINEINFO=1 $*; OBJS =\ --- 1,16 ---- # History:25,17 AFLAGS = /mx /zi /zd ! CFLAGS = -ms -M -DVERBOSE=0 -DDEBUG_ON .c.obj: ! # bcc $(CFLAGS) -DDEBUGGER=1 -DTOPLINEINFO=1 -DSOURCE_LIST -c $*.c ! # -mv $*.obj d$*.obj ! bcc $(CFLAGS) -DDEBUGGER=0 -DTOPLINEINFO=1 -c $*.c .asm.obj: ! # tasm $(AFLAGS) /DDEBUGGER=1 /DTOPLINEINFO=1 $*; ! # -mv $*.obj d$*.obj tasm $(AFLAGS) /DDEBUGGER=0 /DTOPLINEINFO=1 $*; OBJS =\ *************** *** 37,43 **** xms.obj\ vcpi.obj ! all : go32t.exe stub.exe aout2exe.exe exe2aout.exe stub.exe: stub.c tcc stub.c --- 37,44 ---- xms.obj\ vcpi.obj ! all : go32.exe ! # stub.exe aout2exe.exe exe2aout.exe stub.exe: stub.c tcc stub.c *************** *** 44,52 **** tdstrip stub # Note: some tlinks require /3 here, some barf if you supply it. ! go32t.exe : $(OBJS) go32.lnk tlink /3 /l /c /v /s /m @go32.lnk ! tlink /3 /l /c /v /s /m @debug32.lnk bin2byte.exe : bin2byte.c tcc bin2byte.c --- 45,53 ---- tdstrip stub # Note: some tlinks require /3 here, some barf if you supply it. ! go32.exe : $(OBJS) go32.lnk tlink /3 /l /c /v /s /m @go32.lnk ! # tlink /3 /l /c /v /s /m @debug32.lnk bin2byte.exe : bin2byte.c tcc bin2byte.c *************** *** 65,91 **** # DEPENDENCIES ! debug.obj : build.h types.h gdt.h tss.h utils.h unassmbl.h syms.h paging.h npx.h mono.h eventque.h ! exphdlr.obj : build.h types.h gdt.h idt.h tss.h utils.h paging.h npx.h mono.h vcpi.h eventque.h ! control.obj : build.h types.h gdt.h idt.h tss.h valloc.h utils.h syms.h graphics.h mono.h vcpi.h ! graphics.obj : build.h types.h paging.h graphics.h tss.h gdt.h driver.h ! paging.obj : build.h types.h paging.h graphics.h tss.h idt.h gdt.h valloc.h dalloc.h utils.h aout.h mono.h vcpi.h ! syms.obj : build.h types.h syms.h tss.h stab.h stab.def aout.h utils.h ! unassmbl.obj : build.h types.h gdt.h idt.h tss.h utils.h unassmbl.h syms.h mono.h ! utils.obj : build.h types.h tss.h gdt.h utils.h npx.h ! valloc.obj : build.h types.h valloc.h xms.h mono.h vcpi.h xms.obj : xms.h ! dalloc.obj : build.h types.h valloc.h dalloc.h mono.h mono.obj : mono.h --- 66,92 ---- # DEPENDENCIES ! debug.obj : types.h gdt.h tss.h utils.h unassmbl.h syms.h paging.h npx.h mono.h eventque.h ! exphdlr.obj : types.h gdt.h idt.h tss.h utils.h paging.h npx.h mono.h vcpi.h eventque.h ! control.obj : types.h gdt.h idt.h tss.h valloc.h utils.h syms.h graphics.h mono.h vcpi.h ! graphics.obj : types.h paging.h graphics.h tss.h gdt.h driver.h ! paging.obj : types.h paging.h graphics.h tss.h idt.h gdt.h valloc.h dalloc.h utils.h aout.h mono.h vcpi.h ! syms.obj : types.h syms.h tss.h stab.h stab.def aout.h utils.h ! unassmbl.obj : types.h gdt.h idt.h tss.h utils.h unassmbl.h syms.h mono.h ! utils.obj : types.h tss.h gdt.h utils.h npx.h ! valloc.obj : types.h valloc.h xms.h mono.h vcpi.h xms.obj : xms.h ! dalloc.obj : types.h valloc.h dalloc.h mono.h mono.obj : mono.h Only in orig: modi diff -c3 orig/paging.c a/paging.c *** orig/paging.c Tue Jul 7 17:29:16 1992 --- a/paging.c Mon Aug 3 01:05:48 1992 *************** *** 34,40 **** #include "mono.h" #include "vcpi.h" ! #define VERBOSE 0 #if DEBUGGER --- 34,40 ---- #include "mono.h" #include "vcpi.h" ! //#define VERBOSE 0 #if DEBUGGER *************** *** 556,561 **** --- 556,578 ---- dread(paging_buffer, dblock); dfree(dblock); memput(vaddr, paging_buffer, 4096); + pt[pti] &= ~(word32)(PT_A | PT_D); // clean dirty an accessed bits (set by memput) + #ifdef DEBUG + DEBUG(DEBUG_POUT) { + + printf("\nPaging In %lx, flags = ", vaddr); + + printf("%c", (pt[pti] & PT_C) ? 'C' : ' '); + printf("%c", (pt[pti] & PT_S) ? 'S' : ' '); + printf("%c", (pt[pti] & PT_I) ? 'I' : ' '); + printf("%c", (pt[pti] & PT_D) ? 'D' : ' '); + printf("%c", (pt[pti] & PT_A) ? 'A' : ' '); + printf("%c", (pt[pti] & PT_U) ? 'U' : ' '); + printf("%c", (pt[pti] & PT_W) ? 'W' : ' '); + printf("%c", (pt[pti] & PT_P) ? 'P' : ' '); + printf("---"); + } + #endif } else { *************** *** 603,608 **** --- 620,642 ---- if (zaddr != -1) zero32(zaddr); memput(vtran, paging_buffer, vcnt); + pt[pti] &= ~(word32)(PT_A | PT_D); // clean dirty and accessed bits (set by memput) + #ifdef DEBUG + DEBUG(DEBUG_PIN) { + + printf("\nReading %lx, flags = ", vtran); + + printf("%c", (pt[pti] & PT_C) ? 'C' : ' '); + printf("%c", (pt[pti] & PT_S) ? 'S' : ' '); + printf("%c", (pt[pti] & PT_I) ? 'I' : ' '); + printf("%c", (pt[pti] & PT_D) ? 'D' : ' '); + printf("%c", (pt[pti] & PT_A) ? 'A' : ' '); + printf("%c", (pt[pti] & PT_U) ? 'U' : ' '); + printf("%c", (pt[pti] & PT_W) ? 'W' : ' '); + printf("%c", (pt[pti] & PT_P) ? 'P' : ' '); + printf("---"); + } + #endif } #if VERBOSE printf("\n"); *************** *** 614,619 **** --- 648,655 ---- return 0; } + static fInPageOutEverything = 0; + static last_po_pdi = 0; static last_po_pti = 0; static last_pti = 0; *************** *** 631,686 **** if (where == VA_640) { for (pti = last_pti+1; pti != last_pti; pti = (pti+1)%1024) ! if ((vcpi_pt[pti] & (PT_P | PT_S)) == (PT_P | PT_S)) ! { ! dblock = dalloc(); ! memcpy(paging_buffer, (void far *)(pti << 24), 4096); ! dwrite(paging_buffer, dblock); ! #if VERBOSE ! printf ("out_640 %d\n", pti); #endif - vcpi_pt[pti] &= 0xfff & ~PT_P; /* no longer present */ - vcpi_pt[pti] |= (long)dblock << 12; #if TOPLINEINFO ! update_status(old_status, 79); #endif ! last_pti = pti; ! return pti; ! } return -1; } pt = (word32 far *)((word32)(pd_seg[last_po_pdi]) << 24); ! do { ! if ((pd[last_po_pdi] & (PT_P | PT_S)) == (PT_P | PT_S)) ! { ! if ((pt[last_po_pti] & (PT_P | PT_S)) == (PT_P | PT_S)) ! { ! rv = pt[last_po_pti] >> 12; ! dblock = dalloc(); ! v = ((word32)last_po_pdi << 22) | ((word32)last_po_pti << 12); ! memget(v, paging_buffer, 4096); ! dwrite(paging_buffer, dblock); #if VERBOSE ! printf ("out %d:%d\r", last_po_pdi, last_po_pti); #endif ! pt[last_po_pti] &= 0xfff & ~PT_P; /* no longer present */ ! pt[last_po_pti] |= (long)dblock << 12; #if TOPLINEINFO ! update_status(old_status, 79); #endif ! return rv; ! } ! } ! else /* imagine we just checked the last entry */ ! last_po_pti = 1023; ! if (++last_po_pti == 1024) ! { ! last_po_pti = 0; ! if (++last_po_pdi == 1024) ! last_po_pdi = 0; ! pt = (word32 far *)((word32)(pd_seg[last_po_pdi]) << 24); ! } ! } while ((start_pdi != last_po_pdi) || (start_pti != last_po_pti)); #if TOPLINEINFO update_status(old_status, 79); #endif --- 667,927 ---- if (where == VA_640) { for (pti = last_pti+1; pti != last_pti; pti = (pti+1)%1024) ! if ((vcpi_pt[pti] & (PT_P | PT_S)) == (PT_P | PT_S)) { ! ! dblock = dalloc(); ! memcpy(paging_buffer, (void far *)(pti << 24), 4096); ! dwrite(paging_buffer, dblock); ! vcpi_pt[pti] &= 0xfff & ~PT_P; /* no longer present */ ! vcpi_pt[pti] |= (long)dblock << 12; ! ! #if TOPLINEINFO ! { ! register int i; ! char *pStr = "POut640"; ! for (i=0; pStr[i]; i++) ! poke(screen_seg, i*2+50, pStr[i] | 0x0600); ! } ! #endif ! #ifdef DEBUG ! DEBUG(DEBUG_POUT) { ! printf("\nPaging out 640 %lx, flags = ", ((word32)pti << 12)); ! ! printf("%c", (vcpi_pt[pti] & PT_C) ? 'C' : ' '); ! printf("%c", (vcpi_pt[pti] & PT_S) ? 'S' : ' '); ! printf("%c", (vcpi_pt[pti] & PT_I) ? 'I' : ' '); ! printf("%c", (vcpi_pt[pti] & PT_D) ? 'D' : ' '); ! printf("%c", (vcpi_pt[pti] & PT_A) ? 'A' : ' '); ! printf("%c", (vcpi_pt[pti] & PT_U) ? 'U' : ' '); ! printf("%c", (vcpi_pt[pti] & PT_W) ? 'W' : ' '); ! printf("%c", (vcpi_pt[pti] & PT_P) ? 'P' : ' '); ! printf("---"); ! } #endif #if TOPLINEINFO ! update_status(old_status, 79); #endif ! last_pti = pti; ! return pti; ! } return -1; } pt = (word32 far *)((word32)(pd_seg[last_po_pdi]) << 24); ! ! ! do { ! if ((pd[last_po_pdi] & (PT_P | PT_S)) == (PT_P | PT_S)) { ! ! // ! // Don't page out around current instruction ! // UNLESS if paging out everything. ! // Take a limit of +-4 pages ! // ! v = ((word32)last_po_pdi << 22) | ((word32)last_po_pti << 12); ! ! if (fInPageOutEverything == 0) { ! ! unsigned long eipReal = a_tss.tss_eip + 0x10000000L; ! if ((v >= eipReal-0x4000) && (v <= eipReal+0x4000)) { ! ! #ifdef DEBUG ! DEBUG(DEBUG_SKIP_EIP) ! printf("\n++++++++++++++++ Skipping addr = %lx, eip = %lx, pti = %u" ! , v, eipReal, last_po_pti ! ); ! #endif ! last_po_pti += 8; ! if (last_po_pti >= 1024) { ! ! #ifdef DEBUG ! DEBUG(DEBUG_SKIP_EIP) ! printf("\n Wrapped, pti = %u, pdi = %u" ! , last_po_pti, last_po_pdi); ! #endif ! ! last_po_pti = last_po_pti % 1024; ! ! if (++last_po_pdi == 1024) ! last_po_pdi = 0; ! else if ((pd[last_po_pdi] & (PT_P | PT_S)) != (PT_P | PT_S)) ! while ((pd[last_po_pdi] & (PT_P | PT_S)) != (PT_P | PT_S)) { ! last_po_pdi++; ! if ((pd[last_po_pdi] & (PT_P | PT_S)) == (PT_P | PT_S)) ! break; ! } ! ! pt = (word32 far *)((word32)(pd_seg[last_po_pdi]) << 24); ! } ! v = ((word32)last_po_pdi << 22) | ((word32)last_po_pti << 12); ! } ! } ! ! if ((pt[last_po_pti] & (PT_P | PT_S)) == (PT_P | PT_S)) { ! ! // v = ((word32)last_po_pdi << 22) | ((word32)last_po_pti << 12); ! ! //--------------------- TEXT ----------------------------- ! // Text is read only, so discard page ! // ! if ((v >= areas[A_text].first_addr) && ! (v <= areas[A_text].last_addr) ) { ! ! rv = pt[last_po_pti] >> 12; ! pt[last_po_pti] &= 0xfff & ~(PT_A | PT_D | PT_P | PT_I); ! #ifdef DEBUG ! DEBUG(DEBUG_POUT_DISCARD) { ! printf("\nDiscarding Text %lx, flags = ", v); ! ! printf("%c", (pt[last_po_pti] & PT_C) ? 'C' : ' '); ! printf("%c", (pt[last_po_pti] & PT_S) ? 'S' : ' '); ! printf("%c", (pt[last_po_pti] & PT_I) ? 'I' : ' '); ! printf("%c", (pt[last_po_pti] & PT_D) ? 'D' : ' '); ! printf("%c", (pt[last_po_pti] & PT_A) ? 'A' : ' '); ! printf("%c", (pt[last_po_pti] & PT_U) ? 'U' : ' '); ! printf("%c", (pt[last_po_pti] & PT_W) ? 'W' : ' '); ! printf("%c", (pt[last_po_pti] & PT_P) ? 'P' : ' '); ! printf("---"); ! } ! #endif ! #if TOPLINEINFO ! { ! register int i; ! char *pStr = "Discard"; ! for (i=0; pStr[i]; i++) ! poke(screen_seg, i*2+50, pStr[i] | 0x0400); ! } ! #endif ! } ! // ! //--------------------- DATA ----------------------------- ! // Candidate is a data page that is NOT a split page data / bss ! // ! else if ((v >= areas[A_data].first_addr) && ! (v <= areas[A_data].last_addr) && ! ((v & 0xfffff000L) != (areas[A_bss].first_addr & 0xfffff000L)) ! ) { ! // ! // Selected page was modified before. Can't be discarded ! // ! if (pt[last_po_pti] & PT_PageOnceDirty) { ! #ifdef DEBUG ! DEBUG(DEBUG_POUT_DATA_DIRTY) ! printf("\n------- Encountered Data page DIRTY %lx", v); ! #endif ! goto PageItOut; // I can't believe I am using goto ! } ! // ! // Selected page was just modified. Can't be discarded ! // ! else if (pt[last_po_pti] & PT_D) { ! pt[last_po_pti] |= PT_PageOnceDirty; ! #ifdef DEBUG ! DEBUG(DEBUG_POUT_DATA_DIRTY) { ! printf("\n---------------- Marking Data page Once DIRTY %lx, flags =", v); ! ! printf("%c", (pt[last_po_pti] & PT_C) ? 'C' : ' '); ! printf("%c", (pt[last_po_pti] & PT_S) ? 'S' : ' '); ! printf("%c", (pt[last_po_pti] & PT_I) ? 'I' : ' '); ! printf("%c", (pt[last_po_pti] & PT_D) ? 'D' : ' '); ! printf("%c", (pt[last_po_pti] & PT_A) ? 'A' : ' '); ! printf("%c", (pt[last_po_pti] & PT_U) ? 'U' : ' '); ! printf("%c", (pt[last_po_pti] & PT_W) ? 'W' : ' '); ! printf("%c", (pt[last_po_pti] & PT_P) ? 'P' : ' '); ! printf("---"); ! } ! #endif ! goto PageItOut; ! } ! // ! // Page was never written to. Discard it ! // ! else { ! ! rv = pt[last_po_pti] >> 12; ! pt[last_po_pti] &= 0xfff & ~(PT_A | PT_D | PT_P | PT_I | PT_PageOnceDirty); ! ! #ifdef DEBUG ! DEBUG(DEBUG_POUT_DISCARD) { ! printf("\nDiscarding Data %lx, flags = ", v); ! ! printf("%c", (pt[last_po_pti] & PT_C) ? 'C' : ' '); ! printf("%c", (pt[last_po_pti] & PT_S) ? 'S' : ' '); ! printf("%c", (pt[last_po_pti] & PT_I) ? 'I' : ' '); ! printf("%c", (pt[last_po_pti] & PT_D) ? 'D' : ' '); ! printf("%c", (pt[last_po_pti] & PT_A) ? 'A' : ' '); ! printf("%c", (pt[last_po_pti] & PT_U) ? 'U' : ' '); ! printf("%c", (pt[last_po_pti] & PT_W) ? 'W' : ' '); ! printf("%c", (pt[last_po_pti] & PT_P) ? 'P' : ' '); ! printf("+++++++++++++++ "); ! } ! #endif ! #if TOPLINEINFO ! { ! register int i; ! char *pStr = "Dsc Dta"; ! for (i=0; pStr[i]; i++) ! poke(screen_seg, i*2+50, pStr[i] | 0x0400); ! } ! #endif ! } ! } ! // ! // Page out to swap file ! // ! else { ! ! PageItOut: ! rv = pt[last_po_pti] >> 12; ! dblock = dalloc(); ! memget(v, paging_buffer, 4096); ! dwrite(paging_buffer, dblock); ! pt[last_po_pti] &= 0xfff & ~(PT_A | PT_D | PT_P); /* no longer present */ ! pt[last_po_pti] |= (long)dblock << 12; ! ! #ifdef DEBUG ! DEBUG(DEBUG_POUT) { ! printf("\nPaging out %lx, flags = ", v); ! ! printf("%c", (pt[last_po_pti] & PT_C) ? 'C' : ' '); ! printf("%c", (pt[last_po_pti] & PT_S) ? 'S' : ' '); ! printf("%c", (pt[last_po_pti] & PT_I) ? 'I' : ' '); ! printf("%c", (pt[last_po_pti] & PT_D) ? 'D' : ' '); ! printf("%c", (pt[last_po_pti] & PT_A) ? 'A' : ' '); ! printf("%c", (pt[last_po_pti] & PT_U) ? 'U' : ' '); ! printf("%c", (pt[last_po_pti] & PT_W) ? 'W' : ' '); ! printf("%c", (pt[last_po_pti] & PT_P) ? 'P' : ' '); ! printf("---"); ! } ! #endif ! #if TOPLINEINFO ! { ! register int i; ! char *pStr = "POut "; ! for (i=0; pStr[i]; i++) ! poke(screen_seg, i*2+50, pStr[i] | 0x0600); ! } ! #endif #if VERBOSE ! printf ("out %d:%d\r", last_po_pdi, last_po_pti); #endif ! } #if TOPLINEINFO ! update_status(old_status, 79); #endif ! return rv; ! } ! } ! else /* imagine we just checked the last entry */ ! last_po_pti = 1023; ! ! if (++last_po_pti == 1024) { ! last_po_pti = 0; ! if (++last_po_pdi == 1024) ! last_po_pdi = 0; ! pt = (word32 far *)((word32)(pd_seg[last_po_pdi]) << 24); ! } ! } while ((start_pdi != last_po_pdi) || (start_pti != last_po_pti)); ! #if TOPLINEINFO update_status(old_status, 79); #endif *************** *** 698,703 **** --- 939,952 ---- unsigned pn; unsigned ptb; void far *fp; + + #ifdef DEBUG + DEBUG(DEBUG_POUT) + printf("\nPage Out everything -------------------"); + #endif + + fInPageOutEverything = 1; + while ((pn=page_out(-1)) != 0xffff) { vfree(); *************** *** 732,737 **** --- 981,994 ---- unsigned ptb; word32 far *pt; unsigned pta; + + + #ifdef DEBUG + DEBUG(DEBUG_PIN) + printf("\nPage In everything -------------------"); + #endif + fInPageOutEverything = 0; + valloc_initted = 0; pta = valloc(VA_640); pd = (word32 far *)((word32)pta << 24); diff -c3 orig/paging.h a/paging.h *** orig/paging.h Tue Jul 7 17:29:20 1992 --- a/paging.h Sun Aug 2 18:20:54 1992 *************** *** 25,30 **** --- 25,32 ---- #define PT_S 0x400 /* Swappable (else not) */ #define PT_C 0x800 /* Candidate for swapping */ + #define PT_PageOnceDirty PT_C // Page was modified by user at least once + #define EMU_TEXT 0xb0000000 /* If not present and initialized, page is in swap file. -------- END CUT -----------------------------------