Inside COBOL #73 (Cursor Control Techniques)
by
Shawn Gordon
President
The Kompany
This month I thought I would go over a variety of cursor control techniques as well as display enhancements that you can do with simple escape sequences. Many years ago I worked for a company who used no screen driver software at all, they simply did DISPLAY..ACCEPT and let the screen scroll. I thought it looked aweful, so I sat down and decided I would learn View, but with no one to ask questions of, and no real samples to look at I grew quickly frustrated and proceeded to write my own screen driver.
I had read some interesting articles over the years on how to do cursor placement and read the screen and use protected fields, so I ended up making a whole interactive forms design system that stored its screens in a database. I developed a series of macros that we retrieve the form, and display it, and other macros to accept input. It wasn’t too bad for a young punk.
After that I ended up designing a series of callable routines that would take parameters and do things like menu bars and drop down menus and such, also pretty slick, but they all made use of some basic principles and escape sequences, which I’ll talk about today. By the way, this is how I beat up a terminal emulator to make sure it works. Since this all works on a terminal, it better work on a terminal emulator. The old 2392 terminal manual was a great source of information for this stuff.
So what I thought I would do is give you a list of the escape sequences that I use (or some of them anyway), with a description, and then some examples with macros.
* Send the cursor home and clear the display. 01 HOME-N-CLEAR. 05 PIC X VALUE %33. 05 PIC X VALUE 'h'. 05 PIC X VALUE %33. 05 PIC X VALUE 'J'. * * Send the cursor to an absolute position on the screen. 01 START-ADDRESS. 03 PIC X VALUE %33. 03 PIC X(02) VALUE '&a'. 03 START-COL PIC 99 VALUE ZEROES. 03 PIC X VALUE 'c'. 03 START-ROW PIC 99 VALUE ZEROES. 03 PIC X VALUE 'R'. * * Send the cursor to the upper leftmost corner of the display. 01 UP-HOME. 03 PIC X VALUE %33. 03 PIC X VALUE 'h'. * * Send the cursor to the end of display memory. 01 DOWN-HOME. 03 PIC X VALUE %33. 03 PIC X VALUE 'F'. * * Move the cursor up one line. 01 UP-LINE. 03 PIC X VALUE %33. 03 PIC X VALUE 'A'. * * move the cursor down one line. 01 DOWN-LINE. 03 PIC X VALUE %33. 03 PIC X VALUE 'B'. * * Move the cursor one character to the right (not a space). 01 GO-RIGHT. 03 PIC X VALUE %33. 03 PIC X VALUE 'C'. * * Move the cursor one character to the left (not a backspace). 01 GO-LEFT. 03 PIC X VALUE %33. 03 PIC X VALUE 'D'. * * Scroll the display down one line. 01 SCROLL-DOWN. 03 PIC X VALUE %33. 03 PIC X VALUE 'T'. * * Scroll the display up one line. 01 SCROLL-UP. 03 PIC X VALUE %33. 03 PIC X VALUE 'S'. * * Insert a line. 01 INS-LINE. 03 PIC X VALUE %33. 03 PIC X VALUE 'L'. * * Turn on Insert Character. 01 INS-CHAR. 03 PIC X VALUE %33. 03 PIC X VALUE 'Q'. * * Turn off Insert Character. 01 INS-OFF. 03 PIC X VALUE %33. 03 PIC X VALUE 'R'. * * Delete a line. 01 DEL-LINE. 03 PIC X VALUE %33. 03 PIC X VALUE 'M'. * * Delete a charcter from the current cursor position. 01 DEL-CHAR. 03 PIC X VALUE %33. 03 PIC X VALUE 'P'. * * Turn on inverse video. 01 INVERSE. 03 PIC X VALUE %33. 03 PIC X(3) VALUE '&dB'. * * Turn on half bright inverse video. 01 INV-HALF. 03 PIC X VALUE %33. 03 PIC X(3) VALUE '&dJ'. * * Begin Underline. 01 UNDER-LINE. 03 PIC X VALUE %33. 03 PIC X(3) VALUE '&dD'. * * Turn on Half Brite video. 01 HALF-BRITE. 03 PIC X VALUE %33. 03 PIC X(3) VALUE '&dH'. * * Turn off any display enahncement started with &d. 01 EHL. 03 PIC X VALUE %33. 03 PIC X(3) VALUE '&d@'. * * Clear the line from the cursor to the end of the screen. 01 CLEAR-LINE. 03 PIC X VALUE %33. 03 PIC X VALUE 'K'. * * Clear the display from the cursor to the end of display memory. 01 KLEAR. 03 PIC X VALUE %33. 03 PIC X VALUE 'J'. * * Turn on memory lock at the current cursor position. 01 MEM-ON. 03 PIC X VALUE %33. 03 PIC X VALUE 'l'. * * Turn off memory lock (doesn’t matter where the cursor is). 01 MEM-OFF. 03 PIC X VALUE %33. 03 PIC X VALUE 'm'. * * Perform a Next Page. 01 NEXT-PAGE. 03 PIC X VALUE %33. 03 PIC X VALUE 'U'. * * Perform a Previous Page. 01 PREV-PAGE. 03 PIC X VALUE %33. 03 PIC X VALUE 'V'. * * Turn echo off, not the same as the FCONTROL one. 01 ECHO-OFF. 03 PIC X VALUE %33. 03 PIC X(3) VALUE '&dS'. * * Enable Transmit Functions (this is so you can tell when a cursor key is * pressed, and supress the actual action. 01 XMIT-FUNC-ON. 03 PIC X VALUE %33. 03 PIC X(4) VALUE '&s1A'. * * Disable Transmit Functions (default setting). 01 XMIT-FUNC-OFF. 03 PIC X VALUE %33. 03 PIC X(4) VALUE '&s0A'. * * Turn the screen display off, this is good to hide what you are doing, gives * a physchological feeling of instant display. 01 SCREEN-OFF. 03 PIC X VALUE %33. 03 PIC X(5) VALUE '&w13F'. * * Turn the screen display on (default setting). 01 SCREEN-ON. 03 PIC X VALUE %33. 03 PIC X(5) VALUE '&w12F'. * * Read the line at the current cursor position, can be used for a PSCREEN * type function. 01 READ-LINE. 03 PIC X VALUE %33. 03 PIC X VALUE 'd'. * * Turn Line drawing on and off, display an escape character, variables for my * ad-hoc display macros. 01 G-ON PIC X VALUE %16. 01 G-OFF PIC X VALUE %17. 01 ESC PIC X VALUE %33. 01 T-ROW PIC 99 VALUE ZEROES. 01 T-COL PIC 99 VALUE ZEROES. Ok, here is the main macro that I use to implement this stuff. $DEFINE %TERMPOS= COMPUTE T-ROW = !1 - 1 COMPUTE T-COL = !2 - 1 DISPLAY %33 "&a" T-COL "c" T-ROW "R" !3 NO ADVANCING#
Let me explain one thing that may not be obvious. When you look at a terminal and get the screen coordinates, they are numbered from 1,1 at the upper left corner. However, all of the escape sequences to do cursor positioning number from 0,0. So I decided to make the macro adjust for what the screen says and avoid confusion.
So here are some examples of what you might try.
%TERMPOS(5#,1#,KLEAR MEM-ON#). %TERMPOS(5#,1#,UNDER-LINE “This is a heading of some sort” EHL#). %TERMPOS(23#,1#, INVERSE “You have made a fatal error in the applicatoin” EHL#). ACCEPT WS-ERROR. %TERMPOS(23#,1#, KLEAR#).
This is just a simple example of the uses, but once you have built up a small library of predefined variables and macros, you will be able to do all sorts of ad-hoc screens with relative ease.