LOCI ULA snooping - best pattern

The Oric video chip is not an easy beast to master, so any trick or method that allows to achieve nice visual results is welcome. Don't hesitate to comment (nicely) other people tricks and pictures :)
User avatar
Sodiumlightbaby
Flight Lieutenant
Posts: 506
Joined: Thu Feb 22, 2024 11:38 am

LOCI ULA snooping - best pattern

Post by Sodiumlightbaby »

In LOCI we now use ULA snooping on the data bus of the bytes read by the ULA to learn what video mode it is in and where it is in the screen drawing. We can't see addresses the ULA uses, only the data, so the strategy is to put a 4 byte string of bytes in strategic locations in (and around) the video memory and wait for that sequence to show up in a series of the first ULA memory access in each cycle.

What I have been wondering is, what is a good sequence to use? We can't guarantee that the pattern isn't used by the application somewhere, but we can try to make it very unlikely.

Currently the pattern I'm using is

Code: Select all

0x83		//Inverted Ink yellow
0x84		//Inverted Ink blue
0x85		//Inverted Ink magenta
0x86		//Inverted Ink cyan *)
So four ink changes in inverted versions, based on thinking this is non-sense for any actual applications. The increasing numbering is good for human debugging, but is this a risky (possibly used) set of detection values?

My question is basically, is there a better, less likely to exist normally, sequence we should use?

*) Actual mechanics is the 4th value is configurable, and the 5th value is returned when the 4 byte sequence is seen, to allow pattern branches to be detected.
User avatar
Dbug
Site Admin
Posts: 4821
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: LOCI ULA snooping - best pattern

Post by Dbug »

How/who would put these 4 byte sequences of bytes in memory?
User avatar
Sodiumlightbaby
Flight Lieutenant
Posts: 506
Joined: Thu Feb 22, 2024 11:38 am

Re: LOCI ULA snooping - best pattern

Post by Sodiumlightbaby »

Dbug wrote: Sat Nov 30, 2024 6:51 am How/who would put these 4 byte sequences of bytes in memory?
Good quesiton. So the LOCI ROM is likely the only external actor that needs the sequence to be statistically unlikely. Its use is for detecting video mode.

The other actors are any LOCI aware applications that want to learn something about what the ULA is doing. VSYNC is the most obvious use for it. Then the question for the sequence usability is probably still "it should be rare", but more from convenience as likely the application is also the user of the video memory.

Edit:
Example to detect end of HIRES screen (HBLANK of last hires line before switching to the bottom 3 text lines)
  • Put the snooping pattern and a signature byte in the gap (but before x=50) between hires and text memory

    Code: Select all

    BF40: 83 84 85 86 <your byte>
  • Write $86 to the LOCI register $03A3
  • Poll $03A3. When it changes from zero to <your byte>, the ULA has read the pattern. Write register to repeat.
User avatar
ibisum
Wing Commander
Posts: 1815
Joined: Fri Apr 03, 2009 8:56 am
Location: Vienna, Austria
Contact:

Re: LOCI ULA snooping - best pattern

Post by ibisum »

So four ink changes in inverted versions, based on thinking this is non-sense for any actual applications.
Well, not so fast ..

In my soundToy app, I have a situation where I'm generating a large block of HIRES-visible 'semi-random' values, which include the bytes you're suggesting. You can see the screenshots on https://github.com/seclorum/soundToy for an idea of what I mean. This 'random blob' is actually going to be where I source the attribute bytes for various parts of a UI I'm constructing, although this is all still very wet. And actually, I'm sort of depending on these attribute inverse bits to do interesting things, which will be more clear soon as I get this random blob wired up to the other random blob aspect of soundToy, the synthesizer parameter interpretation function ..

