Cycles and video timing II

Here you can ask questions or provide insights about how to use efficiently 6502 assembly code on the Oric.
User avatar
Symoon
Archivist
Posts: 2301
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Cycles and video timing II

Post by Symoon »

Hi,

I tried to make orange background colour by displaying red and yellow on screen, alternatively, each 20000 cycles (should match to VBLs).
But it keeps blinking, on emulators and on a real machine as well.

As I'm not assembler expert, here's the program I made... I already fixed a few mistakes but can't find anymore now. Any help would be great, unless someone already tried and tells me it's impossible (but Jede told me Twilighte had done that already...)
Thanks!

Code: Select all

sei
lda #11       Cy=2
sta adresse   Cy=4 // #8D and screen address
--- tempo1 ---
ldx #18   Cy=2 // 25 loops
ldy #9E   Cy=2 // 158 loops
DEY       Cy=2
BPL #FD   Cy=3; 2 cycles on the last one since there's no branching // FD=-3
DEX       Cy=2 
NOP       Cy=2 
STA #00   Cy=3 // just to spend 3 cycles without affecting the registers 85 00 
BPL #FA   Cy=3; 2 cycles on the last one since there's no branching // FA=-6
NOP       Cy=2 
NOP       Cy=2 
NOP       Cy=2 
NOP       Cy=2 
NOP       Cy=2 
NOP       Cy=2 
NOP       Cy=2 
NOP       Cy=2 
--- fin tempo1 ---
lda #13       Cy=2
sta adresse   Cy=4 // #8D and screen address
--- tempo2 ---
ldx #18   Cy=2 // 25 loops
ldy #9E   Cy=2 // 158 loops
DEY       Cy=2 
BPL #FD   Cy=3; 2 cycles on the last one since there's no branching // FD=-3
DEX       Cy=2 
NOP       Cy=2
STA #00   Cy=3 // just to spend 3 cycles without affecting the registers 85 00 
BPL #FA   Cy=3; 2 2 cycles on the last one since there's no branching // FA=-6
BPL #0    Cy=3 
NOP       Cy=2 
NOP       Cy=2 
NOP       Cy=2 
NOP       Cy=2  
NOP       Cy=2 
--- fin tempo2 ---
JMP to the 1st STA Cy = 3
A few comments:
Tempo 1 cycles:
Intro (starting at the 1st LDA): 10
loop: 19974
(Total small loop: 158*5 - 1 = 789;
Total big loop: (789+10)*25 - 1 = 19974)
+ 8 NOPs = 20000

Tempo 2 cycles:
Intro: 10
loop: 19974
(Total small loop: 158*5 - 1 = 789;
Total big loop: (789+10)*25 - 1 = 19974)
+ final JMP 3
+ BPL0 and 5 NOPS = 20000
User avatar
Chema
Game master
Posts: 3013
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: Cycles and video timing II

Post by Chema »

Well, not sure if o got it but I think your code should not only run every 20000 cycles but also it should be synchronized with the tv retrace, so it updates the attributes while the tv is in the blank period between frames.

Also use Oricutron for testing, not euphoric.

There is no way to do this on the Oric, except by having the vsync cable or making the user calibrate an IRQ timer to the bottom of the screen. That is the purpose of the routine posted years ago by Fabrice and which I am now using in my next project. There a re so details in the related forum.

Could this be useful, or I am completely wrong about what your problem is?
User avatar
Symoon
Archivist
Posts: 2301
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Re: Cycles and video timing II

Post by Symoon »

