class tty {
public:
  byte x, y, scroll;
  uint16_t addr() {
    return (((y + scroll) & 63) << 6) + x;
  }
  void home(void) {
    x = y = 0;
  }
  void move(byte _x, byte _y) {
    x = _x; y = _y;
  }
  void clear(void) {
    home();
    scroll = 0;
    GD.wr16(SCROLL_Y, 0);
    GD.fill(RAM_PIC, ' ', 64 * 64);
  }
  void begin(void) {
    GD.ascii();
    clear();
  }
  void newline() {
    x = 0;
    if (y < 36) {
      y++;
    } else {
      scroll++;
      GD.fill(addr(), ' ', 50);
      GD.fill(0xfff & (addr() + 64), ' ', 50);
      GD.wr16(SCROLL_Y, scroll << 3);
    }
  }
  void write(char c) {
    if (c == '\n')
      newline();
    else {
      GD.wr(addr(), c);
      if (++x == 50) {
        newline();
      }
    }
  }
  void write(const char *s) {
    while (*s)
      write(*s++);
  }
  void write(const char *s, size_t n) {
    while (n--)
      write(*s++);
  }
  void printf(const char *fmt, ...)
  {
    va_list args;
    va_start(args, fmt);
    size_t n = vsnprintf(NULL, 0, fmt, args);
    char buf[n + 1];
    vsprintf(buf, fmt, args);
    write(buf, n);
  }
};
static class tty Tty;

