Changing Border during refresh

Página 2/2
1 |

Por tvalenca

Paladin (747)

Imagen del tvalenca

31-08-2016, 19:54

ARTRAG wrote:

Tiago read also the links on C64 in the other thread about HW capabilities in 80's. The same jittering issue on c64 is solved in many ways.
Look for the sction "Stable Raster Interrupts"
http://z9.io/wp-content/uploads/2008/01/intro-to-programming...

"Double interrupts" seems feasible also on msx. ;)

Thanks! I'll have a look on this also.

It's good to finally dust off my coding skills on something fun... (and develop some ASM coding skills in the process) Altough there's nothing cool hapening (yet)

Por RetroTechie

Paragon (1563)

Imagen del RetroTechie

31-08-2016, 23:48

tvalenca wrote:

Do anyone know how much time I have before the VDP begins to plot the next scanline?

See TMS9918 VDP datasheet, chapter 3.6 "Oscillator and clock generation". Especially the table in chapter 3.6.2 has what you need.

According to that, pixel clock is 5.37 MHz, and 342 pixel clock cycles TOTAL for each line, with either 240 or 256 cycles in active display area. So a full screen line takes ~63.7 µS. Right blanking + horizontal sync + left blanking + color burst + left blanking = 58 cycles = ~10.8 µS. I suppose that would be a good time to switch border color. Or switch in the middle of active screen area? That way you'd have 1 screen line with one border color on left side & another border color on right side (and any jitter hidden behind active display?).

Each 5.37 MHz pixel clock equals ~2/3 Z80 clock cycle, and for many MSX1's it will be exactly that (so for example 15 pixels = 10 Z80 cycles).

Not sure how this is for V9938/9958. But I suppose for MSX1 compatible screen modes, VDP timing should be very similar.

Por RetroTechie

Paragon (1563)

Imagen del RetroTechie

01-09-2016, 00:03

Btw, interesting to know: you can set delays in your code with 1 Z80 clock cycle accuracy. Shocked!

Each Z80 instruction takes at least 4 cycles (and MSX adds 1 to each instruction, so 5 cycles minimum per instruction). But you can replace a 5-cycle instruction with a 6-cycle one. And a 6-cycle one with a 7-cycle one, and so forth.

