Closed dansanderson closed 1 year ago
Notably address $A2DA is in the C64 BASIC ROM in the middle of an error message string, so that's probably unintentional. ;)
PEN lacks the check if the graphics is on. If you use PEN directly after startup, you should get an error message that no graphics screen is open, because PEN is a graphic command. The three bytes that make the check should be included in PEN, then it works.
I confirmed that jsr CheckGraphicMode
in c65.setpen
is the correct fix. Nearly all graphics commands use either CheckGraphicMode
or get_GKI.parm
(which calls CheckGraphicMode
) to abort with a ?SCREEN NOT OPEN ERROR
if there is no active drawscreen, or the requested screen is not open. This is always called in the BASIC entry point and not the kg65 subroutine. I confirmed that all other BASIC 65 bitmap graphics commands and functions are appropriately guarded.
Notably, DMODE
, DPAT
, and RGRAPHIC()
do not check for an open screen, because they operate normally without one. PEN
and RPEN()
need an open screen to handle screen palettes in bitplane modes, converting the provided color number to a global "color index" that is stored in the global kg65.drawpens.
I'm not sure I fully understand why it works this way. The documentation and API design implies that palettes are screen-specific and the pen number is global, which would imply that the pen number refers to the color number of the active drawscreen, and therefore wouldn't need an active drawscreen just to set the pen number (like DPAT
et al). I would guess that's why PEN
is currently unguarded. I can't get palettes to behave this way. Either there's a bug or design flaw in PALETTE screen,...
or there's something I don't understand about the design intent.
Regardless, the current implementation of kg65.setpen
calls kg65.s.color2index
which needs an active drawscreen. So for now at least, this is the correct fix.
Test Environment (required) You can use MEGA65INFO to retrieve this.
Describe the bug PEN hangs if a graphics screen isn't active, but was before.
To Reproduce
PEN 3
. Nothing happens.SCREEN 320,200,2:SCREEN CLOSE
. Screen opens then immediately closes.PEN 3
. Computer hangs.Expected behavior
PEN
and all other graphics system commands that operate on an open screen should throw?SCREEN NOT OPEN ERROR
when a screen is not open. Most screen commands do this already. This includes bothPEN
cases described above.Additional context Original forum64.de report.
It may not be worth trying to understand why
PEN
fails the way it does with a missing precondition. For what it's worth, the hang is in a loop near $A2DA in 920383, which is a junk location (a text message in the C64 kernel).From Snoopy:
We should vet the other graphics commands for similar behavior and make the implementation consistent. Most of the graphics system is implemented in
c65.*
andkg65.*
routines in a sensible layout.