Ansi - printing at bottom right corner causes scroll up

Bug reports (if you don't/won't have a Github account)
Post Reply
rkd77
Member
Posts: 50
Joined: Sun May 04, 2008 10:35 am

Ansi - printing at bottom right corner causes scroll up

Post by rkd77 »

Here is an example code:

Code: Select all

/* zcc +zxansi ... */
#include <input.h>
#include <stdio.h>

void
print_at(unsigned char y, unsigned char x)
{
        printf("\033[%d;%dH", y+1, x+1);
}

int
main(void)
{
        int i,j;

        for (j = 0; j < 23;j++) {
                print_at(j, 0);
                printf("%d", j);
        }
        print_at(23, 0);
        for (j = 0; j < 64; j++) putchar('a');
        in_WaitForKey();
        print_at(0, 0);
        printf("B");
        in_WaitForKey();
        return 0;
}
If the cell 23,63 (counting from zero) is written then it scrolls up the screen, even if the next print is "a move of the cursor".
IMO it is a bug.
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

It sounds like the driver should be checking the cursor position before a char is printed rather than after.
rkd77
Member
Posts: 50
Joined: Sun May 04, 2008 10:35 am

Post by rkd77 »

Code: Select all

Index: f_ansi_putc.asm
===================================================================
RCS file: /cvsroot/z88dk/z88dk/libsrc/stdio/ansi/f_ansi_putc.asm,v
retrieving revision 1.2
diff -u -r1.2 f_ansi_putc.asm
--- f_ansi_putc.asm     13 Apr 2001 14:13:59 -0000      1.2
+++ f_ansi_putc.asm     15 Jul 2013 10:20:21 -0000
@@ -21,14 +21,15 @@
 
 
 .ansi_putc
- 
- call ansi_CHAR
+ push af
  ld a,(text_cols)
  ld d,a
  ld a,(ansi_COLUMN)
+ cp d          ; last column ?
+ call nc,ansi_LF; yes
+ pop af
+ call ansi_CHAR
+ ld a,(ansi_COLUMN)
  inc a
  ld (ansi_COLUMN),a
- cp d          ; last column ?
- ret nz                ; no, return
- jp ansi_LF
-
+ ret
stefano
Well known member
Posts: 2151
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

It is much simpler of the change I was preparing, so I took yours.
einar
Member
Posts: 47
Joined: Fri Sep 06, 2013 4:23 pm

Post by einar »

Bump!

It seems this bugfix didn't work.

The following program:

Code: Select all

// zcc +zx -lm -lndos -create-app prog.c -oprog.bin

#include <stdio.h>

#define printMode(mode)      printf("\x01%c", (mode))
#define printCls()           printf("\x0c")
#define printPaper(k)        printf("\x11%c", '0'+(k))
#define printAt(row, col)    printf("\x16%c%c", ' '+(row), ' '+(col))

void main(void)
{
    printMode(32);
    printCls();
    zx_border(0);
    printPaper(4);
    printAt(23,31);
    putchar('a');
    while (1);
}
Produces the following result:

Image

Therefore it's impossible to use the lower right corner without scrolling the entire screen.

Tested using both latest stable release (version 1.10.1) and latest nightly build. The same problem happens on both.
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

bump -- bug mentioned again
stefano
Well known member
Posts: 2151
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

I'll have a look.
stefano
Well known member
Posts: 2151
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Bug analysis result: the bugfix suggested by rdk77 is working correctly.
It fixes the ANSI VT emulation, (-clib=ansi option). The native ZX libraries still suffer this problem; I'm trying to find a neat solution capable to cover all the similar targets (ts2068, zx81, TI calculators, etc..).
stefano
Well known member
Posts: 2151
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

The vanilla Spectrum should now be fixed. The only missing candidate is the TS2068, for some reason the same workaround seems to let the function in an unstable condition; probably it is just a register getting dirtied somewhere.
TI calculators and Others are not strictly connected to this code. For the record, the ANSI VT related fix impacts all of them.
einar
Member
Posts: 47
Joined: Fri Sep 06, 2013 4:23 pm

Post by einar »

Thank you!
stefano
Well known member
Posts: 2151
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Now the TS2068 target should be fixed too.
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

The compiler build I downloaded at 2. May has the same problem in ZX81 TEXT(!) mode (ZX81 ANSI mode is working).

Siggi
stefano
Well known member
Posts: 2151
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

I expected it, but I hoped you didn't notice that :P
Ok Ok, back to the console support code..
stefano
Well known member
Posts: 2151
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Crossing fingers it should be all right now.. please update your CVS tree or wait for the nightly process.
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

Hi Stefano
the problems seems to be solved: printing to lower right postion does not scroll. Thanks

But there is another problem:
that program:

Code: Select all