I would think that the most viable "sweet code" combination would be a repetitive sequence of 0x18/0x19/0x1a/0x1b or alternatively 0x98/0x99/0x9a/0x9b, since rapidly going between 60hz/50hz doesn't have much 'real application' in an Oric program, and - presumably - you're trapping these values beforehand anyway, so they won't end up getting applied by the ULA (and thus resulting in crazy flickering) ..

For a handy table in case you haven't seen it already, check here:

http://thespider.oric.org/oric_hires_colour.html

the Text/Graphics hz-switching attributes, in any combination, would be my preferred suggestion.
User avatar
Sodiumlightbaby
Flight Lieutenant
Posts: 506
Joined: Thu Feb 22, 2024 11:38 am

Re: LOCI ULA snooping - best pattern

Post by Sodiumlightbaby »

Well, for mode detection I can't use mode bytes in the sequence. The wrapping addresses in VBLANK of the ULA means the bytes need to be placed insided the video memory range and cause problems.

The full sequence only occures at these events, but they are also read in part at other times.

Code: Select all

;ULA mode dependent address jumps
;Use with ULA pattern matching PIO program ($83848586)
;   Text  50Hz: BCA0,BCA1,BBB2,BBB3
;   Hires 50Hz: BCA0,BCA1,A032,A033
;   Text  60Hz: No transition
;   Hires 60Hz: BBB0,BBB1,A032,A033
User avatar
Dbug
Site Admin
Posts: 4821
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: LOCI ULA snooping - best pattern

Post by Dbug »

Is it somewhat possible to detect the double read of the ULA when accessing the text mode charsets?

If that was possible, then if you could identify that a read is actually from a character definition, you could exploit the fact that the bit 6 and 7 of characters are not used for any particular purpose, so technically they could be used to create patterns.
User avatar
Sodiumlightbaby
Flight Lieutenant
Posts: 506
Joined: Thu Feb 22, 2024 11:38 am

Re: LOCI ULA snooping - best pattern

Post by Sodiumlightbaby »

The two ULA accesses happen at distinct times so we have full control of that. We only look at the first of the accesses, the ones that follow the video buffer.

But they are a bit hard to exploit as they are only accessed in text mode. As far as I can see, the ULA reads the same pixel byte twice in hires mode.
User avatar
iss
Wing Commander
Posts: 1723
Joined: Sat Apr 03, 2010 5:43 pm
Location: Bulgaria
Contact:

Re: LOCI ULA snooping - best pattern

Post by iss »

@Sodiumlightbaby: I have a questions: :)
- What is the full range of addresses that ULA uses to generate video?
The memory refresh of DRAMs uses rows (i.e. during RAS all low 8-bits $xx00-$xxFF should appear successively on the '257-muxer inputs) but what range is used during CAS?
- What addresses reads ULA during the green marked times (i.e. front/back porch and blanking):
20241130_100526.jpg
You already mention something but if we can make a picture or table representation it would be very helpful for "visually" understanding.

About the snooping:
IMHO, we need to distinguish/separate both use cases getting in sync with ULA (VSYNCH) and guessing the video mode of the currently running unknown program.
The VSYNC case will be used in future games backed with LOCI-API calls - we can blank the whole video related memory, wait 20mS, set video attribute at $BFDF an wait it to appear on data bus during ULA reads - we are in sync :).

Knowing the video mode can be used to go forth-and-back to LOCI ROM (runtime change DSK/TAP, snapshot functionality, etc). To guess the video mode I think we need to snoop on 6502 writes to the video memory and catch the mode attributes.
User avatar
Dbug
Site Admin
Posts: 4821
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: LOCI ULA snooping - best pattern

Post by Dbug »

It's true that the vsync does not have to work during the game: What Chema did with Oricium is that he does the vsync at the start, and then sets-up the VIA so it stays in sync (I guess that's assuming one does not incorrectly changes frequency by mistake, then all bets are off).

Bonus question: I assume the ULA does not read past BFDF? (It could have been reading BFE0-C000 and discard the result)
User avatar
Sodiumlightbaby
Flight Lieutenant
Posts: 506
Joined: Thu Feb 22, 2024 11:38 am