Following the above, this means that timing-wise, you can move color changes left or right in 1,5 pixel increments. Cool (not saying any of that is easy, but that's what you as programmer could make the hardware do).

Por Overflow

Resident (57)

Imagen del Overflow

01-09-2016, 11:49

ARTRAG wrote:

(...) same jittering issue on c64 is solved in many ways. (...)
"Double interrupts" seems feasible also on msx. Wink

Actually it is not feasible on msx. Let me explain.

C64 does not have a z80 but another (smart) cpu -> NOP or other simple instructions requires ONE cycle only.This does means: interrupting a NOP allow some ONE-cycle precision.

On our z80, architecture is different. Simple instruction such as NOP or HALT requires 5 cycles. It means: using a double-interrupt with NOPs (or using HALT) would lead to 5-cycles precision only.

(You could ask: so how to achieve 1-cycle precision? read next message.)

Por Overflow

Resident (57)

Imagen del Overflow

01-09-2016, 11:57

RetroTechie wrote:

(...) you can move color changes left or right in 1,5 pixel increments. Cool (not saying any of that is easy, but that's what you as programmer could make the hardware do).

This is what I did, as I stated previously: watch this demo (youtube video - starts at 1min36s)
To achieve this, I did not rely on interruption to synchronize, because it does not have a 1-cycle precision (read what I wrote previsously).
To achieve this, I wrote some code so that it takes exactly 71364 cycles. Which is the exact number of cycles a frame has (... from a cpu POV, since the VDP might have its own clock). Part of the difficulty there was also: writing a music-player which takes same amount of cycle at each frame call.

Por tvalenca

Paladin (747)

Imagen del tvalenca

01-09-2016, 20:38

RetroTechie wrote:
tvalenca wrote:

Do anyone know how much time I have before the VDP begins to plot the next scanline?

See TMS9918 VDP datasheet, chapter 3.6 "Oscillator and clock generation". Especially the table in chapter 3.6.2 has what you need.

According to that, pixel clock is 5.37 MHz, and 342 pixel clock cycles TOTAL for each line, with either 240 or 256 cycles in active display area. So a full screen line takes ~63.7 µS. Right blanking + horizontal sync + left blanking + color burst + left blanking = 58 cycles = ~10.8 µS. I suppose that would be a good time to switch border color. Or switch in the middle of active screen area? That way you'd have 1 screen line with one border color on left side & another border color on right side (and any jitter hidden behind active display?).

Yes, that happened. but since I was using SCREEN 0 for demonstration, there's only backdrop color and foreground color, and the jitter anoying your eyes in the middle of the screen. (see my video on the first page of the thread)

RetroTechie wrote:

Each 5.37 MHz pixel clock equals ~2/3 Z80 clock cycle, and for many MSX1's it will be exactly that (so for example 15 pixels = 10 Z80 cycles).

Not sure how this is for V9938/9958. But I suppose for MSX1 compatible screen modes, VDP timing should be very similar.

I'm not sure about the exact timming, but numbers are showing very similar, at least on OpenMSX. The jitter occurs on groups of 5 horizontal pixels

RetroTechie wrote:

Btw, interesting to know: you can set delays in your code with 1 Z80 clock cycle accuracy. Shocked!

Each Z80 instruction takes at least 4 cycles (and MSX adds 1 to each instruction, so 5 cycles minimum per instruction). But you can replace a 5-cycle instruction with a 6-cycle one. And a 6-cycle one with a 7-cycle one, and so forth.

Following the above, this means that timing-wise, you can move color changes left or right in 1,5 pixel increments. Cool (not saying any of that is easy, but that's what you as programmer could make the hardware do).

I grew quite annoyed of "NOPing" the pixels all the way out of the screen so I begun using PUSH IX/POP IX (now I realized that LD (nn), IX would take longer and won't risk destroying anything in the process)

But I found out another anoying thing: the refresh (50/60Hz) interrupt is being fired right after the last line of active video! so, if I use H.TIMI to "reset" screen colors, (and I am doing exactly this) I will have the bottom border in a different color than the one i used on the active video area! With jitter on the middle of the screen and everything!

Overflow wrote:
RetroTechie wrote:

(...) you can move color changes left or right in 1,5 pixel increments. Cool (not saying any of that is easy, but that's what you as programmer could make the hardware do).

This is what I did, as I stated previously: watch this demo (youtube video - starts at 1min36s)
To achieve this, I did not rely on interruption to synchronize, because it does not have a 1-cycle precision (read what I wrote previsously).
To achieve this, I wrote some code so that it takes exactly 71364 cycles. Which is the exact number of cycles a frame has (... from a cpu POV, since the VDP might have its own clock). Part of the difficulty there was also: writing a music-player which takes same amount of cycle at each frame call.

I understand that this is only possible when your application takes complete control of the computer, in a very "Spectrum" way of coding. But at least in my case, I'm interacting with BIOS interrupt handlers and BASIC interpreter, so AFAIK I can't really depend on cycle-accurate code here. But this is superb for Demos...

Por tvalenca

Paladin (747)

Imagen del tvalenca

02-09-2016, 22:01

For whow it may interest, that's my latest code. Making it follow the guidelines make almost all jittering gone (I think this will need some testing on different machines and emulator configurations).

Again, I didn't used an assembler, I started poking the opcodes directly on RAM, then I got an hexadecimal editor and made it a BLOADable ,r BIN file. The ASM listing is from BlueMSX debugger:

9000:   ld     hl,#0007   
9003:   ld     c,(hl)     
9004:   inc    c          
9005:   ld     a,#01      
9007:   out    (c),a      
9009:   ld     a,#8f      
900B:   out    (c),a      
900D:   ld     hl,#0006   
9010:   ld     c,(hl)     
9011:   inc    c          
9012:   in     a,(c)      
9014:   ld     b,a        
9015:   ld     hl,#0007   
9018:   ld     c,(hl)     
9019:   inc    c          
901A:   ld     a,#00      
901C:   out    (c),a      
901E:   ld     a,#8f      
9020:   out    (c),a      
9022:   ld     a,b        
9023:   bit    0,a        
9025:   ret    z          
9026:   ld     a,(#fff2)  
9029:   cp     #25        
902B:   jr     nz,#9041   
902D:   ld     a,#17      
902F:   out    (c),a      
9031:   ld     a,#87      
9033:   out    (c),a      
9035:   ld     a,#d6      
9037:   ld     (#fff2),a  
903A:   out    (c),a      
903C:   ld     a,#93      
903E:   out    (c),a      
9040:   ret               
9041:   cp     #d6        
9043:   jr     nz,#904e   
9045:   ld     a,(#f3e6)  
9048:   out    (c),a      
904A:   ld     a,#87      
904C:   out    (c),a      
904E:   ld     a,#25      
9050:   ld     (#fff2),a  
9053:   out    (c),a      
9055:   ld     a,#93      
9057:   out    (c),a      
9059:   ret               
905A:   di                
905B:   ld     hl,#0007   
905E:   ld     c,(hl)     
905F:   inc    c          
9060:   ld     a,#cd      
9062:   ld     (#fd9a),a  
9065:   ld     a,#00      
9067:   ld     (#fd9b),a  
906A:   ld     a,#90      
906C:   ld     (#fd9c),a  
906F:   ld     a,(#f3df)  
9072:   or     #10        
9074:   out    (c),a      
9076:   ld     a,#80      
9078:   out    (c),a      
907A:   ei                
907B:   ret               

Where, &H9000 is the starting of interrupt routine pointed by H.KEYI hook, and &H905A is the routine that installs the hook (I think it would need a little improvement) and turns on line interrupting generation.

I want to thank you everyone that contributed on this. You rock!

Por PingPong

Prophet (3898)

Imagen del PingPong

29-10-2017, 18:42

The most fast operation takes 2 cycles on 6510

Página 2/2
1 |