Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Print color bug (*solved*)
#16
(10-09-2022, 06:30 PM)boriel Wrote: That's weird: the "system variable" core.SCREEN_ADDR is initialized with 16384, and core.SCREEN_ATTR_ADDR with 22528 respectively, and they are not modified anymore (in other words, all the instructions using these variables are read-only).
Are you sure that it's the PRINT routine? couldn't it be that a third party is corrupting that variable in some way?

The only other time that SCREEN_ATTR_ADDR is used is in this routine and that is read only:

Code:
Sub SetAttrs (ByVal Row as ubyte, ByVal Column as ubyte, ByVal NumberOfCells as uinteger)

Asm
  ld e, (ix+7)
  ld d, (ix+5)
  ld h, 0                     ;  7 T-States
  ld a, d                     ;  4 T-States
  add a, a     ; a * 2        ;  4 T-States
  add a, a     ; a * 4        ;  4 T-States
  ld l, a      ; HL = A * 4   ;  4 T-States
  add hl, hl   ; HL = A * 8   ; 15 T-States
  add hl, hl   ; HL = A * 16  ; 15 T-States
  add hl, hl   ; HL = A * 32  ; 15 T-States
  ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone)
  add hl, de
  ld de, (.core.SCREEN_ADDR)    ; Adds the screen address
  ;ld de, (SCREEN_ADDR)    ; Adds the screen address
  add hl, de
  ld b, (ix+8)
  ld a, (23693)
  SetAttrCopy:
  ld (hl), a
  inc hl
  djnz SetAttrCopy
End asm

End sub

The output from this routine is always right regardless if the workaround is employed or not which means it is not dependent on the attr address and it does not modify it. However that output from the print routine is in the wrong color. The screen is set to black paper and white ink and then the screen is switched to another place in memory and then a print command in blue paper and yellow ink but the blue and yellow does not take. It is printed in the original colors of black and white. Then the screen is copied to another screen where it is printed on some more and then it is copied to screen 16384 or screen0. The only way to get the right colors is to employ the workaround.

My routine above always works and the print routine does not and not other routines in my program mess with my screen other than the routine that sets the screen that I have posted before.

So this is a bug in the compiler, read only or not. It is like it does not update the attr address when it is supposed to, that's the closest I can figure.
Reply
#17
Here is some code that you can use to recreate the bug, the org address is 39936 when compiling.

Code:
Code deleted.
The code should be straightforward to test, you see without the workaround employed the colors are wrong. This code is with the workaround enabled so you can see how it is supposed to look, disable the workaround and then you get the bug. There is no third party corruption in here as far as I can tell, it's like it does not update the attr address at certain times for the print routine or IO routines whatever the case might be. Version 1.14.1 worked fine, this version does not. Hope this helps.
Reply
#18
(10-05-2022, 07:59 AM)Darkstar Wrote:
(10-05-2022, 07:01 AM)boriel Wrote: The print changes were introduced in 1.16.0!
Indeed that was one of the updates from 1.15 to 1.16. I'm on it. Smile

I tested 1.15.2 and the bug was there so it must have happened before 1.16.0. You state in your changelog that you changed the print routine in 1.16.1 so you are contradicting yourself. The print routine is just likely incomplete as it does not reflect some changes that you have made to the core codebase, but the print routine is just fine under the old conditions.

I had a color bug myself as I was compiling my program under the new version of the complier, it was not updating the color when I was tripple buffering. I had to change the code from this:

Code:
Sub fastcall SetScreen (ScreenPtr as uinteger)

Asm
  ld (.core.SCREEN_ADDR), hl
End asm

End sub
 
To this:

Code:
Sub fastcall SetScreen (ScreenPtr as uinteger)

Asm
  ld (.core.SCREEN_ADDR), hl
  ld de, 6144
  Add hl, de
  ld (.core.SCREEN_ATTR_ADDR), hl
End asm

End sub

This might give you a clue.

This makes me wonder if other statements like DRAW, PLOT, CIRCLE have this bug as well. I hope you figure it out.

Okay, I've reviewed your code and it's ok. And so the compiler.
SCREEN_ATTR_ADDR *must* be updated, along with SCREEN_ADDR from 15.x onwards.
This is because this allows having the ATTR Region in another separate place. For example, suppose you want to buffer only the first 2 thirds of the screen (rows 0 to 15, both included), and leave the last third unbuffered (for scores and game data only). You can do it, by pointing the ATTR address to SCREEN_ADDR + 4096 and saving 2k.

Your SetAttrs routine should be:

Code:
Sub SetAttrs (ByVal Row as ubyte, ByVal Column as ubyte, ByVal NumberOfCells as uinteger)

Asm
  ld e, (ix+7)
  ld d, (ix+5)
  ld h, 0                    ;  7 T-States
  ld a, d                    ;  4 T-States
  add a, a    ; a * 2        ;  4 T-States
  add a, a    ; a * 4        ;  4 T-States
  ld l, a      ; HL = A * 4  ;  4 T-States
  add hl, hl  ; HL = A * 8  ; 15 T-States
  add hl, hl  ; HL = A * 16  ; 15 T-States
  add hl, hl  ; HL = A * 32  ; 15 T-States
  ;ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone)  <== NOT NEEDED
  ;add hl, de  <== NOT NEEDED
  ld de, (.core.SCREEN_ATTR_ADDR)    ; Adds attr screen address
  ;ld de, (SCREEN_ADDR)    ; Adds the screen address
  add hl, de
  ld b, (ix+8)
  ld a, (23693)
  SetAttrCopy:
  ld (hl), a
  inc hl
  djnz SetAttrCopy
End asm

End sub
I changed (splitted) the buffering areas because otherwise, you're always enforced to buffer the entire screen in a contiguous region. This way you can buffer only some regions if you choose wisely, or even buffer only one area (and point the other over the ROM, for example).
Reply
#19
This clears it up then, thank you for your time and for the changes to the SetAttrs routine. Good to know this, I am not sure if it is mentioned in the Wiki but that's another matter.

Thanks.
Reply
#20
Note. I've fixed several bugs in the scr buffer routine.
Now PRINT, PLOT, DRAW, CIRCLE, ScrollXXXX and WinscrollXXXX works perfectly and use the screen buffer!

Beta here:
http://www.boriel.com/files/zxb/zxbasic-...ta9.tar.gz
http://www.boriel.com/files/zxb/zxbasic-...-beta9.zip
http://www.boriel.com/files/zxb/zxbasic-...-win32.zip
http://www.boriel.com/files/zxb/zxbasic-...x64.tar.gz
http://www.boriel.com/files/zxb/zxbasic-...cos.tar.gz
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)