ZX81: C console print position does not match BASIC print position

Bug reports (if you don't/won't have a Github account)
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

ZX81: C console print position does not match BASIC print position

Post by siggi »

My current problem is: I have an USB driver, which writes to screen using RST 10 (and using the print position stored in BASIC system variables.
But the simple console driver (LOWRES) of Z88DK holds its own print position, so printing of the driver and printing of my C program (printf in LOWRES, not ANSI) may overwrite the other text, making screen handling not easy :-(

The C-console driver should use the BASIC system variables to hold its cursor position. Then I could use the ROM call PRINT_AT for cursor positioning (like in BASIC), which is not supported by the simple C-console driver.

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

Post by stefano »

Fixed.
Try also the 1 bit sound functions ;)
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

Thanks Stefano.
I will test it in some days, when I have finished the current program with builtin workarounds for that problem ...

Siggi
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

Hi Stefano,
the bugfix does not work as (I) expected ;)

I wrote a BASIC and C program: the C program writes a 'C' to screen, the BASIC writes 'B' next to the C. The expected output should be
"BCB"

But the 'C' is always overwritten by the 'B'. So the output is
"BB"

Maybe the C-program does not set the system variable
"16398 DF_CC Address of PRINT position in display file."
correctly?

Here my test programs

Code: Select all

//zcc +zx81 -startup=2 -create-app -vn -o test.bin test.c
#include <stdio.h>

void main(void)
{
    putchar('C');
}
and

Code: Select all

10 PRINT "B";
20 RAND USR 16514
25 PAUSE 100
30 PRINT "B"
Siggi


Addendum:
Perhaps you could put these 2 functions into the ZX81 lib?

Code: Select all

void zx_cls(void)
{
    putchar(12);
}

void zx_print_at(unsigned char line, unsigned char column)
{
#asm
    XREF restore81
    call  restore81
    pop hl; address
    pop bc; column into C
    pop de; line
    push de
    push bc
    push hl
    ld b,e; line into B
    jp 0x8F5
#endasm
}
Last edited by siggi on Thu Nov 17, 2011 3:34 pm, edited 1 time in total.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

I thought I replied already, but I can't see my post, so I'm writing it again.

I slightly improved fputc_cons to make the BASIC cursor follow me when I print a character *only*.
CR and LF could not behave as expected, and there is a known bug when a character is being printed in the last column (BASIC won't be able to insert the needed <CR>).

On the other side it costs three bytes only :P


zx_cls() now is implemented, I definitely prefer my fast screen fill code to the ROM CLS.
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

Printing of CR+LF is IMHO equivalent to

ld a, $76
rst $10

and this works fine in assembler to terminate a line compatible to BASIC.

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

Post by stefano »

Not so easy.. the ZX81 is not able to scroll automatically.
Ok, I'll do my best to complete the integration.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

try now ;)
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

Thanks :)

Siggi
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

stefano wrote:zx_cls() now is implemented, I definitely prefer my fast screen fill code to the ROM CLS.
I just had a crash, when I loaded Bodo's "25thanni.p" with my USB FILE MANAGER written in C from the USB stick.
The problem is, that my UFM expects an expanded display file (line length 32 + HALT), but Bodos P-file was not saved by a ZX81, but generated directly from assembler, having a collapsed display file (consists only of HALTs).

The ROM CLS routine can handle a collapsed display file, so I could call it to expand a collapsed display file to an expanded, which then would be fit to my UFM. But the (faster) "screen fill code" does not support that.

So the ROM CLS routine is slower, but safer to use ..

Siggi

Edit:
Perhaps you could change the CLS routine in such a way:
if the DFILE has its expected size
then
call fast fill routine
else
call ROM CLS (to expand the DFILE)
Last edited by siggi on Sat Nov 26, 2011 11:25 am, edited 1 time in total.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Siggi, we are supporting the collapsed D-file too as an option for the packager so I know what you do mean.
I never thought at this situation because the packager does not insert the auto-run option in the filename... as soon as the user RUNs the program the screen is expanded automatically.
Ok, I'll have a look..
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

I hope the compromise makes everyone happy: zx_cls() now calls the ROM code and permits auto_expansion of the collapsed d-file, while the whole console stuff including clearing screen with chr$ 12 is optimized for full d-file only.
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

Hi Stefano,
there is still a problem when mixing C and BASIC printing:
I used the latest build of Z88DK to compile my UFM, which uses the C print routines. But the USB driver, that is called by UFM, uses the BASIC print environment (RST 10).
I used zx_cls() before calling the driver. After return form the driver the behaviour of UFM was wrong: the screen got out of sync, when I pressed a key.

The problem was solved, after I added a "putchar (12)" after the zx_cls() call. So putchar(12) seems to affect other variables compared to zx_cls(). IMHO both routines should set the print position to upper left corner and the difference should only be in speed and expansion of a collapsed D-FILE.

Siggi

Edit: no, the D-FILE was still expanded after the driver call.
Last edited by siggi on Wed Nov 30, 2011 7:50 pm, edited 1 time in total.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Ok ok, it could depend on the location entry I'm using with zx_cls.
I'll try by forcing the env. variables.
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

stefano wrote:Ok ok, it could depend on the location entry I'm using with zx_cls.
The current entry to ROM (jp $a2a) is ok: I used also this call with elder Z88DK versions.
I'll try by forcing the env. variables.
You should NOT add additional code to zx_cls() to solve that problem, because anybody can still call the ROM directly without using zx_cls (e. g. when I compile older C-programs, which do not know about zx_cls()).
Please do changes only in the "putchar(12)" routines. No one would call them directly ...

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

Post by stefano »

