Listing 1

/* A simple function for line input */
/* Philip J. Erdelsky - 01 JAN 1991 */
/* object code may be used freely */

static int key(void) {
  int k = bdos(8)&0xFF;
  /* two-byte sequence for special key is collapsed into single code */
  if (k==0) k = bdos(8)&0xFF|0x100;
  return k;
}

static void display(int c) {bdos(2,c);}

int line_input(char *text, int text_length, int display_length) {
  /* start display as though operator had struck Home or End key */
  int k = 0x147; /* Home 0x147 or End 0x14F */
  int finished = 0;
  int desired_cursor_position;
  int position_within_text;
  int actual_cursor_position = 0;
  while (1) {
    switch (k) {
      /* finish line input and exit if k==0x00D (Enter key) */
      /* other terminating keys could be added, if desired */
      case 0x00D:
        finished = 1;
        /* fall through to next case */
      /* move cursor to left end of text if k==0x147 (Home key) */
      case 0x147:
        desired_cursor_position = position_within_text = 0;
        break;
      /* move cursor to right end of text if k==0x14F (End key) */
      case 0x14F:
        position_within_text = strlen(text);
        desired_cursor_position =
          position_within_text<display_length ? position_within_text :
          display_length-1;
        break;
      /* move cursor left one place if k==0x14B (left arrow key) */
      case 0x14B:
        if (position_within_text>0) {
          position_within_text--;
          if (desired_cursor_position>0) desired_cursor_position--;
        }
        break;
      /* move cursor right one place if k==0x14D (right arrow key) */
      case 0x14D:
        if (position_within_text<strlen(text)) {
          position_within_text++;
          if (desired_cursor_position<display_length-1)
            desired_cursor_position++;
        }
        break;
      /* move cursor left one place and delete character under */
      /* cursor if k==0x008 (backspace key) */
      case 0x008:
        if (position_within_text==0) break;
        position_within_text--;
        if (desired_cursor_position>0) desired_cursor_position--;
        /* fall through to next case */
      /* delete character under cursor if k==0x153 (Del key) */
      case 0x153:
        if (text[position_within_text]!=0)
          strcpy(text+position_within_text, text+position_within_text+1);
        break;
      /* insert new character to left of character under cursor */
      default:
        if (' '<=k && k<='~' && strlen(text)<text_length) {
          char *t = text+position_within_text;
          do {
            int temp = *t;.
            *t++ = k;
            k = tempt;
          } while (k!=0);
          *t = 0;
          position_within_text++;
          if (desired_cursor_position<display_length-1)
            desired_cursor_position++;
        }
    }
    /* redisplay entire line */
    {
      int hidden_characters_at_left =
        position_within_text_desired_cursor_position;
      char *t = text+hidden_characters_at_left;
      /* move cursor to left end of line */
      while (actual_cursor_position!=0)
        {display('\b'); actual_cursor_position--;}
      /* display arrows at left end if necessary */
      display('\b');/* 0xAE = left arrows */
      display(hidden_characters_at_left!=0 ? 0xAE : ' ');
      /* display text and trailing spaces, if any */
      while (actual_cursor_position<display_length) {
        int c;
        display(*t==0 ? ' ' : (c = *t++)==' ' ? 0xFA : c);
        actual_cursor_position++; /* 0xFA = tiny dot */
      }
      /* display arrows at right end if necessary */
      display(*t!=0 ? 0xAF : ' '); /* 0xAF = right arrows */
      actual_cursor_position++;
      /* move cursor back to desired position */
      while (actual_cursor_position>desired_cursor_position)
        {display('\b'); actual_cursor_position--;}
    }
    if (finished) return k;
    k = key();
  }
}

/* test program */

void main(int argc, char **argv) {
  char text[40];
  int k;
  strcpy(text, argc>1 ? argv[1] : "");
  printf("> ");
  k = line_input(text, sizeof(text)-1, 20);
  printf("\nreturn value=%03X text=\"%s\"\n", k, text);
}

/* End of File */