You may well be right (actually I don't know!). I hadn't thought changing a single byte would require this synchro.

What puzzles me is that, if the timing of my code was good, even if I was not synchronized with the retrace, I should see something that is not moving, am I wrong?
Either a perfect orange, either a yellow zone and another red zone, whatever their respective size.
But here I see lines moving, which seems to indicate my code is not synchronized anyway...
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: Cycles and video timing II

Post by Dbug »

There are two things to consider there:
- First changing between RED and YELLOW is not going to give you ORANGE: it's going to give you a massive headache :)
- Timings on emulator are complicated by the fact that the Oric assumes a 50hz refresh with 20000 cycles while the emulators have to refresh something that is going to be displayed asynchronously at best, and synchronized with a screen that refreshes at 60hz or more.

For the first problem, I would suggest to use dithering to make the colors, like what I did with my HIRES/TEXT video mode:
Image

You could probably then use flickering to try to improve the effect by alternating RED/YELLOW with YELLOW/RED, but do it per scanline or at the pixel level, not on large areas.

For the timings, well as Chema wrote, you should use the vsync, but Fabrice told me that we did not have 20000 cycles per frame (1000000/50), but something like 19968 cycles (312*64). At least if you use the vsync you will not get out of sync :)
User avatar
Symoon
Archivist
Posts: 2301
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Re: Cycles and video timing II

Post by Symoon »

Dbug wrote:There are two things to consider there:
- First changing between RED and YELLOW is not going to give you ORANGE: it's going to give you a massive headache :)
That's what I wanted to test, trying to find a new technique for background colours without using alternate coloured lines ;-)
BTW I have tested on the real machine, too.
Dbug wrote:For the timings, well as Chema wrote, you should use the vsync, but Fabrice told me that we did not have 20000 cycles per frame (1000000/50), but something like 19968 cycles (312*64). At least if you use the vsync you will not get out of sync :)
Now that's interesting, because by trying various amounts of NOPs, I noticed the red and yellow lines were moving at different speed (understand: they were not synchronized, but in a different way), so maybe I didn't get any "logical" result by the fact that we're not exactly at 20000 cycles?

Anyway, I guess I won't use this further, but I'd like to achieve the test. Will try with 19968 cycles in 2 weeks (I'm out of real machine now) ;)
User avatar
Chema
Game master
Posts: 3013
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: Cycles and video timing II

Post by Chema »

Yep, Dbug is right about the timing. Also you can test with Oticutron, even with the problem of the monitor refresh rate. At least you will see when the lines don't move... Which will indicate the tomings and sync is correct.
User avatar
Symoon
Archivist
Posts: 2301
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Re: Cycles and video timing II

Post by Symoon »

Thanks to you guys for the replies. I'll keep you informed about anything interesting.
User avatar
barnsey123
Flight Lieutenant
Posts: 379
Joined: Fri Mar 18, 2011 10:04 am
Location: Birmingham

Re: Cycles and video timing II

Post by barnsey123 »

Dbug wrote: - First changing between RED and YELLOW is not going to give you ORANGE: it's going to give you a massive headache :)
Ha ha, this is true. BUT you can get a similar effect without getting a headache straightaway - it gives you eye strain first and THEN you get a headache and then you feel sick :lol:
If you fill your screen with YELLOW, stare at it for a bit and then switch it to CYAN then - for a while - you get a sickly shade of GREEN. It really is a horrible effect (I found this out in the chess game, I changed the user mode movement screen from GREEN to YELLOW because I wanted different inverse colors. It worked OK but the transition back to CYAN was horrible (in Oricutron anyway). Euurgh!
User avatar
Symoon
Archivist
Posts: 2301
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Re: Cycles and video timing II

Post by Symoon »

Well, I'm really not a reliable machine-code coder, but if my code is right (mmmh), with Oricutron the correct amount of cycles seems to be 19992 !
With this I get 2 perfect static yellow and red zones horizontally dividing a text line. That means I'd indeed have to synch with the VBL, but at least we have the amount of cycles.
Will have to test on a real machine and CRT monitor some day.
User avatar
Chema
Game master
Posts: 3013
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: Cycles and video timing II

Post by Chema »

Hi again Symoon.

Have you tried the routine that Fabrice Frances posted many years ago? About the user calibrating the vertical retrace? I am using this in my new project and it works nicely, though it requires user input.

Using it (which simply changes the value of the timer increasing/decreasing it depending on the keypress until you get a red band on the bottom of the screen which does not move vertically), the value I get for each frame is 19966. Just one unit up or down and the band starts moving. Beware that I am using it to produce an IRQ, so some cycles may go there...

I also tried it on a real Oric, and it works, but I cannot tell you if this value is the same or not... Should print it I guess :)

You can load this value on the VIA timer 1 latch so you get an IRQ at each frame!
User avatar
Symoon
Archivist
Posts: 2301
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Re: Cycles and video timing II

Post by Symoon »

Chema wrote:Have you tried the routine that Fabrice Frances posted many years ago? About the user calibrating the vertical retrace? I am using this in my new project and it works nicely, though it requires user input.
Not yet, tried to find it back (quickly) but didn't yet!
Chema wrote:You can load this value on the VIA timer 1 latch so you get an IRQ at each frame!
IRQs... Each time I find a moment to understand how it works, I do but I'm moving too something else, so I forget and have to understand again when I'd need it again ;)
I think in the past 6 years I spent time on understanding how to use them about 4 or 5 times...
I'd need a clone, or to quit my job and switch off everything - or better memory ;)
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: Cycles and video timing II

