ZX81: zx_setstr() does not cut existing longer strings correctly

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

ZX81: zx_setstr() does not cut existing longer strings correctly

Post by siggi »

Test program:

Code: Select all

void main(void)
{
        char buffer[60];
        zx_setstr('a', "longlonglong");
        zx_getstr('a', buffer);
        printk("a=%s\n", buffer);

        zx_setstr('a', "short");
        zx_getstr('a', buffer);
        printk("a=%s\n", buffer);
}
Result on ZX81 is:

Code: Select all

A=LONGLONGLONG
A=SHORTO
The new length of the BASIC string is not set correctly. The same happens also, when the BASIC variable A$ is set (inside a BASIC line) during calls of zx_line()

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

Post by siggi »

Addendum:
BASIC shows the correct string "SHORT". LEN gives also the correct result 5.
?????
Siggi
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

The function zx_getstr() seems to be buggy and returns one more char than BASIC, when printing the string variable. If crashes, when the string variable is empty ("").

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

Post by siggi »

The reason for the crash of "zx_getstr" caused by string length 0 is caused by check of the string length AFTER it has been copied to the destination:

Code: Select all

.outloop
        call        zx81toasc
        ld        (de),a
        inc        hl
        inc        de
        dec        bc
        ld        a,b
        or        c
        jr        nz,outloop
Thus string length 0 copies 64K ...

Now l am looking for the additional character at end of the string ....

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

Post by siggi »

The additional char at end of the string is caused by double incrementing DE at end of the string:

Code: Select all

.outloop
        call        zx81toasc
        ld        (de),a
        inc        hl
        inc        de
        dec        bc
        ld        a,b
        or        c
        jr        nz,outloop
;------------------------------
;        ldir
        inc        de
        xor        a
        ld        (de),a
        
        ld        hl,0
        ret
The last "inc de" is one increment too much...

Siggi
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

Thanks Siggi, I've applied that fix.
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

But the problem of string length 0, resulting in a crahs (see my posting before) seems not to be solved ...

IMHO this should solve that problem:

Code: Select all

;-----------------------------
.outloop
        ld a,b
        or c
        jr z,strend 
        call        zx81toasc
        ld        (de),a
        inc        hl
        inc        de
        dec        bc
;        ld        a,b
;        or        c
        jr        outloop
;------------------------------
;        ldir
.strend
        xor        a
        ld        (de),a
        
        ld        hl,0
        ret
Siggi
siggi
Well known member
Posts: 344
Joined: Thu Jul 26, 2007 9:06 am

Post by siggi »

And then the "xor a" (at strend) could be replaced by the comment ";a is already 0 here", saving 1 byte ;-)

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

Post by siggi »

zx_setstr() is also buggy and does also handle strings of length 0 not correct.
Test program:

Code: Select all

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

void main(void)
{
    in_WaitForNoKey();
    printk("press any key to continue\n");
    in_WaitForKey();
    zx_setstr('a', "");
    printk("done\n");
}
After the program has been run, PRINT A$ (at BASIC level) gives "DONE?"

Siggi
Post Reply