Re: LOCI ULA snooping - best pattern

Post by Sodiumlightbaby »

iss wrote: Sat Nov 30, 2024 10:37 pm - What is the full range of addresses that ULA uses to generate video?
- What addresses reads ULA during the green marked times (i.e. front/back porch and blanking):
For full deep dive on ULA operation, the authoritive reference is MikeB's brilliant work https://oric.signal11.org.uk/html/ula-dieshot.htm
Quick recap for the public. During each Oric system clock cylces, there are 3 DRAM accesses, 2 used by the ULA and 1 for the CPU. The ULA uses the first access video memory scanline by scanline. The second is used to fetch the actual mono-chrome 6 pixels to output.

In text mode, the first access when identified as an ASCII value is used to generate the address for the second access to fetch one byte from the character set and output it. This is repeated for each scanline, so in text mode the same text line is read for each scanline and the right slice of character set data fetched in the second cycle.

In hires mode, the same address is generated for both accesses to the DRAM. The first access is only used to capture attributes and the second to fetch the same data again and use as pixel data if it wasn't attributes.

Each scanline read is 64 cycles, 40 of which are used to with active video data, the others happen anyway to give the HBLANK and HSYNC timing. You would think that it starts e.g. at 0xA000 for the first hires scanline and runs through 0xA03F before switching to the next, but the actual row shift happens at cycle 50, so it might be better to think of it as a wrapping 64 address window with 14 cycles of pre-scanline accesses, 40 cycles of scanline accesses and then 10 cycles of post-scanline accesses. So the first scanline in hires would do:

Code: Select all

Pre    A032-A03F
Scan   A000-A027
Post   A028-A031
Then the windown advances by 40 so the next scanline would do:

Code: Select all

Pre    A05A-A067
Scan   A028-A04F
Post   A050-A059
Note that these are not tightly connected to front- or back-porch so I don't have a good graphical represenation for you yet.

So hires is pretty straight forward. For text mode, which is also used at the end of hires, it's basically the same but in the text video memory range, until you get to the end of the video memory (VBLANK), and the optimisations they did in the ULA makes all kinds of strange address ranges appear because it was "don't care" to the designers. To get a list of those addresses I refer to my previous post.
https://forum.defence-force.org/viewtop ... 109#p31109
This might need to be expanded in a knowledge article or something. Guidance is welcome.
iss wrote: Sat Nov 30, 2024 10:37 pm The memory refresh of DRAMs uses rows (i.e. during RAS all low 8-bits $xx00-$xxFF should appear successively on the '257-muxer inputs) but what range is used during CAS?
The ULA always runs RAS as it plows through the addresses for a frame. The addresses are the same, the question is only if CAS is suppressed or no, if data is actually fetched. CAS is suppressed if the ULA address crosses into ROM space, or for the second access if the first is an attribute. There is no special handling for DRAM refresh, it is just a designed in side-effect of running the DRAM accesses beyond the actual required data.
When it is in HBLANK or VBLANK range, it just ignores the data it fetches.
iss wrote: Sat Nov 30, 2024 10:37 pm To guess the video mode I think we need to snoop on 6502 writes to the video memory and catch the mode attributes.
No, we already have video mode detection working with the current ROM and ULA snooping. When you suspend an application there is debug info in the top right corner of the ROM UI telling you if it found T50, T60, H50 or H60. Now, @ibisum might throw a wrench in that detection with his application, but for others it seems to be working. The thread start was basically asking if we could find an ultimate pattern for that detection that could work for all. We have one better for VSYNC, but not for mode detection yet.
Dbug wrote: Sun Dec 01, 2024 8:30 am It's true that the vsync does not have to work during the game: What Chema did with Oricium is that he does the vsync at the start, and then sets-up the VIA so it stays in sync (I guess that's assuming one does not incorrectly changes frequency by mistake, then all bets are off).
The only complication is that using LOCI to suspend and resume such applications will unlink and skrew up that timing and I don't know a good way of fixing it. Perhaps there is some protocol we can agree on for the VIA and timers to make it work, but if not I can only pleed for new applications to allow the user to resync at some point.
Dbug wrote: Sun Dec 01, 2024 8:30 am Bonus question: I assume the ULA does not read past BFDF? (It could have been reading BFE0-C000 and discard the result)
Oh it reads all the way but always discards data it doesn't need. When it generates addresses in the ROM (> 0xC000) range it does however turn off CAS and does not active the DRAM for the read.
User avatar
Sodiumlightbaby
Flight Lieutenant
Posts: 506
Joined: Thu Feb 22, 2024 11:38 am