// zcc +zx81  -vn -create-app -startup=2 test.c -o test.bin
#include <stdio.h>
main()
{
 int a;
 for (a=0; a < 4; a++)
 {
    printf("a=%d\n", a);
    printf("12345678901234567890123456789012");
    printf("12345678901234567890123456789012\r");
    printf("12345678901234567890123456789012\n");
 }

}
gives that output:

Code: Select all

A=0                             
12345678901234567890123456789012
12345678901234567890123456789012
                                
12345678901234567890123456789012
                                
A=1                             
12345678901234567890123456789012
12345678901234567890123456789012
                                
12345678901234567890123456789012
                                
A=2                             
12345678901234567890123456789012
12345678901234567890123456789012
                                
12345678901234567890123456789012
                                
A=3                             
12345678901234567890123456789012
12345678901234567890123456789012
For each 'a' there a 2 empty lines, which I did not expect:
after the first printf("123..") the Zeddy performs an automatic linefeed (OK)
after each next printf("123..") the Zeddy performs an automatic linefeed and the linefeed given by '\n' and '\r', resulting in an empty line.
Is that behaviour correct? IMHO no ...

Siggi
stefano
Well known member
Posts: 2151
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

The cr/lf behaviour is, one of the well known ancient compatibility problems between different computers.

Since the minimalistic console output was often bound to the internal ROM implementations we followed the frequent approach to keep (or, for cross-compatibility, to add where missing) an automatic linefeed to the "\r" control code. In several cases we weren't able to split the codes, by the way. For the same reason lower care was taken for the non-ANSI LineFeed control code.
Even the ANSI VT emulation has the automatic CR, I think !

What would you expect the libraries do ? I think this is a good moment to discuss it, given the Alvin's big work being done..
stefano
Well known member
Posts: 2151
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Ok I also understood what you REALLY mean (sorry, this is consequence of my bad way to manage my time slots).
I'm not sure this is a wrong behaviour, I need to peep at some documentation around.. (a ZX81 BASIC program would do exactly the same).
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

stefano wrote:(a ZX81 BASIC program would do exactly the same).
Of course not!

Here is the equivalent BASIC program and its output. Since BASIC does not know '\n' nor '\r', lines 40 and 50 don't have a trailing ';' to force a "new line"

Code: Select all

            10 FOR A=0 TO 3
            20 PRINT "A=";A
            30 PRINT "12345678901234567890123456789012";
            40 PRINT "12345678901234567890123456789012"
            50 PRINT "12345678901234567890123456789012"
            60 NEXT A



          A=0
          12345678901234567890123456789012
          12345678901234567890123456789012
          12345678901234567890123456789012
          A=1
          12345678901234567890123456789012
          12345678901234567890123456789012
          12345678901234567890123456789012
          A=2
          12345678901234567890123456789012
          12345678901234567890123456789012
          12345678901234567890123456789012
          A=3
          12345678901234567890123456789012
          12345678901234567890123456789012
          12345678901234567890123456789012
And that ia also is my expected behaviour!

The rules are (in my opinion)
1. if the user requests a new-line, this thould be done.
2. if the computer detects, that the user tries to write past end of the line, it may insert an automatic new-line
3. if the user requests a new-line and the computer also want's to insert a new-line, only one new-line should be written

So before an automatic new-line is performed by the computer, it should check, whether the user wants to write more chars (then automatic new-line is OK), or requests himself a new-line (so no additional automatic new-line should occur).

Siggi
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

stefano wrote:What would you expect the libraries do ? I think this is a good moment to discuss it, given the Alvin's big work being done..
In the new clib this is what happens:

Image

and I think this is what siggy is expecting.

It has to do with when the coordinates are checked for being out of bounds. I moved all checking to just before a char is printed. So in the case where '\n' is sent, the cursor is out of bounds but '\n' just moves down one line and to column zero without checking bounds (except for possible scroll of course).

The \r\n stuff is a huge headache because it varies from target to target. Most old z80 machines do not have two separate characters for text linefeed and instead send a single on - CHR$ 13. 13 maps to \r in ascii but all C programs are written using \n to advance line. What's happened is sccz80 has aligned with most of its targets so that \r\n are reversed in character code :- \r=10, \n=13. sdcc, oth, sticks to ascii and has \r=13, \n=10, sending ascii code 10 to advance to the next line which is not understood by most targets.

So what's done in the new clib is there is a clib character set where CHAR_CR ('\r') and CHAR_LF ('\n') are assigned ascii codes differently depending on which compiler is running. Under sdcc, CHAR_LF=10 and under sccz80 CHAR_LF=13. The clib treats CHAR_LF as the linefeed character in its code. The low level driver is responsible for translating native characters (like ENTER=13) to the clib char set (CHAR_LF).

Some programs only send \r (like your dangling example) or \r\n or \n to advance the line. So with a \r the new clib waits to see if a \n comes along and if not it treats an isolated \r like linefeed. If \r\n comes along, only one linefeed is generated. If \n is on its own, one linefeed is on its own. I can't remember what I did with \n\r but I think I did that case too.
Post Reply