aboutsummaryrefslogtreecommitdiff
path: root/src/pool.c
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2026-04-24 03:54:01 -0400
committerB. Watson <urchlay@slackware.uk>2026-04-24 03:54:01 -0400
commit715964c0b5ab8a2bc2b8ae8b7935e9ea0088e332 (patch)
tree8d61003fadc3d3c7761394c517c4488c2b63743d /src/pool.c
parent2ce1d0d8a2e7f79e1bb008836a4dca48adba867e (diff)
downloadfujinet-chat-715964c0b5ab8a2bc2b8ae8b7935e9ea0088e332.tar.gz
Dynamic screens. Still a bit flaky, but actually does work to some degree.
Diffstat (limited to 'src/pool.c')
-rw-r--r--src/pool.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/src/pool.c b/src/pool.c
new file mode 100644
index 0000000..1417a02
--- /dev/null
+++ b/src/pool.c
@@ -0,0 +1,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++;
+}