Re: LOCI ULA snooping - best pattern

Post by Sodiumlightbaby »

Sodiumlightbaby wrote: Sun Dec 01, 2024 12:41 pm Note that these are not tightly connected to front- or back-porch so I don't have a good graphical represenation for you yet.
Checking MikeB's documentation again, this isn't quite true. The 10 cycles post equals the back-porch, then the 14 pre cycles equal 4 cycles of HSYNC and 10 cycles of front-porch.
User avatar
iss
Wing Commander
Posts: 1723
Joined: Sat Apr 03, 2010 5:43 pm
Location: Bulgaria
Contact:

Re: LOCI ULA snooping - best pattern

Post by iss »

Amazing info! Now it's cristal clear.
About the pattern: I think the most non-sense one is to have any combination of 3 consecutive mode-attribute bytes and the 4th is current detected mode. :D
For instance let's suppose the current mode is T50 (#1A) then the pattern can be: H50,H60,T60,T50. I think even 3+1 bytes should do the job. The benefit is that there will be minimal visual changes. For Hires good choice to place the pattern is #BF40 - no visual changes at all.
User avatar
Sodiumlightbaby
Flight Lieutenant
Posts: 506
Joined: Thu Feb 22, 2024 11:38 am

Re: LOCI ULA snooping - best pattern

Post by Sodiumlightbaby »

iss wrote: Sun Dec 01, 2024 7:19 pm About the pattern: I think the most non-sense one is to have any combination of 3 consecutive mode-attribute bytes and the 4th is current detected mode. :D
For instance let's suppose the current mode is T50 (#1A) then the pattern can be: H50,H60,T60,T50. I think even 3+1 bytes should do the job. The benefit is that there will be minimal visual changes. For Hires good choice to place the pattern is #BF40 - no visual changes at all.
For the VSYNC case this is a very good pattern. For mode detection it doesn't work as the current mode is not known (it's what we're tryting to find), and the pattern bytes need to be placed temporarily in odd but specific places inside the normal video memory to catch the different unique address transitions the ULA does during VBLANK.
User avatar
iss
Wing Commander
Posts: 1723
Joined: Sat Apr 03, 2010 5:43 pm
Location: Bulgaria
Contact:

Re: LOCI ULA snooping - best pattern

Post by iss »

Hm, I think you really nailed it: 83,84,85,86! :)
User avatar
Sodiumlightbaby
Flight Lieutenant
Posts: 506
Joined: Thu Feb 22, 2024 11:38 am

Re: LOCI ULA snooping - best pattern

Post by Sodiumlightbaby »

iss wrote: Sun Dec 01, 2024 8:12 pm Hm, I think you really nailed it: 83,84,85,86! :)
Ok, thanks, I'll keep that for now.

Having tickled the brain a little, I think we _could_ afford to have two patterns and choose between then depending on the upper bit of the value written to 0x03A3.

Code: Select all

bit7==1 : 83 84 85 0b1xxxxxxx
bit7==0 : 1C 1E 18 0b0xxxxxxx
Or do you think that becomes too confusing?
Post Reply