+int
+ansi_scroll_up (ANSI * a, CRT_Pos s, CRT_Pos e)
+{
+ char buf[16];
+ int i;
+ if (s.x)
+ return -1;
+ if (e.x != (CRT_COLS - 1))
+ return -1;
+ if (s.y)
+ return -1;
+ if (s.y >= a->size.y)
+ return -1;
+
+ ansi_showhide_cursor (a, 1);
+ i = sprintf (buf, "\033[%d;%dr", s.y + 1, e.y + 1);
+ ansi_write (a, buf, i);
+ i = sprintf (buf, "\033[%d;%dH", e.y + 1, 0);
+ ansi_write (a, buf, i);
+ ansi_write (a, "\033D", 2);
+ ansi_write (a, "\033[r", 3);
+
+ s.y = e.y;
+ crt_erase (&a->crt, s, e, 1);
+
+ a->pos.x = ANSI_INVAL;
+
+ return 0;
+}
+
+
+void
+ansi_spot_scroll_up (ANSI * a, CRT * c)
+{
+ int l, n, p;
+
+ l = c->sh.e.x - c->sh.s.x;
+ l++;
+ l *= sizeof (CRT_CA);
+
+ n = c->sh.e.y - c->sh.s.y;
+ p = CRT_ADDR_POS (&c->sh.s);
+
+ while (n--)
+ {
+ if (memcmp (&c->screen[p], &a->crt.screen[p + CRT_COLS], l))
+ return;
+ p += CRT_COLS;
+ }
+
+ if (ansi_scroll_up (a, c->sh.s, c->sh.e))
+ return;
+
+ n = c->sh.e.y - c->sh.s.y;
+ p = CRT_ADDR_POS (&c->sh.s);
+
+ while (n--)
+ {
+ memcpy (&a->crt.screen[p], &a->crt.screen[p + CRT_COLS], l);
+ p += CRT_COLS;
+ }
+
+ c->sh.dir = 0; //FIXME: horrid hack
+
+}
+
+void
+ansi_spot_scroll (ANSI * a, CRT * c)
+{
+
+ switch (c->sh.dir)
+ {
+ case -1:
+/*we only care about up for the moment */
+ ansi_spot_scroll_up (a, c);
+ break;
+ }
+
+ return;
+}
+
+
+