Page 1 of 1

Undocumented Screen Controls

Posted: 04 Jan 2020 22:47
by Bill B
I have been looking at the ROM code for screen handling and have discovered a few character sequences that can be used to control the screen, that are not documented in either version of the MTX manual:
  • <Ctrl+X> - Sets white text on a black background.
  • <Esc>, "L" - Reads the character under the cursor and stores the ASCII code in (WKAREA) (0xFE1A). This is equivalent to SPK$ except for how it returns the result. What is interesting is that it will work even for the graphics screen, where the VDP does not have the ASCII code. In this case it works by matching the bit pattern at the cursor against the text pattern table.
  • <Esc>, "R", cc - Where cc = 16 * paper + ink. Sets the printing colours as specified and clears the printing attributes.
  • <Esc>, "U", 0xFF - Resets virtual screens 0, 1, 4, 5 & 7 to their default states. Reloads the text pattern table. Selects VS 4 (Graphics screen) and clears the screen.
  • <Esc>, "V", 0xFF - Resets virtual screens 0, 1, 5 & 7 (text screens) to their default states for Basic. Leaves virtual screen 5 selected.
  • <Esc>, "W", 0xFF - Resets virtual screens 0, 1, 5 & 7 (text screens) to their states for PANEL. Leaves virtual screen 5 selected.
For the last three, if the third byte is anything other than 0xFF ( CHR$(255) ) the result is "SE.B".

I expect that the ROM makes use of most of these elsewhere in the code, but <Ctrl+X> is a strange one.

Re: Undocumented Screen Controls

Posted: 05 Jan 2020 23:48
by Bill B
Looking further into the screen handling code I have uncovered an obscure but real bug in the MTX ROM.

It is in ROM 1:

Code: Select all

39B0 F1           crscr2:	POP	AF
39B1 AF           		XOR	A
39B2 BA           		CP	D
39B3 28 FB        		JR	Z, crscr2
39B5 BB           		CP	E
39B6 28 F8        		JR	Z, crscr2
It is triggered if you do a CRVS statement with either the width (parameter 5) or height (parameter 6) set to zero. The above code is then entered with D = height and E = Width. If either of these are zero, then since A is zeroed by the XOR statement, the comparison will always set the zero flag, and the code will go round and around, repeatedly popping values from the stack.

The loop will eventually get broken when an interrupt occurs while the stack pointer is pointing to ROM. But what happens then depends upon exactly where the stack pointer is when the interrupt occurs.

I guess that the crscr2 label was originally somewhere else, leading to an error message, and then this section of code was re-labelled and these jumps were overlooked.