From e29ef0c70b44f075c1b082c452d0367f9426adde Mon Sep 17 00:00:00 2001 From: bbbbbr Date: Thu, 29 Apr 2021 22:55:53 -0700 Subject: [PATCH 1/3] Add STAT to phrasing to clarify & emphasize the interrupt they are associated with Also helps to slightly disambiguate the STAT Vblank Interrupt from the regular Vblank Interrupt --- content/Video_Display.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/Video_Display.md b/content/Video_Display.md index 2d5b3d0b..c7dc159a 100644 --- a/content/Video_Display.md +++ b/content/Video_Display.md @@ -7,12 +7,12 @@ A *dot* is the shortest period over which the PPU can output one pixel: is it eq ### FF41 - STAT (LCD Status) (R/W) ``` -Bit 6 - LYC=LY Interrupt (1=Enable) (Read/Write) -Bit 5 - Mode 2 OAM Interrupt (1=Enable) (Read/Write) -Bit 4 - Mode 1 VBlank Interrupt (1=Enable) (Read/Write) -Bit 3 - Mode 0 HBlank Interrupt (1=Enable) (Read/Write) -Bit 2 - LYC=LY Flag (0=Different, 1=Equal) (Read Only) -Bit 1-0 - Mode Flag (Mode 0-3, see below) (Read Only) +Bit 6 - LYC=LY STAT Interrupt (1=Enable) (Read/Write) +Bit 5 - Mode 2 OAM STAT Interrupt (1=Enable) (Read/Write) +Bit 4 - Mode 1 VBlank STAT Interrupt (1=Enable) (Read/Write) +Bit 3 - Mode 0 HBlank STAT Interrupt (1=Enable) (Read/Write) +Bit 2 - LYC=LY Flag (0=Different, 1=Equal) (Read Only) +Bit 1-0 - Mode Flag (Mode 0-3, see below) (Read Only) 0: In HBlank 1: In VBlank 2: Searching OAM From 913b3451c6b4eff7d61bfac063cafd2d24ebdc42 Mon Sep 17 00:00:00 2001 From: bbbbbr Date: Fri, 30 Apr 2021 12:14:31 -0700 Subject: [PATCH 2/3] Additional STAT Register / STAT Interrupt improvements --- content/Video_Display.md | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/content/Video_Display.md b/content/Video_Display.md index c7dc159a..778c623b 100644 --- a/content/Video_Display.md +++ b/content/Video_Display.md @@ -7,12 +7,12 @@ A *dot* is the shortest period over which the PPU can output one pixel: is it eq ### FF41 - STAT (LCD Status) (R/W) ``` -Bit 6 - LYC=LY STAT Interrupt (1=Enable) (Read/Write) -Bit 5 - Mode 2 OAM STAT Interrupt (1=Enable) (Read/Write) -Bit 4 - Mode 1 VBlank STAT Interrupt (1=Enable) (Read/Write) -Bit 3 - Mode 0 HBlank STAT Interrupt (1=Enable) (Read/Write) -Bit 2 - LYC=LY Flag (0=Different, 1=Equal) (Read Only) -Bit 1-0 - Mode Flag (Mode 0-3, see below) (Read Only) +Bit 6 - LYC=LY STAT Interrupt source (1=Enable) (Read/Write) +Bit 5 - Mode 2 OAM STAT Interrupt source (1=Enable) (Read/Write) +Bit 4 - Mode 1 VBlank STAT Interrupt source (1=Enable) (Read/Write) +Bit 3 - Mode 0 HBlank STAT Interrupt source (1=Enable) (Read/Write) +Bit 2 - LYC=LY Flag (0=Different, 1=Equal) (Read Only) +Bit 1-0 - Mode Flag (Mode 0-3, see below) (Read Only) 0: In HBlank 1: In VBlank 2: Searching OAM @@ -92,11 +92,12 @@ milliseconds. ### INT 48 - STAT Interrupt -There are various reasons for this interrupt to occur as described by -the STAT register (\$FF41). One very popular reason is to indicate to -the user when the video hardware is about to redraw a given LCD line. -This can be useful for dynamically controlling the SCX/SCY registers -($FF43/$FF42) to perform special video effects. +There are various sources which can trigger this interrupt to occur as +described by the [STAT register (\$FF41)](#ff41-stat-lcd-status-r-w). +One very popular use is to indicate to the user when the video +hardware is about to redraw a given LCD line. This can be useful for +dynamically controlling the SCX/SCY registers ($FF43/$FF42) to [perform +special video effects](https://github.com/BlitterObjectBob/DeadCScroll). Example application: set LYC to WY, enable LY=LYC interrupt, and have the handler disable sprites. This can be used if you use the window for @@ -106,10 +107,10 @@ hidden by the text box. ::: warning As mentioned in the description of the STAT register, the PPU cycles through the different modes in a fixed order. If we set the STAT bits -in a way that they would interrupt the CPU at two -consecutive modes, then the second interrupt will not trigger. So for example, -if we enable the interrupts for Mode 0 and Mode 1, -the Mode 1 interrupt will not trigger. +in a way that they would interrupt the CPU at two consecutive modes, +then the second interrupt will not trigger. So for example, if we +enable the interrupts for Mode 0 and Mode 1, the Mode 1 interrupt will +not trigger. This phenomenon is known as "STAT blocking". ::: # LCD Position and Scrolling From ad5fcd96d5527683d8f8acfb30d5be31a4a8b431 Mon Sep 17 00:00:00 2001 From: bbbbbr Date: Sun, 2 May 2021 10:45:17 -0700 Subject: [PATCH 3/3] Update STAT blocking description --- content/Video_Display.md | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/content/Video_Display.md b/content/Video_Display.md index 778c623b..0e55d4fa 100644 --- a/content/Video_Display.md +++ b/content/Video_Display.md @@ -104,13 +104,24 @@ the handler disable sprites. This can be used if you use the window for a text box (at the bottom of the screen), and you want sprites to be hidden by the text box. +The various STAT interrupt sources (modes 0-2 and LYC=LY) have their +state (inactive/low and active/high) logically ORed into a shared +STAT interrupt line if their respective enable bit is turned on. + +A STAT interrupt will be triggered by a rising edge (transition from +low-to-high) on the STAT interrupt line. + ::: warning -As mentioned in the description of the STAT register, the PPU cycles -through the different modes in a fixed order. If we set the STAT bits -in a way that they would interrupt the CPU at two consecutive modes, -then the second interrupt will not trigger. So for example, if we -enable the interrupts for Mode 0 and Mode 1, the Mode 1 interrupt will -not trigger. This phenomenon is known as "STAT blocking". +If a STAT interrupt source logically ORs the interrupt line high while +(or immediately after) it's already set high by another source, then +there will be no low-to-high transition and so no interrupt will occur. +This phenomenon is known as "STAT blocking" ([test ROM example](https://github.com/Gekkio/mooneye-gb/blob/2d52008228557f9e713545e702d5b7aa233d09bb/tests/acceptance/ppu/stat_irq_blocking.s#L21-L22)). + +As mentioned in the description of the [STAT register](#ff41-stat-lcd-status-r-w), +the PPU cycles through the different modes in a fixed order. So for +example, if interrupts are enabled for two consecutive modes such as +Mode 0 and Mode 1, then no interrupt will trigger for Mode 1 (since +the STAT interrupt line won't have a chance to go low between them). ::: # LCD Position and Scrolling