Forum
Weird bug involving OVER 1 (*solved*) - Printable Version

+- Forum (https://www.boriel.com/forum)
+-- Forum: Compilers and Computer Languages (https://www.boriel.com/forum/forumdisplay.php?fid=12)
+--- Forum: ZX Basic Compiler (https://www.boriel.com/forum/forumdisplay.php?fid=11)
+---- Forum: Bug Reports (https://www.boriel.com/forum/forumdisplay.php?fid=15)
+---- Thread: Weird bug involving OVER 1 (*solved*) (/showthread.php?tid=618)



Weird bug involving OVER 1 (*solved*) - einar - 11-02-2014

ZX BASIC has some weird bug involving OVER 1. Unfortunately I was unable to isolate this problem to produce a short example, so I will have to provide my full source code...

The ZEN source code is available here:

<!-- m --><a class="postlink" href="https://www.dropbox.com/sh/bgtoq6tdwropzzr/AAAknv_0PeJGhn36dLJZfGASa">https://www.dropbox.com/sh/bgtoq6tdwrop ... 6dLJZfGASa</a><!-- m -->

Right at the beginning, you will notice it sets ATTR_P to INK 0:

Code:
INK 0: PAPER 0: FLASH 0: BRIGHT 0: CLS

Afterwards it never sets a different INK, except for a single PRINT statement at the end of this sub-routine:

Code:
sub drawTile(row AS UBYTE, col AS UBYTE, color AS UBYTE)
    DIM tile AS UBYTE
    DIM ch AS UBYTE

    LET tile = PEEK BOARD(row, col)
    IF tile = 0 THEN
        IF row=0 AND col=width THEN
            OVER 1
        ELSEIF color=2 THEN
            LET tile = 16
        END IF
    END IF
    LET ch = (tile<<2)+32
    POKE UINTEGER 23606, @zenchr-256
    INK color
    PRINT AT row0+(row<<1), col0+(col<<1); CHR$(ch);CHR$(ch+1);AT row0+(row<<1)+1, col0+(col<<1);CHR$(ch+2);CHR$(ch+3);:
    INK 0
    OVER 0
end sub

An obvious optimization would be setting a temporary INK inside this PRINT statement, instead of using a separate INK statement before, and another INK 0 immediately afterwards. Right? Unfortunately that won't work! Try it yourself. Replace these lines:

Code:
INK color
    PRINT AT row0+(row<<1), col0+(col<<1); CHR$(ch);CHR$(ch+1);AT row0+(row<<1)+1, col0+(col<<1);CHR$(ch+2);CHR$(ch+3);:
    INK 0
    OVER 0

with this:

Code:
PRINT INK color; AT row0+(row<<1), col0+(col<<1); CHR$(ch);CHR$(ch+1);AT row0+(row<<1)+1, col0+(col<<1);CHR$(ch+2);CHR$(ch+3);:
    OVER 0

If you recompile ZEN with this change, parts of the board will be disappearing on screen. If you analyze the screen when it happens, you will notice the INK colors are correct on screen, but the pixels are missing. Therefore this PRINT statement is apparently using OVER 1 even in cases where OVER 1 wasn't set.

This bug is not relevant for me anymore since I have already released this game anyway, but it demonstrates ZX BASIC has some bug involving OVER 1 that may affect other developers in the future.


Re: Weird bug involving OVER 1 - boriel - 11-02-2014

einar Wrote:ZX BASIC has some weird bug involving OVER 1. Unfortunately I was unable to isolate this problem to produce a short example, so I will have to provide my full source code...

The ZEN source code is available here:

<!-- m --><a class="postlink" href="https://www.dropbox.com/sh/bgtoq6tdwropzzr/AAAknv_0PeJGhn36dLJZfGASa">https://www.dropbox.com/sh/bgtoq6tdwrop ... 6dLJZfGASa</a><!-- m -->

Right at the beginning, you will notice it sets ATTR_P to INK 0:

Code:
INK 0: PAPER 0: FLASH 0: BRIGHT 0: CLS

Afterwards it never sets a different INK, except for a single PRINT statement at the end of this sub-routine:

Code:
sub drawTile(row AS UBYTE, col AS UBYTE, color AS UBYTE)
    DIM tile AS UBYTE
    DIM ch AS UBYTE

    LET tile = PEEK BOARD(row, col)
    IF tile = 0 THEN
        IF row=0 AND col=width THEN
            OVER 1
        ELSEIF color=2 THEN
            LET tile = 16
        END IF
    END IF
    LET ch = (tile<<2)+32
    POKE UINTEGER 23606, @zenchr-256
    INK color
    PRINT AT row0+(row<<1), col0+(col<<1); CHR$(ch);CHR$(ch+1);AT row0+(row<<1)+1, col0+(col<<1);CHR$(ch+2);CHR$(ch+3);:
    INK 0
    OVER 0
end sub

An obvious optimization would be setting a temporary INK inside this PRINT statement, instead of using a separate INK statement before, and another INK 0 immediately afterwards. Right? Unfortunately that won't work! Try it yourself. Replace these lines:

Code:
INK color
    PRINT AT row0+(row<<1), col0+(col<<1); CHR$(ch);CHR$(ch+1);AT row0+(row<<1)+1, col0+(col<<1);CHR$(ch+2);CHR$(ch+3);:
    INK 0
    OVER 0

with this:

Code:
PRINT INK color; AT row0+(row<<1), col0+(col<<1); CHR$(ch);CHR$(ch+1);AT row0+(row<<1)+1, col0+(col<<1);CHR$(ch+2);CHR$(ch+3);:
    OVER 0

If you recompile ZEN with this change, parts of the board will be disappearing on screen. If you analyze the screen when it happens, you will notice the INK colors are correct on screen, but the pixels are missing. Therefore this PRINT statement is apparently using OVER 1 even in cases where OVER 1 wasn't set.

This bug is not relevant for me anymore since I have already released this game anyway, but it demonstrates ZX BASIC has some bug involving OVER 1 that may affect other developers in the future.

This bug is more important than the optimizer one. Will check it ASAP :!:


Re: Weird bug involving OVER 1 - einar - 11-02-2014

boriel Wrote:This bug is more important than the optimizer one. Will check it ASAP :!:

Let me take this chance to emphasize how much I appreciate your ZX BASIC support. This game ZEN is a good example. I originally wrote it in another programming language but didn't get the necessary support for bugs I found, so I converted it to ZX BASIC instead. I mentioned it here:

<!-- m --><a class="postlink" href="http://www.worldofspectrum.org/forums/showpost.php?p=797677&postcount=5">http://www.worldofspectrum.org/forums/s ... ostcount=5</a><!-- m -->

The opposite never happened. I'm not saying ZX BASIC is flawless, but whenever I reported a serious bug, it was always fixed really fast. Thank you!


Re: Weird bug involving OVER 1 - einar - 07-23-2015

It took me ages, but I finally managed to isolate this bug.

Here's a simple test program to reproduce this issue:

Code:
sub printA()
    PRINT AT 5,5;PAPER 6;INK 1;"A";
end sub

sub printBs()
    FOR f=9 TO 11
        PRINT INK 2;AT f,5;OVER 1;"B";
    NEXT f
end sub

INK 0: PAPER 0: CLS
printA()
printBs()

Both "A" and the first "B" will be printed with yellow background, the remaining 2 "B" will be printed with black background. However every "B" was supposed to have the same color!

Tested with several ZX BASIC versions (including latest version 1.4.0s1912), with different compiler optimization levels, on different ZX-Spectrum models. It never provided the correct result.


Re: Weird bug involving OVER 1 - boriel - 07-23-2015

I think it's fixed now. This bug didn't involve OVER 1 in the end but ATTRibute restoration after ; within a subroutine (yes, a strange case!)
Can you download ZX Basic version 1.4.0s1913 and check if it works? :roll:


Re: Weird bug involving OVER 1 - einar - 07-28-2015

It works, thanks a lot!!!