Mode change procedure
André Timmermans (100) 655 posts |
Jon, shouldn’t you just let “AnyMode” utility do the job for you? Now here are my thoughts on screen mode selection: Having created a litle module for the RPC which manipulate the setting of unavailable resolutions to center them at the center of existing MDF mode definitions), I tend now to view EnumerateScreenModes as a simple list of physical resolutions supported by a monitor, nothing more. The display manager can make use of this list to offer a list of desktop resolutions but it should not restrict the modes which a program can select, i.e. OS_CheckModeValid and OS_ScreenMode should leave the whole job (except for numbered modes) to the graphics driver. This means that on the PI graphic driver could do what “AnyMode” currently does and other graphic drivers could display screen modes at the center of provided MDF/EDID resolutions (by transfering the the resolution differences to the borders). |
Jon Abbott (1421) 2651 posts |
I’m trying to avoid loading a Module during the boot sequence or forcing the use of Auto in Configure. You shouldn’t even need Anymode on the Pi as it supports all legacy resolutions. I suppose the fundamental issue here is that it’s an oversight on the Pi build, which we probably should have picked up on when Steve coded AnyMode in the first place. At the time Steve coded it, I wondered “why do you need a Module for that?” As all MODE’s seemed to work on my Pi – what I didn’t realise at the time was that all my Pi’s were either set to Auto or using an MDF I’d created on the RPC that had all legacy and known game resolutions predefined. I’ve only picked up on the issue because Diggers was high on the “wanted” list, and once I actually got it running on the Pi, the testers couldn’t get it to run, and I couldn’t get it to run under the NOOBS build Pi’s I’d prepared for the London show. After initially looking at my own code as the root cause, it eventually dawned on me that RISCOS was at fault. For the London show, I’ll set them all to Auto – but if this is being deprecated at some point, I do need to find a more permanent long term solution. |
Jeffrey Lee (213) 6048 posts |
(Ack, lots of posts appeared while I was working on this)
Am I correct in thinking that your code is currently structured as follows? if Service_ModeExtension has returned with VIDCList.type == 0 or VIDCList.type == 1 issue Service_ModeExtension for base mode to get type 3 VIDC list make copy of type 3 list and modify parameters based on type 0/1 list claim service call and return modified type 3 list endif (edit – this is assuming you have a way of intercepting the result of a service call!) So the problem you’d be facing is that unless you have an MDF which contains an appropriate definition for the base mode, the Service_ModeExtension call you make will fail and you won’t be able to get the required details of the base mode. In which case, I think a reasonable solution would be to make the kernel respond to Service_ModeExtension when the details of a legacy numbered mode are requested. Doing this should also help to simplify the mode change code – after thinking about it for a bit I think it would be possible to get rid of all the bits which are highlighted in red in this updated diagram and implement all of the required logic in the kernel’s Service_ModeExtension handler. Possibly we’d also be able to get rid of the ScreenModes Service_ModeTranslation handler (which, as I noted earlier in the thread, seems to only exist in order to protect the user from the dumb choices the kernel will make) |
Jon Abbott (1421) 2651 posts |
Not quite, what I’m doing is as follows: if Service_ModeExtension Service_ModeExtension isn’t the issue though – it’s just highlighted it. The issue is that the base MODE is changed to MODE 25, 26, 27 or 28. Likewise, you can’t switch to MODE 13 on a Pi when a default monitor definition is selected in Configure.
Your suggested changes to FindOKMode are what I was thinking to resolve the problem. I’m not sure if the other changes you suggest would affect this issue or not. |
Jeffrey Lee (213) 6048 posts |
Service_ModeTranslation is only called if the provided mode isn’t valid (see the logic in FindOKMode). |
André Timmermans (100) 655 posts |
If you mean by that letting the kernel translate legacy screen mode numbers into screen mode blocks and purging the graphics system of anything related to mode numbers, that is I think the way to go. |
Jon Abbott (1421) 2651 posts |
Are you sure? The way I’m reading it, trying to enter MODE 13 will hit “known monitor type?”, which will be unknown if an MDF is selected and therefore always call Service_ModeTranslation, this looks to me like it’s never passed on if an MDF is being used and will always return MODE 25..28 (if MODE 13 isn’t in the MDF) I’m probably not reading the diagram correctly! |
Jeffrey Lee (213) 6048 posts |
Service_ModeTranslation is only called if the provided mode isn’t valid (see the logic in FindOKMode). If the mode is valid, it shouldn’t even reach that point – it should call OfferModeExtension, which will then translate the mode number to a mode selector (assuming the first call to Service_ModeExtension failed), and then call Service_ModeExtension again (which should then be picked up by ScreenModes, assuming you have a 320×256 mode in your MDF). |
Jeffrey Lee (213) 6048 posts |
So the problem you’d be facing is that unless you have an MDF which contains an appropriate definition for the base mode, the Service_ModeExtension call you make will fail and you won’t be able to get the required details of the base mode. In which case, I think a reasonable solution would be to make the kernel respond to Service_ModeExtension when the details of a legacy numbered mode are requested. Doing this should also help to simplify the mode change code – after thinking about it for a bit I think it would be possible to get rid of all the bits which are highlighted in red in this updated diagram and implement all of the required logic in the kernel’s Service_ModeExtension handler. Possibly we’d also be able to get rid of the ScreenModes Service_ModeTranslation handler (which, as I noted earlier in the thread, seems to only exist in order to protect the user from the dumb choices the kernel will make) Yeah, I guess that’s what I’m aiming for. |
Jon Abbott (1421) 2651 posts |
That’s the bit I misunderstood, I was assuming Mode selector? would fail if a MODE number was passed. Its probably worth trying a repro on the Pi at this point:
On the Pi this should work because the hardware supports it, but won’t because (I believe) the MDF doesn’t list the resolution. Now repeat the process but select Auto in the first step…it works, possibly because the inbuilt RISCOS MDF includes the legacy resolutions. Specific to the Pi build, it should support all legacy resolutions regardless of the MDF. 1/2/4 bpp being upped to 8 bpp. |
Jeffrey Lee (213) 6048 posts |
On the Pi this should work because the hardware supports it, but won’t because (I believe) the MDF doesn’t list the resolution. Correct, on all counts.
Also correct, although (a) I’d like us to have a generic way of indicating support for hardware scaling, and (b) I’d like us to be have builtin emulation of low colour modes. |
Richard Walker (2090) 431 posts |
Whilst we’re daydreaming, would the proposed architecture allow for enhancements such as pixel-doubling for the small/rectangular modes? That was always something I wanted on the Risc PC (not so much a worry on the Pi). |
Jeffrey Lee (213) 6048 posts |
That’s the plan, yes. |
Jon Abbott (1421) 2651 posts |
Rasters may actually need doubling on the Pi, to correct scaling. MODE 15 for example is not scaled correctly, it’s an issue that I’ve yet to sort out under ADFFS but am considering raster doubling as a last resort, unless I can find a way to fool the GPU to scale correctly. |
Rick Murray (539) 13850 posts |
Is it BootFX that puts the Pi in HD? If I could find where this is done and where the built in MDF is, I could ensure that 1280×1024 is defined, then select that. |
Chris Hall (132) 3558 posts |
The problem here is that RISC OS cannot yet talk to the GPU. The GPU talks to the monitor and examines config/txt and decides what resolution to send to the monitor independently of RISC OS. An LCD monitor will take whatever it gets and display it at its native resolution. RISC OS, via configure, decides what it sends to the GPU, which will scale it if necessary to fit what it is sending to the monitor. Complicated isn’t it? |
Jeffrey Lee (213) 6048 posts |
Is it BootFX that puts the Pi in HD? BCMVideo is responsible for both. If you’re building from source you should just be able to add an extra mode to its MDF (in mixed.RiscOS.Sources.HWSupport.Video.BCMVideo.Resources) and then change the mode selector block (‘startupmode’ in s.BCMVideo) to specify that mode. If you’re using an existing build tree, remember to do an ‘export resources’ phase after modifying the MDF for the updated file to actually show up in the ROM. |
Rick Murray (539) 13850 posts |
Thanks. Tweakage this evening. |
Rick Murray (539) 13850 posts |
Brilliant. Readable startup text at last! ;-) I’ll need to tweak BootFX next; it puts the output box and bar in the wrong place (naughty! hardcoding instead of enquiring the current display mode!); but the text is now readable, which is good. One question – the backdrop JPEG – is it available as a DrawFile or somesuch? BootFX currently scales it (which looks weird as 1280×1024 isn’t widescreen!). It would be better to crop the background and shift around the text to fit within. |
Jon Abbott (1421) 2651 posts |
How about an option to turn it off as it slows the boot sequence unnecessarily – it’s only shown for a few ms and takes a lot longer than that to scale and display. |
Jeffrey Lee (213) 6048 posts |
For now, I think the best way of turning it off is to just unplug the module. But in the future (when we have a better way of doing CMOS on the Pi) I guess we might want to have a CMOS bit allocated to it (so that we won’t have to worry about the wrong module becoming unplugged if the ROM module order is changed) |
Rick Murray (539) 13850 posts |
Pleasant booting on a Pi at 1280×1024. First, we’ll need to hack BCMVideo to select a more appropriate mode. The code is at …BCM2835Dev.mixed.RiscOS.Sources.Video.HWSupport.BCMVideo.s.BCMVideo and around line 319 you will see startupmode which is defining a 1920×1080 mode. Alter as follows:
Save it, you’re done with that. Now open the associated built-in mode definition file at …BCM2835Dev.mixed.RiscOS.Sources.Video.HWSupport.BCMVideo.Resources.RPIMon and you will see a number of definitions. The first two are for 1080P and 720P. Following these, add in a definition for 1280×1024:
Save it, you’re done with that. Essentially, that’s all you need to do, however it may be nice to also hack BootFX so things appear in a better place on the screen. So… open up BootFX which it at …BCM2835Dev.bsd.RiscOS.Sources.Video.UserI.BootFX.c.bootfx and look around line 202 until you see the definitions of where things are placed. It will look like this:
Alter the values in the first set (the Pi’s set) as follows:
This will place the bar and text window centred on the screen and in a position that will better match the (stretched) backdrop image. The values were created thanks to a lot of trial and error. For a safe build, rebuild your ROM from scratch. If that is long and complicated, and everything else is up to date, you can do the following:
In the !Builder application, tick only Install ROM and Join ROM and then Build it. |
Jon Abbott (1421) 2651 posts |
On this thread, what’s the method for determining if a MODE has non-square pixels. It’s obvious looking at MODE 15 (640*256) that the pixels are double height, the same goes for MODE 49 (320×480) which are double width. But how does VIDC / VIDC20 do it? Is it simply a case of the ratio of HCR:VCR being above or below a certain threshold? |
Rick Murray (539) 13850 posts |
OS_ReadVduVariables for the mode variables Xeig and Yeig? |
Jon Abbott (1421) 2651 posts |
OS_ReadModeVariable would work for standard MODE’s, but I’m dealing with games that are writing to VIDC1 and VIDC20 directly so need to calculate the ratio based on VIDC parameters. Odd thing is, taking MODE 2 (160×256) as an example, its programmed as 320×256 according to the values in the RO3.5 source so I’m totally confused as to how it ends up displaying as 160×256 |