ftp.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1992/08/04/23:47:01

Date: Mon, 3 Aug 92 01:44:41 -0500
From: rcharif AT math DOT utexas DOT edu
Posted-Date: Mon, 3 Aug 92 01:44:41 -0500
To: dj AT ctron DOT com
Cc: djgpp AT sun DOT soe DOT clarkson DOT edu
Subject: Paging enhancement for go32 v1.07
Reply-To: rcharif AT math DOT utexas DOT edu

Hi,

I made a slight modification to the paging procedure in Go32 v1.07. I
have remarked that go32 swapps to the paging file each time there is
need for memory.

If the page hasn't been written to, there is no need to page it out.
It can simply be discarded and a disk access avoided. When the page is
needed again it will brought from the executable file as if it is the
first access. The limitation is that executing files from a floppy
disk or a slow network will prove to be slower, but if the executable
is on a local disk there is a performance improvement.

In the modification I discard both code and data pages. Code pages are
discarded if they belong to the executable file without any checking.
Data pages are discarded if they have never been written to. (See the
file paging.c for details).

Another modification is that the paging routine will not page out the
pages surrounding the current instruction pointer +-4 pages. The old
routine, used to page out blindly and sometimes paged out the
currently executed instruction. This resulted in unneeded and slow
trafic. When I gathered statistics, I saw this happening with gcc most
of the time.

I included another modification to permit selective debugging in go32.
(See build.h). The flags denoting the sections to be debugged can be
given on the command line like the following :

	go32 -debug all program_name	<-- to debug all
	go32 -debug <debug_mask_value> program_name <-- To debug certain mask

or in the GO32 environment variable with the following :

	set go32= debug all ....
or	set go32= debug <debug_mask_value> ....

The command line debug mask has priority over the one given in the
go32 environment variable.

The following masks (along their values) are used for now :

	DEBUG_POUT              1	view page out trafic
	DEBUG_PIN               2	view page in trafic
	DEBUG_POUT_DATA_DIRTY   4	view data pages flagging as dirty
	DEBUG_POUT_DISCARD      8	view discarding pages
	DEBUG_SKIP_EIP         16	view skipping current eip

debug_mask_value is formed by adding the wanted mask's numerical value.

An interesting value is 25. This permits to view the page out algoritm
and compare the ratio page out / discard.

I put a complete version of the modification on :

	math.utexas.edu:/pub/msdos/Go32Modif/paging
	user 	ftp
	login	anonymous

The following files are available :

	ModifDiff.zip		: a diff -c3 of the modified files. Use patch
				to apply the modifications

	Go32Modified.zip	: A complete version source + executable

	ModifiedFiles.zip	: Source code of the modified source files

I tried this modification with a relatively big program (5.6 Megabytes)
 and I found a significant improvement.

I will be interested in your comments especially comparison with the
basic go32. I hope that DJ will be able to insert this modification in
future versions of go32.

Regards,
Rami El Charif

Here is the diff file for the modification --------------------------------
--------------------- Cut Here ---------------------------------------
diff -c3 d:\local\go32\org/build.h d:\local\go32\mod/build.h
*** d:\local\go32\org/build.h	Sun Aug  2 23:25:26 1992
--- d:\local\go32\mod/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 d:\local\go32\org/control.c d:\local\go32\mod/control.c
*** d:\local\go32\org/control.c	Tue Jul  7 17:29:14 1992
--- d:\local\go32\mod/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 <flag value>] [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 <all || debug_flags_value>] 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 d:\local\go32\org/makefile d:\local\go32\mod/makefile
*** d:\local\go32\org/makefile	Sat Aug  1 19:58:24 1992
--- d:\local\go32\mod/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
  
diff -c3 d:\local\go32\org/paging.c d:\local\go32\mod/paging.c
*** d:\local\go32\org/paging.c	Tue Jul  7 17:29:16 1992
--- d:\local\go32\mod/paging.c	Sun Aug  2 20:48:14 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");
***************
*** 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
--- 665,905 ----
    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.
!          // Take a limit of +-4 pages
!          //
!          v = ((word32)last_po_pdi << 22) | ((word32)last_po_pti << 12);
!          if ((v >= a_tss.tss_eip-0x4000) && (v <= a_tss.tss_eip+0x4000)) {
! 
! #ifdef DEBUG
!             DEBUG(DEBUG_SKIP_EIP)
!                printf("\n++++++++++++++++ Skipping eip, addr = %lx,  eip = %lx"
!                   , v, a_tss.tss_eip
!                   );
! #endif
!             last_po_pti += 6;
!             if (last_po_pti >= 1024) {
! 
!                last_po_pti %= 1024;
!                if (++last_po_pdi == 1024)
!                   last_po_pdi = 0;
!                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 ****
--- 917,928 ----
    unsigned pn;
    unsigned ptb;
    void far *fp;
+ 
+ #ifdef DEBUG
+    DEBUG(DEBUG_POUT)
+       printf("\nPage Out everything -------------------");
+ #endif
+ 
    while ((pn=page_out(-1)) != 0xffff)
    {
      vfree();
***************
*** 732,737 ****
--- 957,969 ----
    unsigned ptb;
    word32 far *pt;
    unsigned pta;
+ 
+ 
+ #ifdef DEBUG
+    DEBUG(DEBUG_PIN)
+       printf("\nPage In everything -------------------");
+ #endif
+ 
    valloc_initted = 0;
    pta = valloc(VA_640);
    pd = (word32 far *)((word32)pta << 24);
diff -c3 d:\local\go32\org/paging.h d:\local\go32\mod/paging.h
*** d:\local\go32\org/paging.h	Tue Jul  7 17:29:20 1992
--- d:\local\go32\mod/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 HERE -----------------------------------------------------


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019