Line IRQ Timing

Get help from the community & developers with the X16 hardware if you can't find the solution elsewhere
Elektron72
Posts: 137
Joined: Tue Jun 30, 2020 3:47 pm

Line IRQ Timing

Post by Elektron72 »


Does anyone know exactly when the VERA triggers line IRQs? Ideally, I hope it can trigger an IRQ as soon as it is done drawing the visible part of the previous line. This would give programmers the maximum amount of time for routines that alter the screen between lines.

Ender
Posts: 220
Joined: Sat May 09, 2020 9:32 pm

Line IRQ Timing

Post by Ender »


That can be configured in the VERA by setting the lower 4 bits of the IEN register ($9F26).  If you set bit 2, then it will trigger at the end of a line.  Looking at the emulator code, it looks like it's right when you are hoping, when it is done drawing the visible area of the line.


Quote




float advance = ((out_mode & 2) ? NTSC_PIXEL_FREQ :  VGA_PIXEL_FREQ) / mhz;

scan_pos_x += advance;

if (scan_pos_x > SCAN_WIDTH) {

     ....

    if (ien & 2) { // LINE IRQ

        ....



 

Elektron72
Posts: 137
Joined: Tue Jun 30, 2020 3:47 pm

Line IRQ Timing

Post by Elektron72 »


SCAN_WIDTH includes the horizontal back porch of the previous line. This means that the IRQ (at least in the emulator) doesn't trigger until the beginning of the horizontal front porch of the line that the interrupt is set to trigger on. Triggering the interrupt on the line before as soon as scan_pos_x is greater than the sum of SCREEN_WIDTH and either VGA_FRONT_PORCH or NTSC_FRONT_PORCH (changes depending on the video mode) would provide much more time to interrupt routines. Although changing the emulator would be relatively simple, I want to make sure that this will (hopefully) reflect the actual hardware.

Guybrush
Posts: 63
Joined: Fri Jul 10, 2020 10:38 pm

Line IRQ Timing

Post by Guybrush »


Be aware that VERA hardware will probably have very different timings. The emulator renders the current line into the buffer in one cycle (from the CPU's perspective), while real hardware will be rendering most of the time during the scanline. If I'm understanding things correctly, real VERA will actually be rendering the next scanline into 3 separate line buffers (sprites, layer 0, layer 1) while it composes and outputs the current scanline from its line buffers. Which means that VERA is actually using a sort of scanline double buffering internally. See this comment from VERA's designer, Frank van den Hoef.

I suppose VERA hardware could latch the contents of its registers (layer settings, sprite settings etc.), but it's not going to be latching the VRAM. Therefore, writes to VRAM might affect the rendering of the scanline on real hardware. And if VERA doesn't perform any latching of its registers, any changes of those registers may also affect the rendering of the current (actually, next) scanline.

So, it really remains to be seen how the real hardware handles the rendering and what are the exact timings, e.g. when does the rendering of the scanline start/end and which, if any, registers are being latched. At this time it is only safe to assume that any changes that might affect the rendering of the scanline can only be made during a small window, but since we don't know where and how long this window is, we're back to square one ?

TL;DR the emulator is not at all accurate when it comes to line interrupts. Any effects you create and test with the emulator may or may not work on real hardware. YMMV.

Ender
Posts: 220
Joined: Sat May 09, 2020 9:32 pm

Line IRQ Timing

Post by Ender »



45 minutes ago, Elektron72 said:




SCAN_WIDTH includes the horizontal back porch of the previous line. This means that the IRQ (at least in the emulator) doesn't trigger until the beginning of the horizontal front porch of the line that the interrupt is set to trigger on. Triggering the interrupt on the line before as soon as scan_pos_x is greater than the sum of SCREEN_WIDTH and either VGA_FRONT_PORCH or NTSC_FRONT_PORCH (changes depending on the video mode) would provide much more time to interrupt routines. Although changing the emulator would be relatively simple, I want to make sure that this will (hopefully) reflect the actual hardware.



Ah right.  SCAN_WIDTH is 800 and the SCREEN_WIDTH is 640.  Yeah, that's unfortunate, then.  But as @Guybrush says, the real hardware will be different anyway.  I wonder how hard it would be to more accurately emulate the real hardware?  Based on his description it seems doable, but it would be a big rewrite.

Elektron72
Posts: 137
Joined: Tue Jun 30, 2020 3:47 pm

Line IRQ Timing

Post by Elektron72 »


I decided to calculate how many cycles programmers will have depending on where the IRQ triggers:


  • Beginning of front porch of IRQ line

    This is where the emulator currently triggers line IRQs. However, its effects are not immediately obvious, since the emulator instantly renders everything at the end of the line.

    Doing some calculations (numbers are rounded), we can determine:

    8000000 Hz (processor speed) / 60 Hz (refresh rate) = 133333 cycles per frame

    133333 / 525 (number of lines per frame) = 254 cycles per line

    254 / 800 (number of pixels in a line) = 0.32 cycles per pixel

    16 (number of pixels in the VGA front porch) * 0.32 = 5 cycles

    5 cycles is enough time to run about two short instructions. There isn't enough time to do anything useful before the visible area of the screen begins. Additionally, the 65C02 must also finish its current instruction before handling an interrupt, which will likely take a few cycles. After finishing the instruction, the CPU will jump to ROM before going to a user routine. This routine spends the remaining cycles pushing the registers onto the stack, and jumping to the user routine. With this timing, there is no safe window where changes can be made.


  • Beginning of back porch 

    This would be the ideal time to trigger the line IRQ in order to give the maximum available time to IRQ handlers.

    800 (number of pixels in a line) - 16 (number of pixels in the VGA front porch) - 640 (number of pixels in a visible line) = 144 pixels in the VGA back porch

    144 * 0.32 = 46 cycles

    46 cycles is enough time to make multiple changes to the VERA's registers, allowing for a wide variety of visual effects without any on-screen distortion.


Overall, if the actual hardware triggers an interrupt at the beginning of the front porch rather than the back porch, it will greatly hamper the usefulness of line IRQs.

TomXP411
Posts: 1785
Joined: Tue May 19, 2020 8:49 pm

Line IRQ Timing

Post by TomXP411 »



6 hours ago, Elektron72 said:




Beginning of back porch 

This would be the ideal time to trigger the line IRQ in order to give the maximum available time to IRQ handlers.



I think you have your nomenclature backward. The porches surround hsync, so the front porch is the blank time before the sync pulse. This actually puts the 16 pixel front porch at the end of the scan line and at the beginning of the blanking interval. If the interrupt is actually fired on the front porch, this gives us the longest period of time to work between frames. 

From a hardware standpoint, the simplest time to trigger an interrupt is on the rising edge of the horizontal sync. Since the hardware has to trigger the sync pulse anyway, the IRQ line can be tied to the sync pulse and trigger at the same time. Triggering at the end of hsync is also fairly easy, since that's just a matter of inverting the hsync output. 

Display Timings 

https://projectf.io/posts/video-timings-vga-720p-1080p/

So let's analyze the timing:

According to the this page, the porch timings are:

Pixel Clock: 25.175 MHz. 

Front porch: 16

Sync: 96

Back Porch: 48

I'm thinking the clock generator will be driven by the video clock, or 25.175/3 MHz. This gives us 8.4MHz. 


  • The total blank time between lines is 160 pixels, or 53 clock ticks. This is room for roughly 10-13 ML instructions.


  • The back porch is 16 clock ticks, or 3-4 instructions.


  • The front porch is 5 clock ticks, enough for two instructions in the absolute best case. 


So losing the front porch doesn't lose that much time, basically one instruction, but losing the hsync means not really having enough time to get anything done between raster lines. 

 


image.png
Ender
Posts: 220
Joined: Sat May 09, 2020 9:32 pm

Line IRQ Timing

Post by Ender »



31 minutes ago, TomXP411 said:




Pixel Clock: 25.175 MHz. 

Front porch: 16

Sync: 96

Back Porch: 98



This gives us roughly 3 pixels per 6502 clock tick, which we can use for some rough back of the napkin calculations:




  • The total blank time between lines is 210 pixels, or 70 clock ticks.


  • The back porch alone is 32 clock ticks.


  • hsync + back porch is 64 ticks




I think that's 48 on the back porch, and a total of 160, not 210? Which is 53 clock ticks total: 16 for the back porch, and hsync+back porch is 48.  If we assume an average of 4 ticks/instruction, that's 4, 12, or 13 instructions.

TomXP411
Posts: 1785
Joined: Tue May 19, 2020 8:49 pm

Line IRQ Timing

Post by TomXP411 »



4 hours ago, Ender said:




I think that's 48 on the back porch, and a total of 160, not 210? Which is 53 clock ticks total: 16 for the back porch, and hsync+back porch is 48.  If we assume an average of 4 ticks/instruction, that's 4, 12, or 13 instructions.



Yes, it was a typo. 

I believe the CPU clock will be based on the video clock (this a super common design, and why we see weird speeds like 3.54 MHz or 1.79 Mhz. The closest speed to 8MHz is actually 8.391Mhz, or the 25.175MHz pixel clock divided by 3.

 

 

Elektron72
Posts: 137
Joined: Tue Jun 30, 2020 3:47 pm

Line IRQ Timing

Post by Elektron72 »



13 hours ago, TomXP411 said:




I think you have your nomenclature backward. The porches surround hsync, so the front porch is the blank time before the sync pulse. This actually puts the 16 pixel front porch at the end of the scan line and at the beginning of the blanking interval. If the interrupt is actually fired on the front porch, this gives us the longest period of time to work between frames. 



Thanks for the correction; I had assumed it was the other way around. While the current version of the emulator does not account for horizontal timing, it does count the vertical front porch lines at the beginning of a frame, rather than at the end. I might open a pull request to fix this.

Post Reply