1 /*
2   PG_Flat
3   Keep all bytes resident; much faster but memory hungry
4   (Should exploit the knowledge that the memory is flat in mem)
5 */
6 
7 #include "page.h"
8 
9 #include "alloc.h"
10 #include "head.h"
11 #include "interp.h"
12 #include "mem.h"
13 #include "os.h"
14 #include "pc.h"
15 #include "stack.h"
16 #include "stop.h"
17 #include "var.h"
18 
19 typedef byte block[BLOCK_SIZE];
20 
21 byte *base_ptr;
22 
23 static word minpages;
24 static block *lock;
25 
pg_head(void)26 int pg_head(void)
27 {
28   base_ptr = alloc(1, block);
29   hd_load(0, 1, base_ptr);
30   return base_ptr != 0;
31 }
32 
pg_init(word minimum,word maximum)33 int pg_init(word minimum, word maximum)
34 {
35   minpages = minimum;
36   lock = alloc(maximum, block);
37   os_mcpy(lock[0], base_ptr, sizeof(block));
38   base_ptr  = lock[0];
39   hd_load(1, maximum - 1, lock[1]);
40   return 1;
41 }
42 
pg_fetch(word new_page)43 byte *pg_fetch(word new_page)
44 {
45   return lock[new_page];
46 }
47 
48 
49 /* Additions for undo */
50 
51 static byte *undo = 0;
52 static int undo_size = 0;
53 
needed(void)54 static int needed(void)
55 {
56   /* Paragraphs needed for the undo buffer */
57   word need = minpages * sizeof(block)
58             + 2 * sizeof(word)
59             + sizeof(stack_space)
60             + sizeof(var_ptr)
61             + sizeof(stack_ptr)
62             ;
63   return need;
64 }
65 
append(int * off,void * from,word size)66 static void append(int *off, void *from, word size)
67 {
68   os_mcpy(undo + *off, from, size);
69   *off += size;
70 }
71 
pg_save_undo(void)72 void pg_save_undo(void)
73 {
74   word result = 0; /* Failed */
75   int need = needed();
76   if(undo == 0)
77   {
78     undo_size = need;
79     undo = alloc(undo_size, byte);
80   }
81   if(undo_size < need)
82   {
83     undo_size = need;
84     undo = os_realloc(undo, undo_size);
85   }
86   if(undo)
87   {
88     int off = 0;
89     word p = pc_page();
90     word o = pc_offset();
91     append(&off, lock,           minpages * sizeof(block));
92     append(&off, &p,             sizeof(p));
93     append(&off, &o,             sizeof(o));
94     append(&off, stack_space,    sizeof(stack_space));
95     append(&off, &var_ptr,       sizeof(var_ptr));
96     append(&off, &stack_ptr,     sizeof(stack_ptr));
97     result = 1;
98   }
99   store(result);
100 }
101 
restore(int * off,void * to,word size)102 static void restore(int *off, void *to, word size)
103 {
104   os_mcpy(to, undo + *off, size);
105   *off += size;
106 }
107 
pg_restore_undo(void)108 void pg_restore_undo(void)
109 {
110   if(undo)
111   {
112     int off = 0;
113     word p, o;
114     restore(&off, lock,           minpages * sizeof(block));
115     restore(&off, &p,             sizeof(p));
116     restore(&off, &o,             sizeof(o));
117     restore(&off, stack_space,    sizeof(stack_space));
118     restore(&off, &var_ptr,       sizeof(var_ptr));
119     restore(&off, &stack_ptr,     sizeof(stack_ptr));
120     set_pc(p, o);
121     init_interpreter(0);
122     store(2);
123   }
124   else
125   {
126     display("Undo attempted when not valid.");
127     quit();
128   }
129 }
130