1 /* yForth? - Written by Luca Padovani (C) 1996/97
2 * ------------------------------------------------------------------------
3 * This software is FreeWare as long as it comes with this header in each
4 * source file, anyway you can use it or any part of it whatever
5 * you want. It comes without any warranty, so use it at your own risk.
6 * ------------------------------------------------------------------------
8 * Abstract: Block word set implementation
17 /**************************************************************************/
18 /* VARIABLES **************************************************************/
19 /**************************************************************************/
24 FILE *block_file; /* FILE used to implement blocks */
26 struct _block_data *block_data;
27 struct _block_buffer *block_buffer;
29 static int block_clock; /* Used to select the next block to
30 deallocate. Based on the "clock
34 /**************************************************************************/
35 /* WORDS ******************************************************************/
36 /**************************************************************************/
39 register UCell u = (UCell) *sp;
40 register int b = search_block(u);
41 if (b < 0) b = allocate_block(u, 1);
43 sp[0] = (Cell) &block_buffer[b].buffer;
47 register UCell u = (UCell) *sp;
48 register int b = search_block(u);
49 if (b < 0) b = allocate_block(u, 0);
51 sp[0] = (Cell) &block_buffer[b].buffer;
57 for (i = 0; i < NUM_BLOCKS; i++) block_data[i].block_no = 0;
61 register UCell block_no = (UCell) *sp;
62 save_input_specification();
64 _input_buffer = (Char *) *sp++;
65 _in_input_buffer = BLOCK_SIZE;
69 restore_input_specification();
72 void _save_buffers() {
74 for (i = 0; i < NUM_BLOCKS; i++) if (block_data[i].dirty) save_block(i);
78 block_data[current_block].dirty = 1;
81 /**************************************************************************/
82 /* AUXILIARY FUNCTIONS ****************************************************/
83 /**************************************************************************/
85 int search_block(UCell block_no) {
87 for (i = 0; i < NUM_BLOCKS && block_data[i].block_no != block_no; i++) ;
88 return (i < NUM_BLOCKS ? i : -1);
91 int allocate_block(UCell block_no, int load) {
93 register int b = search_block(0);
95 if (block_data[block_clock].dirty) save_block(block_clock);
97 block_clock = (block_clock + 1) % NUM_BLOCKS;
99 if (load) load_block(block_no, b);
103 void load_block(UCell block_no, int b) {
104 block_data[b].block_no = block_no;
105 block_data[b].dirty = 0;
106 fseek(block_file, ((long) (block_no - 1)) * BLOCK_SIZE, SEEK_SET);
107 fread(&block_buffer[b].buffer, BLOCK_SIZE, 1, block_file);
110 void save_block(int b) {
111 fseek(block_file, ((long) (block_data[b].block_no - 1)) * BLOCK_SIZE, SEEK_SET);
112 fwrite(&block_buffer[b].buffer, BLOCK_SIZE, 1, block_file);
113 block_data[b].dirty = 0;
116 int open_block_file(char *name) {
117 block_file = fopen(name, "r+b");
118 if (!block_file) block_file = fopen(name, "r+b");
120 block_data = (struct _block_data *) malloc(NUM_BLOCKS * sizeof(struct _block_data));
121 block_buffer = (struct _block_buffer *) malloc(NUM_BLOCKS * sizeof(struct _block_buffer));
122 if (block_data && block_buffer) {
124 for (i = 0; i < NUM_BLOCKS; i++) block_data[i].block_no = 0;
125 } else block_file = NULL;
127 return (block_file ? 0 : -1);
130 void close_block_file() {