Loci - my Oric storage emulation project
- Sodiumlightbaby
- Flight Lieutenant
- Posts: 481
- Joined: Thu Feb 22, 2024 11:38 am
Re: Loci - my Oric storage emulation project
Or hold, on - I might be getting something very very wrong here. The ULA doesn't just splur out counter flip-flops - some high bits are fixed vales!
Edit: While some address bits are fixed or rigged, I still think it does 0xC000 address crossing.
Edit: While some address bits are fixed or rigged, I still think it does 0xC000 address crossing.
- Sodiumlightbaby
- Flight Lieutenant
- Posts: 481
- Joined: Thu Feb 22, 2024 11:38 am
Re: Loci - my Oric storage emulation project
Quick recap, the ULA continues to generate addresses (and trigger RAM accesses) during the HBLANK and VBLANK periods. The question has been, what addresses does it actually generate? We can't see the addresses but we can see the data on the bus. This hasn't been of much use, but with LOCI we're trying to figure out a way to detect the video mode, and potentially some kind of VSYNC trigger. And we know how to snoop that data! So my quest right now is to figure out exactly what the ULA does during *BLANK.
This rabbit hole is very very deep, but also incredibly satisfying. There is very little documentation out there about what the ULA does during H- and VBLANK period, but, again, Mike Brown's ULA v2 schematics and documentation has all the details to figure it out - and it's quite fascinating.
The VRAM is right up against the 0xC000 ROM address space and we know it doesn't activate RAM once that address line is crossed. So we're hosed? Not quite, for a few reasons:
1. Forced text mode (after scan line 200) is in effect during all of VBLANK.
2. Text mode address calculation has been logic optimized, strange things happen outside the acive VRAM address space.
The ULA doesn't do straight forward/brute force calculations, it has two counters it generates the address from but sets some bits fixed, reuses others and the offsets are baked into the summing logic with just enough precision to make it work correct within the visible space. The result is addresses that wanders not only into ROM space (0xC00), but also a lot back into the text screen area (0xBB80) and hires screen area (0xA000).
Add to this fact that the vertical counter isn't incremented at the end of the horizontal counter's 64 cycles, but at the 50 cycles mark, and you get some head-twisting address sequences - BUT they are 100% deterministic for a given mode
How can this be useful for us?
I've changed the ULA snooping PIO program to scout for a specific 4 byte sequence read by the ULA and made myself a simple emulator version of the address calculation circuit to list out addresses and seek out some transition of interest. On the Oric, by placing 2 bytes at the addresses before a transition and two at the addresses after, the PIO program is able to detect when the ULA does the jump! Well, with high likelihood at least - even with 100% control over VRAM there is still the undefined periods when it wonders off into ROM space.
Here are some transitions that may become useful I've not tested all yet, so take the data with a grain of salt until we have it all working. I've been wrong before
This rabbit hole is very very deep, but also incredibly satisfying. There is very little documentation out there about what the ULA does during H- and VBLANK period, but, again, Mike Brown's ULA v2 schematics and documentation has all the details to figure it out - and it's quite fascinating.
The VRAM is right up against the 0xC000 ROM address space and we know it doesn't activate RAM once that address line is crossed. So we're hosed? Not quite, for a few reasons:
1. Forced text mode (after scan line 200) is in effect during all of VBLANK.
2. Text mode address calculation has been logic optimized, strange things happen outside the acive VRAM address space.
The ULA doesn't do straight forward/brute force calculations, it has two counters it generates the address from but sets some bits fixed, reuses others and the offsets are baked into the summing logic with just enough precision to make it work correct within the visible space. The result is addresses that wanders not only into ROM space (0xC00), but also a lot back into the text screen area (0xBB80) and hires screen area (0xA000).
Add to this fact that the vertical counter isn't incremented at the end of the horizontal counter's 64 cycles, but at the 50 cycles mark, and you get some head-twisting address sequences - BUT they are 100% deterministic for a given mode
How can this be useful for us?
I've changed the ULA snooping PIO program to scout for a specific 4 byte sequence read by the ULA and made myself a simple emulator version of the address calculation circuit to list out addresses and seek out some transition of interest. On the Oric, by placing 2 bytes at the addresses before a transition and two at the addresses after, the PIO program is able to detect when the ULA does the jump! Well, with high likelihood at least - even with 100% control over VRAM there is still the undefined periods when it wonders off into ROM space.
Here are some transitions that may become useful I've not tested all yet, so take the data with a grain of salt until we have it all working. I've been wrong before
Code: Select all
Text 50Hz: BCA0,BCA1,BBB2,BBB3
Hires 50Hz: BCA0,BCA1,A032,A033
Text 60Hz: No transition
Hires 60Hz: BBB0,BBB1,A032,A033
VBLANK 224: BFEA,BFEB,BFEC,BFED (early but not transition - repeats 8 times)
VBLANK 232: A038,A039,A062,A063 (later, one-shot)
Last edited by Sodiumlightbaby on Tue Nov 12, 2024 6:16 am, edited 1 time in total.
Re: Loci - my Oric storage emulation project
Please keep this going. It is really interesting stuff.
- Sodiumlightbaby
- Flight Lieutenant
- Posts: 481
- Joined: Thu Feb 22, 2024 11:38 am
Re: Loci - my Oric storage emulation project
Good news - 50Hz detection is working great, and I got 60Hz text detection that seems to work by poking some mode bytes in basic. I've not got it fully verified for 60Hz hires. Does anyone know of any actual 60Hz hires applications?
A technical note on the "No transition" for 60Hz text mode. The 60Hz ULA setup resets the vertical counter when it rolls over to 264, so the transtion we would like to catch is the 263 to 264 vertical counter tranisiton. Why don't we see it?
From line/vcounter 200 we are in forced text mode, so the addresses generated in phase 1 are the same for 8 scanlines. The ULA looks up the same character data for each scanline of text and what changes is what part of the character set it looks up in phase 2. So at line 263 we're using the same address generation as we start with 8 lines earlier, at 256. Well, that's a nice power of two number that actually triggers a counter wrapping behaviour back to the first text line starting at 0xBB80. Then the resetting of vcounter to 0 to get back to 0xBB80 doesn't change the addresses generated
So how is the 60Hz text detection done then? Well, it's the only mode without a detection so we're using the lack of a match to identify it
Note that 50Hz text and 60Hz hires can't be tested for at the same time due to the 0xBBB0-BBB3 address overlap. Text and Hires 50Hz however can be tested for at the same time. The PIO program returns the 5th byte (1st after match) so we can put identifiers in 0xBBB4 and 0xA034 that tells us which transition was actually detected. Fun!
A technical note on the "No transition" for 60Hz text mode. The 60Hz ULA setup resets the vertical counter when it rolls over to 264, so the transtion we would like to catch is the 263 to 264 vertical counter tranisiton. Why don't we see it?
From line/vcounter 200 we are in forced text mode, so the addresses generated in phase 1 are the same for 8 scanlines. The ULA looks up the same character data for each scanline of text and what changes is what part of the character set it looks up in phase 2. So at line 263 we're using the same address generation as we start with 8 lines earlier, at 256. Well, that's a nice power of two number that actually triggers a counter wrapping behaviour back to the first text line starting at 0xBB80. Then the resetting of vcounter to 0 to get back to 0xBB80 doesn't change the addresses generated
So how is the 60Hz text detection done then? Well, it's the only mode without a detection so we're using the lack of a match to identify it
Note that 50Hz text and 60Hz hires can't be tested for at the same time due to the 0xBBB0-BBB3 address overlap. Text and Hires 50Hz however can be tested for at the same time. The PIO program returns the 5th byte (1st after match) so we can put identifiers in 0xBBB4 and 0xA034 that tells us which transition was actually detected. Fun!
Re: Loci - my Oric storage emulation project
I do.Sodiumlightbaby wrote: ↑Tue Nov 12, 2024 9:06 am Good news - 50Hz detection is working great, and I got 60Hz text detection that seems to work by poking some mode bytes in basic. I've not got it fully verified for 60Hz hires. Does anyone know of any actual 60Hz hires applications?
My last trailer for Encounter was in 60hz so the screen get stretched vertically so the pixels are more square than squished, which makes the aspect ratio be more similar to what you get on a PC with emulator.
Re: Loci - my Oric storage emulation project
IIRC, Load Vader is in 60Hz (though I don't understand anymore how I did that ) because I was back then using mainly a Joytech screen which required this frequency.Sodiumlightbaby wrote: ↑Tue Nov 12, 2024 9:06 am Does anyone know of any actual 60Hz hires applications?
https://www.oric.org/software/load_vader-2542.html
And there was also a 60Hz version of Stormlord, but I'm not sure it's available somewhere.
- Sodiumlightbaby
- Flight Lieutenant
- Posts: 481
- Joined: Thu Feb 22, 2024 11:38 am
Re: Loci - my Oric storage emulation project
Does it have a hires section? Looks like text mode to meSymoon wrote: ↑Tue Nov 12, 2024 2:39 pm IIRC, Load Vader is in 60Hz (though I don't understand anymore how I did that ) because I was back then using mainly a Joytech screen which required this frequency.
https://www.oric.org/software/load_vader-2542.html
If anyone knows, please speak out
That would be good test. The version I have seen (v0.3) looks to be 50Hz only. If you would be happy send or point me to it so I can try the 60Hz hires detection, I'd be very grateful.
- Sodiumlightbaby
- Flight Lieutenant
- Posts: 481
- Joined: Thu Feb 22, 2024 11:38 am
Re: Loci - my Oric storage emulation project
Hurray! Thanks to Dbug I have fixed a dumb bug in the 60Hz detection and can confirm it now correctly detects and restores also Hires 60Hz and Text 60Hz
Also thanks to Symoon - Load Vader totally skrews up LOCI Not only does it not suspend nicely, it corrupts the startup of the LOCI ROM in a way I've not seen before. A great application to investigate and help firm up the LOCI robustness further.
Also thanks to Symoon - Load Vader totally skrews up LOCI Not only does it not suspend nicely, it corrupts the startup of the LOCI ROM in a way I've not seen before. A great application to investigate and help firm up the LOCI robustness further.
Re: Loci - my Oric storage emulation project
Ouch, certainly because it has its own loading tape routines and is running them as soon as loaded?Sodiumlightbaby wrote: ↑Tue Nov 12, 2024 5:27 pm Hurray! Thanks to Dbug I have fixed a dumb bug in the 60Hz detection and can confirm it now correctly detects and restores also Hires 60Hz and Text 60Hz
Also thanks to Symoon - Load Vader totally skrews up LOCI Not only does it not suspend nicely, it corrupts the startup of the LOCI ROM in a way I've not seen before. A great application to investigate and help firm up the LOCI robustness further.
The purpose of Load Vader is only to load something and look for errors. Maybe it doesn't make that much sense to have it stopped and resumed, since it's supposed to work with a running real tape - but glad if it gives you interesting problems that allow a better robustness
(and yes it's text only)
- Sodiumlightbaby
- Flight Lieutenant
- Posts: 481
- Joined: Thu Feb 22, 2024 11:38 am
Re: Loci - my Oric storage emulation project
Do you remember how low the tape routine goes? As in, does it do its own VIA coding, or does it rely on the ROM for reading bits? Since it only works on Atmos I was thinking it could be the latter. Then it could be fun to try it with LOCI and swap TAP files around So perhaps not very useful, outside of LOCI robustness workSymoon wrote: ↑Tue Nov 12, 2024 7:37 pm Ouch, certainly because it has its own loading tape routines and is running them as soon as loaded?
The purpose of Load Vader is only to load something and look for errors. Maybe it doesn't make that much sense to have it stopped and resumed, since it's supposed to work with a running real tape - but glad if it gives you interesting problems that allow a better robustness
(and yes it's text only)
- Sodiumlightbaby
- Flight Lieutenant
- Posts: 481
- Joined: Thu Feb 22, 2024 11:38 am
Re: Loci - my Oric storage emulation project
Meanwhile...
"Random" ROM file loaded! Still some usability cleaning up to do but I'm so out of time for the rest of the week
"Random" ROM file loaded! Still some usability cleaning up to do but I'm so out of time for the rest of the week
Re: Loci - my Oric storage emulation project
It has calls to the ROM to configure the VIA and to read bytes indeed, I tried to make it as small as possible in RAM so it could load big files. You should have the code listing with comments in French in Oric.org's zip file. Though they might be a bit wrong (I'm saying it switches to 50Hz, when obviously it's 60Hz, and I actually don't explain what exactly does achieve this )
Re: Loci - my Oric storage emulation project
This is great stuff! So much in such a short time... Exciting indeed. I am really sorry for not being able to contribute more—you don’t give me enough time for it!
- Sodiumlightbaby
- Flight Lieutenant
- Posts: 481
- Joined: Thu Feb 22, 2024 11:38 am
Re: Loci - my Oric storage emulation project
For future reference, here is a partly condenced function to get the ULA address used in text mode in its pase 1 lookup in DRAM, given a vertical count (0-263/311) and horizontal count (0-63). Any address in Cxxx space does get CAS suppressed thus no output from DRAM. Note that the function does't show the wrap back on the last line; at hc=50.
Code: Select all
unsigned int ula_text_address_algo(unsigned int vc, unsigned int hc){
unsigned int stage1, stage2, stage3;
stage1 = ((vc & 0xFF) >> 3) + 0xB0;
stage2 = (stage1 * 5) & 0x3FF;
stage3 = (stage2 << 3) + hc + 0xA000;
return stage3;
}
Re: Loci - my Oric storage emulation project
hello I'm looking to maybe produce a little, and I'm asked the number of layers in the LOCI circuit, 2 layers? or 4 layers?