Line 140: |
Line 140: |
| | | |
| All of these registers must be accessed with 32bit operations regardless of the registers' actual bit size. | | All of these registers must be accessed with 32bit operations regardless of the registers' actual bit size. |
| + | |
| + | The naming of these parameters reflects the physical characteristics of the displays, and not the way the 3DS is normally held. |
| + | |
| + | To make sense of these values, the 3DS must be held in a way, so that the bottom screen is in the left hand, and the top screen is in the right hand, and that way the first pixel will be in the top-left corner, as it should be. If the 3DS is held normally, the first pixel is in the bottom-left corner. |
| + | |
| + | All pixel and scanline timing values are 12bits, unless noted. This also applies to those fields where two u16 are combined into one register. Each u16 field is only 12bits in size. |
| | | |
| {| class="wikitable" border="1" | | {| class="wikitable" border="1" |
Line 147: |
Line 153: |
| |- | | |- |
| | 0x00 | | | 0x00 |
− | | H-total (V-total on not physically rotated screens). | + | | HTotal |
− | | 12bits.
| + | | The total width of a timing scanline. In other words, this is the horizontal refresh clock divider value. |
| | | |
− | Setting this value too low will make the screen not be able to sync any pixels other than a single one from the wrong location. The lowest the screen can handle is 0x1C2, at 0x1C1 the display loses a few scanlines worth of pixel clock (though not noticable).
| + | HClock = PClock / (this value + 1) |
| |- | | |- |
| | 0x04 | | | 0x04 |
− | | HBlank timer(?) | + | | ? |
| | Seems to determine the horizontal blanking interval. | | | Seems to determine the horizontal blanking interval. |
| | | |
Line 209: |
Line 215: |
| |- | | |- |
| | 0x24 | | | 0x24 |
− | | V-total (H-total on not physically rotated screens). | + | | VTotal |
− | | Total scanlines including porches/sync timing. Setting this to 494 for the topscreen lowers framerate to about 50.040660858 Hz. | + | | Total height of the timing window. Can be interpreted as the vertical clock divider. |
| + | |
| + | VClock = Pclock / (HTotal + 1) / (VTotal + 1) |
| + | |
| + | Setting this to 494 lowers framerate to about 50.040660858 Hz (268111856 / 24 / (250 + 1) / (494 + 1)). |
| |- | | |- |
| | 0x28 | | | 0x28 |
− | | VBlank timer(?) | + | | ? |
| | Seems to determine the vertical blanking interval. | | | Seems to determine the vertical blanking interval. |
| | | |
Line 224: |
Line 234: |
| |- | | |- |
| | 0x30 | | | 0x30 |
− | | VTotal | + | | ? |
| | Total amount of vertical scanlines in the pixel buffer, must be bigger than *an unknown blanking-like value*. If this value is less than VDisp then the last two scanlines will be repeated interlaced until VDisp is reached. | | | Total amount of vertical scanlines in the pixel buffer, must be bigger than *an unknown blanking-like value*. If this value is less than VDisp then the last two scanlines will be repeated interlaced until VDisp is reached. |
| |- | | |- |
Line 251: |
Line 261: |
| | 0x4C | | | 0x4C |
| | Overscan filler color | | | Overscan filler color |
− | | | + | | 24bits(? top 8bits ignored) |
| + | |
| + | When the visible region is being drawn, but the timing parameters are set up in a way that the framebuffer is smaller than the visible region, it will be filled by this color. |
| |- | | |- |
| | 0x50 | | | 0x50 |
Line 301: |
Line 313: |
| Bit 4: Currently displaying framebuffer? | | Bit 4: Currently displaying framebuffer? |
| Bit 8: Reset FIFO? | | Bit 8: Reset FIFO? |
− | Bit 16: H(Blank?) IRQ status/ack. Write 1 to aknowledge. | + | Bit 16: HBlank IRQ status/ack. Write 1 to aknowledge. |
| Bit 17: VBlank IRQ status/ack. | | Bit 17: VBlank IRQ status/ack. |
| Bit 18: Error IRQ status/ack? | | Bit 18: Error IRQ status/ack? |
Line 316: |
Line 328: |
| | 0x90 | | | 0x90 |
| | Framebuffer stride | | | Framebuffer stride |
− | | Distance in bytes between the start of two framebuffer rows (must be a multiple of 8). | + | | 32bits (bottom 3bits ignored?) |
| + | |
| + | Distance in bytes between the start of two framebuffer rows (must be a multiple of 8). |
| | | |
| In other words, this can be interpreted as the amount to add to the framebuffer pointer after displaying a scanline. | | In other words, this can be interpreted as the amount to add to the framebuffer pointer after displaying a scanline. |
Line 322: |
Line 336: |
| Setting this to zero will cause only the first line of the image to be displayed repeated on the entire display. With the HSync interrupt it's possible to "race the beam" to (ab)use this feature. | | Setting this to zero will cause only the first line of the image to be displayed repeated on the entire display. With the HSync interrupt it's possible to "race the beam" to (ab)use this feature. |
| | | |
− | Because of this simplicity, writing a negative value here VFlips the image (which appears as a HFlip if the 3DS is held properly) | + | Because of this simplicity, writing a negative value here VFlips the image, although that requires the framebuffer pointer register to be set to the start of the last scanline, instead of at the start of the framebuffer. |
| |- | | |- |
| | 0x94 | | | 0x94 |
| | Framebuffer B first address | | | Framebuffer B first address |
− | | For top screen, this is the right eye 3D framebuffer. Unused for bottom screen. | + | | For top screen, this is the right eye 3D framebuffer. Unused for bottom screen in userland. |
| |- | | |- |
| | 0x98 | | | 0x98 |
| | Framebuffer B second address | | | Framebuffer B second address |
− | | For top screen, this is the right eye 3D framebuffer. Unused for bottom screen. | + | | For top screen, this is the right eye 3D framebuffer. Unused for bottom screen in userland. |
| |} | | |} |
| | | |