blob: 1417a02f72b9ec2dc9fb624bbc5c538262433dcd (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#include <atari.h>
#include "pool.h"
#include "addrs.h"
#include "memclear.h"
screen_t screens[MAX_SCREENS];
pool_t pools[MAX_POOLS];
void init_pools(void) {
char p;
pools[0].screen_count = 0;
pools[0].free_list = (line_t *)END_MARKER;
for(p = 1; p < MAX_POOLS; p++)
pools[p].screen_count = POOL_UNUSED;
add_to_pool(0, SCR_MAIN_MEM, SCR_MAIN_END);
if((u16)OS.memlo < SCR_LOW_END - sizeof(pool_t))
add_to_pool(0, (u16)OS.memlo, SCR_LOW_END);
}
void add_to_pool(char p, u16 start, u16 end) {
line_t *l;
end -= sizeof(line_t);
l = (line_t *)start;
while(l <= (line_t *)end) {
memclear(l, sizeof(line_t));
l->next = pools[p].free_list;
pools[p].free_list = l;
l++;
}
}
char get_smallest_pool(void) {
char p, r;
u16 min;
min = 0xffff;
r = 0;
for(p = 0; p < MAX_POOLS; p++) {
if(pools[p].screen_count = POOL_UNUSED)
continue; /* maybe break here instead */
if(pools[p].screen_count < min) {
min = pools[p].screen_count;
r = p;
}
}
return r;
}
line_t *steal_line(char s) {
line_t *l;
char candidate, victim;
u16 maxheight;
victim = s;
maxheight = 0;
for(candidate = 0; candidate < MAX_SCREENS; candidate++) {
/* only steal from the same pool */
if(screens[candidate].pool != screens[s].pool)
continue;
/* steal from the screen with the most lines */
if(screens[candidate].line_count > maxheight) {
maxheight = screens[candidate].line_count;
victim = candidate;
}
}
/* find 2nd to last line of the victim screen */
for(l = screens[victim].line_list; l->next->next != (line_t *)END_MARKER; l = l->next)
;
/* prepend last line to screen s */
l->next->next = screens[s].line_list;
screens[s].line_list = l->next;
memclear(screens[s].line_list->data, LINE_LEN);
l->next = (line_t *)END_MARKER;
return l;
}
line_t *find_line(char s) {
line_t *p;
p = pools[screens[s].pool].free_list;
if(p != (line_t *)END_MARKER) {
pools[screens[s].pool].free_list = p->next;
return p;
}
/* free_list was null, pool is full */
return steal_line(s);
}
void add_line(char s) {
line_t *p;
p = find_line(s);
p->next = screens[s].line_list;
screens[s].line_list = p;
screens[s].line_count++;
}
|