static void cga_scroll(int delta) { int new_backscroll = max(min(crtsave_backscroll - delta, (int) crtsave_size), 0); if (new_backscroll == crtsave_backscroll) return; if (crtsave_backscroll == 0) // save current screen cga_savebuf_copy(crtsave_pos + crtsave_size, 0); crtsave_backscroll = new_backscroll; cga_savebuf_copy(crtsave_pos + crtsave_size - crtsave_backscroll, 1); }
static void cga_putc(int c) { #if CRT_SAVEROWS > 0 // unscroll if necessary if (crtsave_backscroll > 0) { cga_savebuf_copy(crtsave_pos + crtsave_size, 1); crtsave_backscroll = 0; } #endif // if no attribute given, then use light gray on black if (!(c & ~0xFF)) c |= 0x0700; switch (c & 0xff) { case '\b': if (crt_pos > 0) { crt_pos--; crt_buf[crt_pos] = (c & ~0xff) | ' '; } break; case '\n': crt_pos += CRT_COLS; /* fallthru */ case '\r': crt_pos -= (crt_pos % CRT_COLS); break; case '\t': cons_putc(' '); cons_putc(' '); cons_putc(' '); cons_putc(' '); cons_putc(' '); break; default: crt_buf[crt_pos++] = c; /* write the character */ break; } // What is the purpose of this? if (crt_pos >= CRT_SIZE) { int i; #if CRT_SAVEROWS > 0 // Save the scrolled-back row if (crtsave_size == CRT_SAVEROWS - CRT_ROWS) crtsave_pos = (crtsave_pos + 1) % CRT_SAVEROWS; else crtsave_size++; memcpy(crtsave_buf + ((crtsave_pos + crtsave_size - 1) % CRT_SAVEROWS) * CRT_COLS, crt_buf, CRT_COLS * sizeof(uint16_t)); #endif memcpy(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) * sizeof(uint16_t)); for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i++) crt_buf[i] = 0x0700 | ' '; crt_pos -= CRT_COLS; } /* move that little blinky thing */ outb(addr_6845, 14); outb(addr_6845 + 1, crt_pos >> 8); outb(addr_6845, 15); outb(addr_6845 + 1, crt_pos); }