Easiest (to read and write) way to position the cursor on X16 BASIC?

grommile

New Member
Nov 24, 2019
12
5
3
Northampton, UK
I'm writing a game that is intended to be approximately a homage to the late Daniel M. Lawrence's Telengard, so I have a bunch of text display elements that want to be in specific places on the screen. Both as an aspect of the homage (DML wrote the original PET version in BASIC), and because there's a certain visceral satisfaction in doing so, I'm writing it in BASIC.

This leads me to a question: is there a way of moving the cursor that is both (a) more reader-friendly than making a call to the KERNAL's PLOT routine and (b) more writer-friendly than strings of 20-odd cursor movement characters?
 
  • Like
Reactions: codewar65

codewar65

Member
Sep 25, 2019
36
20
8
I'd love to see control codes for:

  • move cursor position; <move><row><col> - If <move> were $02, then a chr$(2);chr$(0);chr$(0) would home the cursor. Any <row>,<col> outside of the range of the current screen size would be truncated to edge.
  • repeat character; <repeat><count><char> - if <repeat> were $82, then a chr($82);chr$(14);"A" would print 14 A's.
This would request a byte of kernal vars to hold the current state of the output, something like:

  • 0 = normal state, not escaped
  • 1 = next byte is row position for a <move>
  • 2 = next byte is col position for a <move>
  • 3 = next byte is a <repeat> count
  • 4 = next byte is a petscii character to be <repeat>ed.
This way you could move left 20 positions relative with a <repeat><20><crsrleft> or move absolute with <move><row><col>.

It might be simpler to add a GOTORC, MOVECRSR, or some BASIC command for absolute cursor movement.

Perhaps some simple VT52 style ESC codes could be implemented as well.
 
  • Like
Reactions: BruceMcF

BruceMcF

Active Member
May 19, 2019
177
53
28
I'd love to see control codes for:

  • move cursor position; <move><row><col> - If <move> were $02, then a chr$(2);chr$(0);chr$(0) would home the cursor. Any <row>,<col> outside of the range of the current screen size would be truncated to edge.
  • repeat character; <repeat><count><char> - if <repeat> were $82, then a chr($82);chr$(14);"A" would print 14 A's.
This would request a byte of kernal vars to hold the current state of the output, something like:

  • 0 = normal state, not escaped
  • 1 = next byte is row position for a <move>
  • 2 = next byte is col position for a <move>
  • 3 = next byte is a <repeat> count
  • 4 = next byte is a petscii character to be <repeat>ed.
This way you could move left 20 positions relative with a <repeat><20><crsrleft> or move absolute with <move><row><col>.

It might be simpler to add a GOTORC, MOVECRSR, or some BASIC command for absolute cursor movement.

