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