In the last post we learned about control characters and the C escape sequences that represent some of them. Today we’re going to see a different kind of escape sequences: the ones that control the console.
You may remember that among the list of control characters we saw there were two that weren’t used to control the screen, but instead mark the beginning of either a graphic character or a terminal escape sequence. In this chapter we’re going to see how to use one of these (character code 27, or \33, or 0x1B):
Printing this character by itself does nothing. However, when it is followed by certain sequences of characters we can control several aspects of the text screen such as the position and shape of the cursor.
We call these sequences of characters terminal escape sequences (or also screen/console escape sequences). Do not mistake them with the C escape sequences we saw earlier:
- C escape sequences are symbols the C programming language uses to represent especific control characters, regardless of the platform.
- Terminal escape sequences are sequences of characters the MSX supports that perform operations on the screen, regardless of the programming language.
Let’s take a look at the terminal escape sequences supported.
Using terminal escape sequences
Let’s start with an example: printing the sequence of characters ‘\33’, ‘y’ and ‘4’ changes the shape of the cursor to an underscore. Note that we must print each character without spaces between them, as if they were a single word:
If you want to compare, try commenting out the line that prints the escape sequence in the program above and compile again.
The MSX standard supports 16 of these escape sequences:
Notice that there is a bit of overlap. Some of these perform the same function as some control characters (\33A, \33B, \33C, \33D), and also some are equivalent to C escape sequences (\33E, \33H and \33j).
There’s a bunch of them, so let’s take a closer look at a few useful examples.
Changing the position of the cursor
The escape sequence \33Yxx performs the same function as the LOCATE statement in BASIC: it moves the cursor to an especific location on the screen. The two x are two characters whose character code indicate the screen coordinates. The first one indicates the Y coordinate on the screen (the line number) and the second indicates the X coordinate (the column). To obtain the character that goes in the escape sequence just add 32 to each coordinate.
Yes, I understand that putting it in words it sounds complex, but it’s actually very simple. An example will illustrate this better:
Move the cursor to coordinates (3, 6)
We want to move the cursor to screen coordinates (3, 6). For this we have to print the sequence \33Y followed by two characters indicating the coordinates. The first of these characters will be the one whose code is 32 + the Y coordinate, and the second character will be the one with code 32 + the X coordinate. We can check any ASCII table to look up the characters.
The Y coordinate is 6, so we have to find the character with ASCII code 38 (32 + 6). This character is &.
The X coordinate is 3, which gives us character with ASCII code 35 (32 + 3). The character is #.
Putting it all together, we get that the escape sequence we want is \33Y&# (remember that the Y coordinate goes first)
Let’s see this in an example program. The program below prints a small text box starting from screen coordinates (3,6). The box takes three lines of text, so the program uses three escape sequences to position the cursor before printing each line:
If you run this program you’ll see that it always prints the text box and exits immediately:
After the program exits we can see the MSX-DOS2 prompt again. You may need to clear the screen after this (just type the “CLS” command).
One thing to note is that escape sequences don’t have to be printed in a separate puts() call. They can appear anywhere in the text. The following program does exactly the same as the previous one, but is a bit more efficient:
Or we can just put all the text together and print the whole multiline box using a single puts():
In these examples we have used puts() to print the escape sequence, but we can use any other function that displays text on the screen, such as putchar() or printf() as long as we don’t break the sequence:
Notice how in the program above we didn’t bother to look at the ASCII table and just gave putchar() the character codes that match the coordinates we want. We can do the same thing easily with printf():
Inserting and deleting lines on the screen
Look again at the table of escape sequences at the beginning of this post. \33L inserts a line on the screen and \33M deletes a line. Both of them operate on the position of the cursor.
As an example, if we want to insert five lines of text from line 3 on the screen, first we have to move the cursor to line 3 and then print the escape sequence \33L five times:
Note that in the program above the escape sequence to position the cursor is “\33Y# “. The space after the # is part of the sequence. This is because we’re placing the cursor in coordinate (0,3) on the screen, so the character code that represents coordinate 0 is 32 (the space).
Compile the program and you’ll see that every time you run it the text on the screen scrolls five lines towards the bottom:
We can easily modify the previous program to delete lines instead, using the sequence \33M instead of \33L:
Compile and run it and you’ll see how the escape sequence deletes lines and scrolls the contents towards the top of the screen:
We can use these sequences to clear the screen with a text scroll by placing the cursor at the top of the screen and deleting or inserting lines:
Enabling and disabling the cursor
There are times when for aesthetic reasons it’s convenient to disable the cursor so it’s not displayed on the screen, such as when showing a prompt asking the user to press a key. The escape sequences \33×5 and \33y5 respectively disable and enable the cursor.
Take a look at the following two programs. They both print a text message on the screen and wait for the user to press the space key. Note that we include the header MSXBIOS.H in order to use the gttrig() function. This is part of the MSX-C Library package that we installed at the beginning of the course. We’ll discuss it in a future post. For now just type the programs as below:
Notice that the only difference between them is the escape sequence. SEQ10.C disables the cursor before printing anything, and SEQ11.C enables it.
If you run them you’ll spot the difference easily: SEQ11.COM keeps the cursor on the screen at all times, while SEQE10.COM doesn’t:
After running SEQ11 you may notice that when working on MSX-DOS the display of text on the screen feels slower. For example, listing the files in a directory with DIR feels a bit different. You’re not imagining things. The cursor setting will remain even after the program finishes.
When the cursor is enabled, MSX-DOS shows the cursor after every character it prints on the screen, slowing down the display of text for a few fractions of a second. You can see the effect on this video:
In this post we’ve seen the list of terminal escape sequences supported by the MSX standard and we’ve seen a few examples about how to use them. The most useful will be the \33Yxx escape sequence to position the cursor on the screen.
In the next post…
The next post will be about graphical characters. Those are a set of 32 characters that take one byte in the video memory, but are represented by the MSX as tw0-byte characters. This will be the last we’ll see about escape sequences and especial characters.
This series of articles is supported by your donations. If you’re willing and able to donate, please visit the link below to register a small pledge. Every little amount helps.