Perhaps some simple VT52 style ESC codes could be implemented as well.
Though that state of output is one reason they may be reluctant to do that. Once you have an escape string state, then you have errors for entering something that is not a valid input, and then you have to add that error handling. With stateless cursor controls, every input is meaningful (even if it doesn't always mean what we thought it meant when we programmed it).

The stateless ways to speed up a lot of the longer cursor movements are to have fixed jumps and/or to have "halfscreen right/left/up/down", where you go half the distance to the edge in the direction you are pointed. <HOME><HSDN><HSRT> and you are in the middle of the screen.

Neither are as optimal as <ESC>'['<8>';'<54>'H' ... a 6 byte escape sequence to get to an arbitrary column/line on screen (assuming mono-width fonts), but the only state is requires is the current cursor position, so if the screen is 80x24 (where VT100 is one-based indexing):

Stateless without speedups:

<HOME><CRD><CRD><CRD><CRD><CRD>
<CRR><CRR><CRR><CRR><CRR><CRR><CRR><CRR><CRR><CRR>
<CRR><CRR><CRR><CRR><CRR><CRR><CRR><CRR><CRR><CRR>
<CRR><CRR><CRR><CRR><CRR><CRR><CRR><CRR><CRR><CRR>
<CRR><CRR><CRR><CRR><CRR><CRR><CRR><CRR><CRR><CRR>
<CRR><CRR><CRR><CRR><CRR><CRR><CRR><CRR><CRR><CRR>
<CRR><CRR><CRR>
... 59 cursor characters.

Or if <EOL> is available on a 80 column by 24 line display:
<HOME><DN><DN><DN><DN><DN>
<EOL><CRL><CRL><CRL><CRL><CRL><CRL><CRL><CRL><CRL><CRL>
<CRL><CRL><CRL><CRL><CRL><CRL><CRL><CRL><CRL><CRL>
<CRL><CRL><CRL><CRL><CRL><CRL>
... 33 characters.

With HS characters:

<HOME><HSDN><HSUP><HSRT><HSRT> gets you to 6 down and 60 across, so the:

<HOME><HSDN><HSUP><CRD><CRD><HSRT><HSRT><CRL><CRL><CRL><CRL>
... 11 cursors characters.

With horizontal tabstops every eight columns and vertical tabstops every eight lines, that is:

<HOME><VT><CRU><CRU><TAB><TAB><TAB><TAB><TAB><TAB><TAB><CRR><CRR>
... 13 cursor characters.

<VT> and <HT> have the advantage that they are only two characters and are already defined control codes. They also turn the screen into 8x8 zones, 10 across and 6 down, so if you organize your display so that a place you are going a lot is on a horizontal and vertical tabstop, it becomes very efficient.
 
Last edited:
  • Like
Reactions: codewar65

codewar65

Member
Sep 25, 2019
36
20
8
I've written several terminal emulators and a few ANSI art programs over the years, and I'd just do what is normal with malformed ANSI sequences, values out of range get capped, or abort the sequence and reset state to 0.

So a bad VT52 sequence (e.g.: ESC X) would just reset state to 0 and output 'X' (ignoring the ESC).
 
Last edited:

rje

New Member
Nov 6, 2019
15
2
3
I think the only thing we need to provide TERMCAP-like behavior is a BASIC command to position the cursor on the screen.

I've had to write a subroutine that does this for me.
 
  • Like
Reactions: grommile

BruceMcF

Active Member
May 19, 2019
177
53
28
I've written several terminal emulators and a few ANSI art programs over the years, and I'd just do what is normal with malformed ANSI sequences, values out of range get capped, or abort the sequence and reset state to 0.

So a bad VT52 sequence (e.g.: ESC X) would just reset state to 0 and output 'X' (ignoring the ESC).
Not saying they are shying away from adding sequences that require adding an error handling routine because it's a hard task, but because it's an additional task, and they have plenty of tasks on their plate already. Just as an outsider looking in, a cursor plot routine, made available through a cursor plot keyword, seems more likely to me than embedded escape sequences.
 
Last edited:
May 22, 2019
549
283
63
I think the only thing we need to provide TERMCAP-like behavior is a BASIC command to position the cursor on the screen.

I've had to write a subroutine that does this for me.
Right. The LOCATE command has been a staple of Microsoft BASIC since 1981. It's been in all variants of PC BASIC since then, and it really ought to be in Commander BASIC.
 
  • Like
Reactions: BruceMcF
May 22, 2019
549
283
63
Not saying they are shying away from adding sequences that require adding an error handling routine because it's a hard task, but because it's an additional task, and they have plenty of tasks on their plate already. Just as an outside looking in, a cursor plot routine, made available through a cursor plot keyword, seems more likel to me than embedded escape sequences.
Agreed. There are currently no terminal sequences in PETSCII; adding one just to support cursor movement (when there already is a method of doing so) seems like a lot of work for little gain. All Michael needs to do is add the LOCATE command, which is just a wrapper for the KERNAL PLOT routine.
 
  • Like
Reactions: BruceMcF