Listing 2 (rdscrnc.c)

struct screen_block   /* structure of argument passed from APL  */
 { short start_row;   /* will be passed as either a vector of   */
   short start_col;   /* length 4 or an N,4 matrix.             */
   short number_rows;
   short number_cols;
 };

void result_size(int,struct screen_block far *,short far *,short far *);
void read_screen_blocks(short,struct screen_block far *,short,char far *);

/*
    RESULT_SIZE -  calculate size of APL Result.
                    Equals number of rows in all blocks by
                    the length of the longest row ..
*/
void result_size(cnt,blocks,result_rows,result_cols)
int cnt;                                  /* number of rows in APL data */
struct screen_block far * blocks;          /* the APL argument itself .. */
short far * result_rows;                   /* # of rows in APL result    */
short far * result_cols;                   /* # of cols in APL result .. */
{
    short i,temp_rows,temp_cols;

    temp_rows = 0;
    temp_cols = 0;
    for(i = 0;i < cnt;i ++)
     { temp_rows += blocks[i].number_rows;
       temp_cols = (temp_cols > blocks[i].number_cols)
                    ? temp_cols : blocks[i].number_cols;
     }
    *result_rows = temp_rows;
    *result_cols = temp_cols;
}
/*
      READ_SCREEN_BLOCKS -    Read data from screen, fill in
                           APL result ...
*/
void read_screen_blocks(cnt,blocks,result_cols,result)
short cnt;                                    /* number of rows in APL arg */
struct screen_block far * blocks;             /* the APL argument itself .. */
short result_cols;                            /* max # cols in APL result . */
char far * result;                            /* APL result to be filled in */
{
   short i,j,k;
   unsigned long video_memory,rowstart,position;
   char video_mode;

   video mode = *(char far *) 0x00400049;    /* get video mode        */
   if(video_mode == 7)                       /* ie, mono ...          */
      video_memory = 0xb0000000;
   else
      video_memory = 0xb8000000;

   for(i = 0;i < cnt;i ++)                          /* process screen block
*/
    { rowstart : video_memory + (unsigned) blocks[i].start_row * 160;
      rowstart += (unsigned) blocks[i].start_col * 2;
      for(j = 0;j < blocks[i].number_rows; j++)      /* process each row */
       { position = rowstart;
         for(k = 0;k < blocks[i].number_cols;k ++)    /* process cols .*/
          { *result++ = *(char far *)position;        /* get char .. */
            position += 2;                             /* skip attribute*/
          }
         for(;k < result_cols;k ++)               /* any filler needed .. */
            *result++ = ' ';
         rowstart += 160;                         /* to next screen row   */
       }
    }
}