diff options
author | lonkaars <loek@pipeframe.xyz> | 2023-02-07 19:40:53 +0100 |
---|---|---|
committer | lonkaars <loek@pipeframe.xyz> | 2023-02-07 19:40:53 +0100 |
commit | d74668c6ecd13d0eea7811d0b881eed2bfffa162 (patch) | |
tree | 03023957ebdb0ecd80fe3ae953076b9ece6152fe /docs | |
parent | 2662b6ff63ab7ff1dc039ce88baf1d08441bd2c2 (diff) |
more PPU documentation
Diffstat (limited to 'docs')
-rw-r--r-- | docs/ppu.drawio | 2 | ||||
-rw-r--r-- | docs/research.md | 78 |
2 files changed, 77 insertions, 3 deletions
diff --git a/docs/ppu.drawio b/docs/ppu.drawio index 17ea515..2efedf8 100644 --- a/docs/ppu.drawio +++ b/docs/ppu.drawio @@ -1 +1 @@ -<mxfile host="Electron" modified="2023-02-05T15:24:04.957Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/20.8.16 Chrome/106.0.5249.199 Electron/21.4.0 Safari/537.36" etag="Sw92OaPQb4kISNLgk6ge" version="20.8.16" type="device" pages="2"><diagram name="level-1" id="DBE48RpXtx8JnoEt3ekA">7Vpdb9owFP01SNsDVb6BxwApndQiBLRbH11iQjaDI8cU2K+f09iExEBIQwma6EMV31xfO8fnXPu6remd+bpHQDB7wi5ENU1x1zW9W9M0w2yx35FhExuaViM2eMR3Y5OaGEb+X8iNCrcufReGKUeKMaJ+kDZO8GIBJzRlA4TgVdptilF61AB4UDKMJgDJ1p++S2f8K0wlsT9A35uJkVWFv5kD4cwN4Qy4eLVj0p2a3iEY0/hpvu5AFGEncIn73R94u50YgQt6Sgdz84PSX3S8VMerV4T7lqM81HmUd4CW/IPbINyEOrPdD3p2TbMQC95+I+zJi54Gg2f+OXQjMCJ4uXBhNIzCPFYzn8JRACbR2xUjBbPN6Byxlsoe5WmLOUBC4XrHxD+jB/EcUrJhLuJtk0PKOaXz5ipZINXittnu4ghHwEnhbUMnuLEHDl0BGDUJxq4fBghEk8ZLGiypjOS3l579vXIs9ROwVC6KpS5hORo/6dq90lKHHRnGzhUQUm/dtRonwHin6JdEUm1IUL4M7ae63e0OJczgwrWjfMlaEwTC0J+kYUpjCl2WJXlnTOgMe3gBkJNY2xC9fQSLUPRZPmUmgHxvwUwITqOVYwkxiPpPEVzzodshJfjPNtNG47J58V1B/3gPCN1ps6YH6QASn0EGSbTK/sITC8/DGKLjNq4SB061D/IgxEsygfmMjeeSn2wj7E5KcxKFzD1CFDYCEaD+e3rb2kcpPt4A++w7k8GMgxwWQWIceL/djSYTSmtKoYxMKL5s2VCMBR8pU7gFkUN4ZNKNdPJSs1tgMX/2EM8g01tMB0+nIaS1rCy3K1dCqc39Su3aY/tKlVpMXMdVfJPeuaRnGtlQjS+SnilNWjVy1JfbpToBGrL+6qPXfkcWX66c0vJLfB4xDrhCf0NKN5z/YElxWr9CfCRmWgl1iIIpTx1aMXWIuMV4X5RhuplO1uZxdh13r45ZlsSshxuzKmaWlaZKI4dZR92rY5Z8Zhg63RutriZhibr51IyV8a+OWC2JWL2h4/Rv1LoeauUUOjn+FRY6isSt9uOzc6PW9VAr5xSf418dtTSZWk7fbj/uIdfFC+jPc+tW4GYKXClU64sKXEsaKacCye1RoTbkS/Xq69vS2jg17+qf0kZJ0hvqITYUJr0h/32hno11JtaXLLpzjiVaGe+r0ZJ8V1R9Rf+fa0mTBJC91iyjpexmdC4tlbtmUHN2mzLe13KFoe27wxg5Y1lKtyPbZY9spnKn7PyoKfpYnxSf2lKOxjnb0a2Q8I67f4U4WDP5v5/YPfnnKd35Bw==</diagram><diagram id="lj51MlK96fuJFRP7cw84" name="level-2">1Zhbs5owEMc/DY9nhouKPnrQY2tr6xw79bGTwgqpgTAxXj99FwkqBtueViu+OMk/t81vF5bVcLx4MxAkjUY8AGbYZrAxnJ5h241mB38zYZsL7ZabC6GgQS5ZR2FCd6BEU6lLGsCiNFFyziRNy6LPkwR8WdKIEHxdnjbjrHxqSkLQhIlPmK5OaSAjdYumedTfAQ2j4mTLVCMxKSYrYRGRgK9PJKdvOJ7gXOateOMBy9gVXPJ1LxdGD4YJSOSfLHhNv3/ytkP4xqMfg9FwKMzZ7snOd1kRtlQX9j5+UPbKbQFB8GUSQLaPaTjP64hKmKTEz0bX6HXUIhkz7FnY1O1Spq5ASNicSMrOAfAYpNjilE3Z+dtyd310QEdJ0Qn7widEuTw87Hukgg0F5g2QHA3S10E3I0TDhGSrQ0hAEMnF/cnVDF1DQ/dM/Hm4x7J/auOUL2gdyJ0HnXtnck2N3AsXUEdy5zF3b3ItjdyY+nIpIDssCOD+xOr2gnM1YpNUIATU8JZIrAbMahZkbT0nvHZH/0Ypg0Hx06PLMLGgJnl6HXbO38Wb5d6KXkdPC9eGF9MgyDa6Cj+7zK+h83Mr+Nm3wlf47zQ5PBK/1r35WRq/L5RBjEwehuGh0PgNxJs9w5ZeO4yxbJISy7WHodj+f5FoD6bcnXhi3vu8m9uyP6L91ZMeiNP3Yw0fXk6WGS2k4HPwOMPvP6eX8CTjM6OMnUlEMfQRGSbxX8CtckrZbRdYV3jkchI/D+KKN2mrgr/zdv7YPdbW+7GTPyic/k8=</diagram></mxfile>
\ No newline at end of file +<mxfile host="Electron" modified="2023-02-07T18:38:14.606Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/20.8.16 Chrome/106.0.5249.199 Electron/21.4.0 Safari/537.36" etag="JN-PGJMUQf8Og2T_o1es" version="20.8.16" type="device" pages="3"><diagram name="level-1" id="DBE48RpXtx8JnoEt3ekA">7Vtbd6I6FP41rjXnoV0EBOsjXtqe08txqaetjyhRmYnEBbHq/PoJmohJKJZjgWGNvkh2di7sb+fbOzHWjPZicxc4y/kTdiGq6Zq7qRmdmq6DOqjTr0iy3UturMZeMAs8lynFgoH3EzKhxqQrz4WhoEgwRsRbisIJ9n04IYLMCQK8FtWmGImjLp0ZVASDiYNU6avnkjl7C1OL5ffQm835yEBjNQuHKzNBOHdcvD4SGd2a0Q4wJvunxaYNUWQ8bpd9u9sPag8TC6BPPtPA3P5NyBsZrsBwPUL42epq91esl3cHrdgLt5xwGxpUdtu7s2u6hWjnrXFAn2bRU6/3H3sdsuU2CvDKd2E0jEY11nOPwMHSmUS1a+oVVDYnC0RLgD6GtMbzZ49wGs36ytRiWZ/ZURCyXpEzhqiHQ4942KeyCX1rGNCKdxgQj+L1KCmMMSF4QRUc5M0SW9isguBoiqo5uW2oOtwciZh57yBeQBJsqQqvtRjUzNcNVlzHjgO4N8yPnYYrOsxZZ4euYzzpA4M0A7y6Am/HC5fIiSaNV2S5IirC317u7L8uGH+AsaGfxPgmL4jfIVo+rf4F24dO/3YBn8c9958rYClYQZdSGCvigMzxDPsO6sbSlohmrPOIIzvtMPwOCdkyPnZWBIsIQ59ztZ5m1xCvgglMcVCDUboTzCBJeUsWNKI3S0UpgMgh3rtI3kk2Z0172KNTjlewKaJrSqjt58kaxcDZQbBbUlxtGSmEKcMY4jB1U2TuTOr0YT9+7EMHg5zhVjd/gls1c3GrzO5QF/G1TrhDqvrZ7vDwaL8sRqPR20O36W3sn2NsvXKDnuEN4Q9IJvP/7xqH9GnXGUWW2FF6RwU+9iGX3XrRe+10vtR7Eo2i/x7eI7ED0LKxiaR/tv+kmfQoERkMnwz9VmuCflvNQdqXLPPjDKR53WyczkGuNaPITJPHiyOEVcrwXb5mJ8gJQ28igiYifJpgIBrvOuOmPoIB7YCPSGMZtZ8iuGFDt7iV6pwz+L7O2gcgqXgUj3barGwUEp+A8UmK2QjjHzmCmZCMctm5yRKQUuGG5Fx7MyjZktKRLufUzZzSLilwglN5V7q+yJRxaz4dPJ2GkNTklfUFyVldWWsvg9FzW1lwlFGIxIskwD9gGyMcxJFzSoOmJJLWkUxmC891d0swiYaluC8QrMTBmkLVqXlfRpLU4o8hAFlP2Jgnbdry2rOZCn73F/wy4GeVjB9oqrHtt9wcJc7eUoNP2uFRyemtATLtldPV89kr6/Vy3IHO+o0nS1FhFBWuTV7sbI4rO9tDKTc3SgtWJbuR3szkRrK6fLYuq5+jXYSLWoVlDMGef3MLOV8UYPSGBELJIaWhANR9tluP3erlBMK++muzAvkHlnqRCB1+x6tk0L+pVtDXRKBPnIimq+cU9M0/MegnuFHaDqfabgTSwzg4R7sIF1WP5PLaZlY06Je9j2wqAPW7g+7wEvNTYr5VaMxPOMSuTsznZqlo0AdGRro2ivhdXFPW7N2FUGMIyj6ZUy+0vfTtpyu70+lXkFaj24QF8WryzbTciPX8CwVlEqtebWI9dYaarp8TserKym1diDWGoGxiVW9w7Ii1Yw/tC7GmEmuxp1RAQaNKxFqvNrHqGYlVL4JY1dsCeaRCVSVWvWxiVS8DqCv4cnEq68Up8EmCKOXilKFda8cfS3RJzUysznqtCjTOGiavS1cnOPKEfiGXrtJu+8oJ0Gv3+ZL/pOY/2tfQKS3Gf5bbgxr/5dDo/gI=</diagram><diagram id="MdQQJuunD4ehtDpxKxax" name="level-2">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</diagram><diagram id="lj51MlK96fuJFRP7cw84" name="level-3">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</diagram></mxfile>
\ No newline at end of file diff --git a/docs/research.md b/docs/research.md index 6e16bc8..acb1c24 100644 --- a/docs/research.md +++ b/docs/research.md @@ -172,12 +172,86 @@ Notable differences: ![PPU top-level design](../assets/ppu-level-1.svg) -![PPU level 2 design](../assets/ppu-level-2.svg) +Important notes: + +- The STM32 receives 'feedback' lines from the PPU. These are mirrors of the + VSYNC and HSYNC lines from the VGA signal generator. These lines can be used + to trigger interrupts for counting frames, and to make sure no read/write + conflicts occur for protected memory regions in the PPU. +- The STM32 can enable and reset the PPU. These lines will also be connected to + physical buttons on the FPGA. +- The STM32 uses direct memory access to control the PPU. + +![PPU level 2 design (data flows from top to bottom)](../assets/ppu-level-2.svg) + +Important notes: + +- The pixel fetch logic is pipelined in 3 stages: + 1. - (Foreground sprite info) calculate if foreground sprite exists at current pixel using FAM register + - (Background sprite info) get background sprite info from BAM register + 2. - (Sprite render) calculate pixel to read from TMM based on sprite info + 3. - (Compositor) get pixel with 'highest' priority (pick first foreground + sprite with non-transparent color at current pixel in order, fallback to + background) + - (Palette lookup) lookup palette color using palette register + - (VGA signal generator) output real color to VGA signal generator +- The pipeline takes 5 clock ticks in total. About 18 are available during each + pixel. For optimal display compatibility, the output color signal should be + stable before 50% of the pixel clock pulse width (9 clock ticks). +- RAM regions mentioned that don't have a block right of the PPU RAM bus in + this graphic, are stored in and exposed by the component that mentions the + memory region. +- Each foreground sprite render component holds its own sprite data copy from + the RAM in it's own cache memory. The cache updates are fetched during the + VBLANK time between each frame. +- Since the "sprite info" and "sprite render" steps are fundamentally different + for the foreground and background layer, these components will be combined + into one for each layer respectively. They are separated in the above diagram + for pipeline stage illustration. +- The pipeline stages with two clock cycles contain an address set and memory + read step. +- The palette lookup component has separate memory that is connected to the PPU + RAM bus for read/write access. + +### Registers + +|Address range |Alias|Description| +|-----------------|-----|-----------| +|`0x0000`-`0x0000`|TMM |[tilemap memory][TMM]| +|`0x0000`-`0x0000`|BAM |[background attribute memory][BAM]| +|`0x0000`-`0x0000`|FAM |[foreground attribute memory][FAM]| +|`0x0000`-`0x0000`|PAL |[palettes][PAL]| +|`0x0000`-`0x0000`|BAX |[background auxiliary memory][BAX]| + +[TMM]: #tilemap-memory +#### Tilemap memory + +- TODO: list format + +[BAM]: #background-attribute-memory +#### Background attribute memory + +- TODO: list format + +[FAM]: #foreground-attribute-memory +#### Foreground attribute memory + +- TODO: list format + +[PAL]: #palettes +#### Palettes + +- TODO: list format + +[BAX]: #background-auxiliary-memory +#### Background auxiliary memory + +- background scrolling [nesppuspecs]: https://www.copetti.org/writings/consoles/nes/ [nesppudocs]: https://www.nesdev.org/wiki/PPU_programmer_reference [nesppupinout]: https://www.nesdev.org/wiki/PPU_pinout -[custompputimings]: https://docs.google.com/spreadsheets/d/1MU6K4c4PtMR_JXIpc3I0ZJdLZNnoFO7G2P3olCz6LSc/edit?usp=sharing +[custompputimings]: https://docs.google.com/spreadsheets/d/1MU6K4c4PtMR_JXIpc3I0ZJdLZNnoFO7G2P3olCz6LSc # Generating audio signals |