Post by Dbug »

If it can make you feel better, I keep copying the IRQ code from project to project.
The only time I really tried to understand all of it was when I did the IRQ accuracy testing code to check the differences between Euphoric, Mess and Oricutron.
User avatar
Xeron
Emulation expert
Posts: 426
Joined: Sat Mar 07, 2009 5:18 pm
Contact:

Re: Cycles and video timing II

Post by Xeron »

It isn't exactly 20000 cycles per frame. 80s computers don't output a full interlaced PAL signal, they usually output the same field each time. For PAL that is a 312 line field, which the TV shows as a 312 line non-interlaced picture.

As nobody has reverse engineered the ULA of the Oric, I made a reasonable assumption.

As you can see in the oricutron code here, I did the following guestimate (until someone gives us real readings from a ULA..):

// PAL50 = 50Hz = 1,000,000/50 = 20000 cpu cycles/frame
// 312 scanlines/frame, so 20000/312 = ~64 cpu cycles / scanline

= 64 * 312 = 19968 cycles per frame.

This is likely more accurate than 20000, and AFAIK this is bourne out by Chema's comparisons against real hw.
User avatar
Symoon
Archivist
Posts: 2301
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Re: Cycles and video timing II

Post by Symoon »

Here's the program I made, counting 19992 cycles, but I may be wrong as it's the very 1st time I'm trying to do so. Please let me know if I made any mistake ;-)

BTW where can I find Fabrice's routine? I searched many topics here but didn't find it. Thanks!
Attachments
blink19992-OK.tap
Swapping red and yellow
(88 Bytes) Downloaded 681 times
User avatar
Chema
Game master
Posts: 3013
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: Cycles and video timing II

Post by Chema »

For example here:
http://forum.defence-force.org/viewtopi ... 2&start=30

Edit: just found the original reference here:
http://oric.free.fr/projects.html

And ready to use in OSDK:

Code: Select all

_Syncrho
.(
	STA $04     
	STX $03     
	LDA #$80    
	STA $00     
	LDA #$BB    
	STA $01     
	LDY #$00    
	CLC         
L1
	LDA $04     
	STA ($00),Y 
	LDX $03      
loop1
	DEX         
	BNE loop1   
	TYA         
	ADC #$28    
	TAY         
	BCC L1   
	LDA #$00    
	ADC $01     
	STA $01     
	CMP #$C0    
	BCC L1  
	RTS        
.)
_DoSync
.(
	SEI         
L6
	LSR $02DF   
	LDA #$40    
L2
	BIT $030D   
	BEQ L2   
	LDA #$11    
	LDX #$01    
	JSR _Syncrho   
	LDA #$12    
	LDX #$12    
	JSR _Syncrho   
	BRK         
	BRK         
	LDA $02DF   
	CMP #$D3    
	BNE L3   
	INC $0306   
	BNE L3   
	INC $0307   
L3
	CMP #$C6    
	BNE L4   
	LDX $0306   
	BNE L5   
	DEC $0307   
L5
	DEC $0306   
L4
	CMP #$D1    
	BNE L6   
	CLI         
	RTS         
.)
If you call DoSync() from the main program, a red band appears. The user may locate it at the bottom of the screen (using 'F' and 'S') and then 'Q' for exit. It sets the IRQ timer so you have an IRQ each vsync.
Post Reply