Siggi, I'm sorry but I got your message after putting the latest changes online.
Please have at least a look at zx_setcursorpos(x,y), it is meant for (0;0) at top-left.
At the moment that fix is in place, it was useful for other functions (i.e. to place the cursor at top-left after scrolling down the text).
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

Hmm, the linker says: "Error in expression _ZX_SETCURSORPOS" ...
In which lib is it included?

Should it work also in ANSI mode?

Siggi

Edit:
Upps: it was not the linker. The error message is:

Code: Select all

2 errors occurred during assembly
Key to filenames:
C:\DOKUME~1\Engel\LOKALE~1\Temp\s5a8_.o = ufm-driver.c
File 'C:\DOKUME~1\Engel\LOKALE~1\Temp\s5a8_.asm', Module 'UFM', Symbol not defin
ed
Error in expression _ZX_SETCURSORPOS

File 'C:\DOKUME~1\Engel\LOKALE~1\Temp\s5a8_.asm', Module 'UFM', Symbol not defin
ed
Error in expression _ZX_SETCURSORPOS
Last edited by siggi on Tue Dec 20, 2011 10:28 am, edited 1 time in total.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

I tested it in "-startup=2" mode.
If you are in the same mode then I must have forgot a file or a declaration somewhere; I agree it should work also in ANSI mode (even if obviously on the standard TEXT page).
I'll check it the next week
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

I'm not sure where the problem was, please verify that with the last update the error does not appear anymore and test the console stuff.
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

Now there is no error during compiling.

I found, that the parameters of zx_setcursorpos(x,y) are different to the basic PRINT AT:
PRINT AT x, y prints to line x and column y, while zx_setcursorpos(x,y) prints to column x and line y.
So line/column is swapped.
Is that an intended behaviour?

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

Post by stefano »

wow.. no !
Good, I'll fix this too, sorry for the mess.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

x,y swap done, please try now.
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

Hmm, UFM and that test program both crash with the latest build :-(

Code: Select all

#include <stdio.h>
main(void)
{
    zx_setcursorpos(0,0); printf("1");
    zx_setcursorpos(21,0); printf("2");
    zx_setcursorpos(0,30); printf("3");
    zx_setcursorpos(21,29); printf("4");
}
Siggi
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

I still have major problems when mixing BASIC and C "screens":
I currently write an NFM (Network Filemanager) to load/save programs via Ethernet.

I am using routines to do that, which I used already in older programs (to load programs from USB sticks or FAT32 MMC cards) and they worked (with older z88dk versions). Now, when I am loading a file, I often have crashes or corrupted screens :-(

The problem is: when I load a new program (my NFM is running above 32K) , the current DFLILE is overwritten by the new program, thus the DFILE and is located on a new position and the print positions (absolute positons) do not match any more.
I tried to clear the new screen (using first the ROM routine to expand a possibly collapsed DFILE) and also do a putchar(12) to clear the "C screen" (and to reset the print position maybe used in C libs).
But that did not help ...
LOAD is done in FAST mode and the C slow routine is called after loading. But then the display is corrupted ..

Here is my code to load a P-file:

Code: Select all

int RunProgram(char * fname, int execute, char * address)
{
    char save_cd;  // usewd to save my CDFLAGS
    char retry = 0; /* hope that no retry is necessary */
    char is_prog = 0;
    unsigned int addr;
    int err;
    if (*address)
    {
        addr = atoi(address);
        execute = 0;
    }
    else
    {
        addr = PROG;
        is_prog = 1;
        if (!strchr(fname,'.'))
            strcat(fname,".P");
    }
#ifdef DEBUG
        printf("loading %s to %u\n", fname, addr);
#endif

    /* load during fast mode only! */
    ZX81Fast();
    save_cd = CDFLAGS;

#ifdef TEST_UI
    #asm
    ; on EO: copy P file from 50000 to 16393
    ld HL, 50000
    ld DE, 16393
    ld BC, 14000 ; leave space for stack
    ldir
    #endasm
#else
    do
    {
        err = load_file_tnfs(mount_point, fname, addr);
        if (err >= 0)
            {
                if (is_prog)
                {
                    /* plausi check for file end */
                    if (*(unsigned char *)(E_LINE-1) == 0x80) /* file end is as expected */
                    {
                        /* a new BASIC program is loaded */
                         CDFLAGS = save_cd; // restore my CDFLAGS
                    if(execute == '+')
                    {
                        C_exit();    /* abort C program, cleanup stack, goto BASIC */
                    }
                    else if (execute == '-')
                    {
                                     NXTLIN = 0; /* destroy autorun info */
                    }
                        ZX81Cls(); /* expand possibly collapsed D-File */
                        zx_cls();  /* clear C screen */
                    if (retry)
                        printf("Retries: %d\n", retry);
                    retry = 0;
                }
                    else
                    {
                            retry++;  /* retry */
                    }
           }
               }
               else
            return(err);
    }
    while (retry);
#endif
    return(EOK);
}
Any hints what I could do better?

Siggi
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

It seems, that now Z88DK does not keep the BASIC print position (stored in ZX81 system variables) in sync with the C print position (at least in text mode). I am using that code to prevent scrolling a big e-mail from screen before the user could read it:

Code: Select all

char lines @ 16442;

// Pause when screen gets full
int check_full(void)
{
    int ret_val = 0;
    if (lines < 4)
    {
        printf("\n<cr>");
        in_WaitForNoKey();
        if (getchar() != 13)
        {
           ret_val = -1;
        }
        zx_cls();
    }
    return ret_val;
}
That worked well in 2014 but no more today.

This little BASIC program shows the behavior of BASIC:

Code: Select all

10 input a
20 print at 1,0;peek 16442
Value a=20 gives result 4.

Siggi
Post Reply