Posts: 92
Threads: 8
Joined: Mar 2011
Reputation:
0
(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.
Posts: 92
Threads: 8
Joined: Mar 2011
Reputation:
0
10-10-2022, 04:20 AM
(This post was last modified: 10-11-2022, 07:00 PM by Darkstar.)
Here is some code that you can use to recreate the bug, the org address is 39936 when compiling.
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.
Posts: 1,770
Threads: 55
Joined: Aug 2019
Reputation:
24
10-11-2022, 06:15 PM
(This post was last modified: 10-18-2022, 03:57 PM by boriel.)
(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.
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).
Posts: 92
Threads: 8
Joined: Mar 2011
Reputation:
0
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.
Posts: 1,770
Threads: 55
Joined: Aug 2019
Reputation:
24
|