GP1 Display Control Commands: Difference between revisions
| Revision as of 02:32, 23 October 2026 RemmyLee (CLAUDE.md, CONTEXT.md: the gate skips doc-slop's length and lede rules) | Revision as of 02:43, 23 October 2026 RemmyLee (GPU at register depth: GP0, GP1, GPUSTAT, VRAM, rendering, T-cache, video timing) | ||
| Line 1: | Line 1: | ||
| + | --- | ||
| + | title: GP1 Display Control Commands | ||
| + | type: register | ||
| + | summary: Reset, display and DMA commands written to the GP1 port of the GPU. | ||
| + | category: Hardware | ||
| + | category: GPU | ||
| + | --- | ||
| + | |||
| + | ## Summary | ||
| + | |||
| + | GP1 is the control port of the [GPU](/hardware/gpu/) at 0x1F801814. A write to GP1 sends a display control command, and a read returns the status register ([GPUSTAT](/hardware/gpu/gpustat/)).[^spx-io] Each command is one word with the 8-bit command number in the upper bits and a 24-bit parameter in the lower bits. Unlike GP0 commands, GP1 commands go directly to the GPU and do not pass through the command FIFO, so they can be sent even while the FIFO is full.[^spx-gp1] | ||
| + | |||
| + | Table: GP1 commands | ||
| + | |||
| + | | Command | Purpose | DISPENV member | | ||
| + | | --- | --- | --- | | ||
| + | | GP1(00h) | Reset GPU | | | ||
| + | | GP1(01h) | Reset command buffer | | | ||
| + | | GP1(02h) | Acknowledge GPU interrupt (IRQ1) | | | ||
| + | | GP1(03h) | Display enable | | | ||
| + | | GP1(04h) | DMA direction and data request | | | ||
| + | | GP1(05h) | Start of display area in VRAM | disp | | ||
| + | | GP1(06h) | Horizontal display range on screen | screen | | ||
| + | | GP1(07h) | Vertical display range on screen | screen | | ||
| + | | GP1(08h) | Display mode | disp, isinter, isrgb24 | | ||
| + | | GP1(09h) | Set VRAM size (v2 GPU) | | | ||
| + | | GP1(10h) | Read GPU internal register | | | ||
| + | | GP1(20h) | Set VRAM size (v1 GPU) | | | ||
| + | |||
| + | GP1(0Ah), GP1(0Ch) to GP1(0Fh) and GP1(21h) to GP1(3Fh) are not used, and GP1(40h) to GP1(FFh) mirror GP1(00h) to GP1(3Fh).[^spx-na] | ||
| + | |||
| + | In libgpu the display state is the DISPENV structure, whose members correspond to the commands as shown in the table. Its members are the display area in the frame buffer (disp), the position on the screen (screen), the interlace flag (isinter) and the 24-bit mode flag (isrgb24).[^lo86] PutDispEnv() makes a DISPENV the current display environment. Unlike a drawing environment, its settings take effect at once, so the display position can be changed while drawing continues in the background.[^lo86][^lo87] | ||
| + | |||
| + | ## GP1(00h) - Reset GPU | ||
| + | |||
| + | GP1(00h) resets the GPU. Its parameter bits are not used and should be 0. The reset has the effect of the following commands:[^spx-reset] | ||
| + | |||
| + | Table: GP1(00h) reset values | ||
| + | |||
| + | | Command | Value after reset | | ||
| + | | --- | --- | | ||
| + | | GP1(01h) | Command FIFO cleared | | ||
| + | | GP1(02h) | Interrupt acknowledged | | ||
| + | | GP1(03h) | Display off | | ||
| + | | GP1(04h) | DMA off | | ||
| + | | GP1(05h) | Display address 0 | | ||
| + | | GP1(06h) | X1 = 200h, X2 = 200h + 256 x 10 | | ||
| + | | GP1(07h) | Y1 = 010h, Y2 = 010h + 240 | | ||
| + | | GP1(08h) | Display mode 0 | | ||
| + | | GP0(E1h) to GP0(E6h) | Drawing attributes 0 | | ||
| + | |||
| + | After the reset GPUSTAT reads 14802000h. GP1(09h) is not affected by the reset. The X1 and Y1 values place the upper left edge of the picture off the visible screen.[^spx-reset] | ||
| + | |||
| + | Libgpu resets the graphics system with ResetGraph(), which takes a reset level. Every level stops the drawing command in progress, cancels the requests in the queue and enters wait status, and the levels differ in what they preserve:[^lo817] | ||
| + | |||
| + | Table: Reset levels | ||
| + | |||
| + | | Reset Level | Callback | DISPENV | DRAWENV | command queue | | ||
| + | | --- | --- | --- | --- | --- | | ||
| + | | 0 | Initialize | Initialize | Initialize | Initialize | | ||
| + | | 1 | Save | Save | Save | Initialize | | ||
| + | | 3 | Initialize | Save | Save | Initialize | | ||
| + | |||
| + | Level 0 is a complete reset, executed once when the program starts; it initializes the display to 256 x 240 and masks the display. Level 1 cancels drawing only and is used when switching the double buffer. Level 3 is a complete reset that keeps the display and drawing environments and leaves the display unmasked. Consequently, a child process started with Exec() should begin with ResetGraph(3), because a level 0 reset would disturb the screen set up by the parent.[^lo817] | ||
| + | |||
| + | ## GP1(01h) - Reset Command Buffer | ||
| + | |||
| + | GP1(01h) clears the command FIFO and the CLUT cache. The parameter bits are not used.[^spx-01] | ||
| + | |||
| + | ## GP1(02h) - Acknowledge GPU Interrupt | ||
| + | |||
| + | GP1(02h) clears the interrupt flag in bit 24 of GPUSTAT. GP0(1Fh) sets the flag.[^spx-02] | ||
| + | |||
| + | ## GP1(03h) - Display Enable | ||
| + | |||
| + | GP1(03h) turns the display on or off. Bit 0 is DMSK (0 = on, 1 = off), shown in bit 23 of GPUSTAT; bits 1 to 23 are not used. With the display off the GPU outputs a black picture and still sends sync signals to the television.[^spx-03] | ||
| + | |||
| + | ## GP1(04h) - DMA Direction | ||
| + | |||
| + | GP1(04h) selects when the GPU requests DMA. Bits 0 to 1 are the DMA direction. GPUSTAT shows the setting in bits 29 to 30:[^spx-04] | ||
| + | |||
| + | Table: GP1(04h) DMA direction | ||
| + | |||
| + | | Value | Name | DMA request | | ||
| + | | --- | --- | --- | | ||
| + | | 0 | Off | No request | | ||
| + | | 1 | WFNF | While the GP0 write FIFO is not full | | ||
| + | | 2 | WFEP | While the GP0 write FIFO is empty (CPU to GPU) | | ||
| + | | 3 | RFFL | While the GP0 read FIFO is full (GPU to CPU) | | ||
| + | |||
| + | The direction must be set before DMA channel 2 is used. Transfers by software without DMA are possible with any setting, but the setting changes the meaning of GPUSTAT bit 25.[^spx-04][^spx-dma] | ||
| + | |||
| + | ## GP1(05h) - Start of Display Area | ||
| + | |||
| + | GP1(05h) sets the upper left corner of the display area in VRAM. Bits 0 to 9 are the X coordinate in halfwords (0 to 1023), bits 10 to 18 the Y coordinate in lines (0 to 511), and bits 19 to 23 are not used.[^spx-05] | ||
| + | |||
| + | In libgpu this is (disp.x, disp.y) of DISPENV. For a double buffer at (0, 0)-(320, 240) and (0, 240)-(320, 480), the display area origin alternates between (0, 240) and (0, 0) while the drawing area uses the other buffer.[^lo87] | ||
| + | |||
| + | ## GP1(06h) - Horizontal Display Range | ||
| + | |||
| + | GP1(06h) sets where each line of the picture starts and ends on the screen. Both values are 12 bits and count video clock cycles from the horizontal sync:[^spx-06] | ||
| + | |||
| + | Table: GP1(06h) fields | ||
| + | |||
| + | | Bits | Content | Typical value | | ||
| + | | --- | --- | --- | | ||
| + | | 0 to 11 | X1, start of the picture | 260h | | ||
| + | | 12 to 23 | X2, end of the picture | 260h + 320 x 8 | | ||
| + | |||
| + | The number of pixels per line is (((X2 - X1) / cycles per pixel) + 2) AND NOT 3. The hardware therefore rounds the width to a multiple of 4 pixels, and for resolutions other than 320 the values may need adjusting to match exactly. The video clock is that of the console region and does not change with the mode that GP1(08h) selects.[^spx-06] psx-spx gives the following X1 and X2 for a full-width picture in official games:[^spx-06] | ||
| + | |||
| + | Table: Horizontal display ranges | ||
| + | |||
| + | | Width | X1 | X2 | Range | | ||
| + | | --- | --- | --- | --- | | ||
| + | | NTSC 256 | 590 | 3150 | 2560 | | ||
| + | | NTSC 320 | 600 | 3160 | 2560 | | ||
| + | | NTSC 368 | 539 | 3227 | 2688 | | ||
| + | | NTSC 512 | 615 | 3175 | 2560 | | ||
| + | | NTSC 640 | 620 | 3180 | 2560 | | ||
| + | | PAL 256 | 610 | 3170 | 2560 | | ||
| + | | PAL 320 | 624 | 3184 | 2560 | | ||
| + | | PAL 368 | 560 | 3248 | 2688 | | ||
| + | | PAL 512 | 635 | 3195 | 2560 | | ||
| + | | PAL 640 | 640 | 3200 | 2560 | | ||
| + | |||
| + | The screen size does not change the size of a pixel. The GPU sends more or fewer pixels to the screen, and many sets show only part of an enlarged picture.[^spx-dse] Sony expresses the same idea in the screen member of DISPENV, whose standard coordinates are (0, 0) to (256, 240). A smaller screen area is an underscan and a larger one an overscan, and the pixel size stays the same.[^lo86] | ||
| + | |||
| + | ## GP1(07h) - Vertical Display Range | ||
| + | |||
| + | GP1(07h) sets the first and last scanline of the picture. Both values count scanlines from the vertical sync:[^spx-07] | ||
| + | |||
| + | Table: GP1(07h) fields | ||
| + | |||
| + | | Bits | Content | NTSC | PAL | | ||
| + | | --- | --- | --- | --- | | ||
| + | | 0 to 9 | Y1, first line | 88h - 240/2 | A3h - 288/2 | | ||
| + | | 10 to 19 | Y2, last line | 88h + 240/2 | A3h + 288/2 | | ||
| + | | 20 to 23 | Not used | | | | ||
| + | |||
| + | The number of lines is Y2 - Y1, and no rounding is applied. If Y2 is much too large, the GPU stops generating vertical blank interrupts (IRQ0). On most television sets only 224 of 240 NTSC lines are visible, and many PAL games show only 256 lines.[^spx-07] psx-spx notes that most NTSC games use X1 = 260h and Y1, Y2 centered on 88h, while PAL games use many different values, and some games change these values to shake the screen.[^spx-07][^spx-pal] | ||
| + | |||
| + | For PAL output Sony moves the 240-line NTSC picture down by changing the screen member of DISPENV: screen.y = 8 (that is, (256 - 240)/2) and screen.h = 240, with x and w unchanged.[^lo840] | ||
| + | |||
| + | ## GP1(08h) - Display Mode | ||
| + | |||
| + | GP1(08h) sets the resolution, video standard, color depth and interlace of the display. Its fields are as follows:[^spx-08] | ||
| + | |||
| + | Table: GP1(08h) fields | ||
| + | |||
| + | | Bits | Name | Content | GPUSTAT bit | | ||
| + | | --- | --- | --- | --- | | ||
| + | | 0 to 1 | HDS | Horizontal resolution 1 (0 = 256, 1 = 320, 2 = 512, 3 = 640) | 17 to 18 | | ||
| + | | 2 | VDS | Vertical resolution (0 = 240, 1 = 480 when bit 5 is set) | 19 | | ||
| + | | 3 | NPB | Video mode (0 = NTSC 60Hz, 1 = PAL 50Hz) | 20 | | ||
| + | | 4 | LBS | Display area color depth (0 = 15-bit, 1 = 24-bit) | 21 | | ||
| + | | 5 | IRS | Vertical interlace (0 = off, 1 = on) | 22 | | ||
| + | | 6 | HDS2 | Horizontal resolution 2 (0 = per bits 0 to 1, 1 = 368) | 16 | | ||
| + | | 7 | | Flip screen horizontally (v1 GPU only) | 14 | | ||
| + | | 8 to 23 | | Not used | | | ||
| + | |||
| + | Interlace must be on for all lines to be seen in 480-line mode. The color depth bit affects only the display, because the drawing commands always draw in 15-bit color. The interlace bit, however, also affects drawing.[^spx-08] Bit 7 is the "reverse" setting of older Sony libraries and works only on the v1 arcade GPU.[^spx-08] | ||
| + | |||
| + | The [GPU](/hardware/gpu/) page lists the screen modes that Sony documents. In DISPENV the width disp.w can be 256, 320, 360, 512 or 640 and the height disp.h 240 or 480; with a height of 480 the display is interlaced whatever the isinter flag says.[^lo86] Libgpu selects PAL with SetVideoMode(MODE_PAL), and on the DTL-H2000 the DIP switch must also be set.[^lo840] | ||
| + | |||
| + | ## GP1(09h) - Set VRAM Size | ||
| + | |||
| + | GP1(09h) exists only on the v2 GPU. Bit 0 allows Y coordinates from 512 to 1023 (0 = no, wrap to 0 to 511; 1 = yes). On a retail console only the first VRAM chip select is used, so enabling this mode makes textures disappear if GP0(E1h) bit 11 is also set. The v1 GPU uses GP1(20h) instead, whose parameter values are uncertain.[^spx-09] | ||
| + | |||
| + | ## GP1(10h) - Read GPU Internal Register | ||
| + | |||
| + | GP1(10h) latches an internal register in the GP0 read port, where the CPU can read it at once. Bits 0 to 23 select the register; GP1(11h) to GP1(1Fh) are mirrors. Unlike a VRAM read, a register read does not use GPUSTAT bit 27, so the CPU must not wait for that bit. The latched value stays until another read is requested, and it is not updated when the register changes.[^spx-10] | ||
| + | |||
| + | Table: GP1(10h) registers | ||
| + | |||
| + | | Index | v0 GPU | v2 GPU | | ||
| + | | --- | --- | --- | | ||
| + | | 00h to 01h | Nothing (old value remains) | Nothing (old value remains) | | ||
| + | | 02h | Texture window, GP0(E2h), 20 bits | Texture window, GP0(E2h), 20 bits | | ||
| + | | 03h | Drawing area top left, GP0(E3h), 19 bits | Drawing area top left, GP0(E3h), 20 bits | | ||
| + | | 04h | Drawing area bottom right, GP0(E4h), 19 bits | Drawing area bottom right, GP0(E4h), 20 bits | | ||
| + | | 05h | Drawing offset, GP0(E5h), 22 bits | Drawing offset, GP0(E5h), 22 bits | | ||
| + | | 06h | Nothing | Nothing | | ||
| + | | 07h | Nothing | GPU version (2) | | ||
| + | | 08h | Mirror of 00h | 00000000h | | ||
| + | |||
| + | The version index gives a way to detect the GPU type. psx-spx shows a detection routine from Perfect Assassin: it latches index 4 and then index 7, and a result of 2 identifies a v2 GPU. Otherwise it writes GP0(E1h) with bit 12 set and reads GPUSTAT bit 12 to tell the v1 GPU from the v0.[^spx-det] | ||
| + | |||
| + | ## References | ||
| + | |||
| + | [^spx-io]: psx-spx. Graphics Processing Unit (GPU), GPU I/O Ports, DMA Channels, Commands, VRAM. https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-io-ports-dma-channels-commands-vram | ||
| + | [^spx-dma]: psx-spx. Graphics Processing Unit (GPU), GPU-related DMA Channels (DMA2 and DMA6). https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-io-ports-dma-channels-commands-vram | ||
| + | [^spx-gp1]: psx-spx. Graphics Processing Unit (GPU), GPU Display Control Commands (GP1). https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-display-control-commands-gp1 | ||
| + | [^spx-reset]: psx-spx. Graphics Processing Unit (GPU), GP1(00h) - Reset GPU. https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-display-control-commands-gp1 | ||
| + | [^spx-01]: psx-spx. Graphics Processing Unit (GPU), GP1(01h) - Reset Command Buffer. https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-display-control-commands-gp1 | ||
| + | [^spx-02]: psx-spx. Graphics Processing Unit (GPU), GP1(02h) - Acknowledge GPU Interrupt (IRQ1). https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-display-control-commands-gp1 | ||
| + | [^spx-03]: psx-spx. Graphics Processing Unit (GPU), GP1(03h) - Display Enable. https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-display-control-commands-gp1 | ||
| + | [^spx-04]: psx-spx. Graphics Processing Unit (GPU), GP1(04h) - DMA Direction / Data Request. https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-display-control-commands-gp1 | ||
| + | [^spx-dse]: psx-spx. Graphics Processing Unit (GPU), Display start/end. https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-display-control-commands-gp1 | ||
| + | [^spx-05]: psx-spx. Graphics Processing Unit (GPU), GP1(05h) - Start of Display area (in VRAM). https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-display-control-commands-gp1 | ||
| + | [^spx-06]: psx-spx. Graphics Processing Unit (GPU), GP1(06h) - Horizontal Display range (on Screen). https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-display-control-commands-gp1 | ||
| + | [^spx-07]: psx-spx. Graphics Processing Unit (GPU), GP1(07h) - Vertical Display range (on Screen). https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-display-control-commands-gp1 | ||
| + | [^spx-pal]: psx-spx. Graphics Processing Unit (GPU), Mis-Centered PAL Games (wrong GP1(06h)/GP1(07h) settings). https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-display-control-commands-gp1 | ||
| + | [^spx-08]: psx-spx. Graphics Processing Unit (GPU), GP1(08h) - Display mode. https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-display-control-commands-gp1 | ||
| + | [^spx-09]: psx-spx. Graphics Processing Unit (GPU), GP1(09h) - Set VRAM size (v2) and GP1(20h) - Set VRAM size (v1). https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-display-control-commands-gp1 | ||
| + | [^spx-10]: psx-spx. Graphics Processing Unit (GPU), GP1(10h) - Read GPU internal register. https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-display-control-commands-gp1 | ||
| + | [^spx-na]: psx-spx. Graphics Processing Unit (GPU), GP1(0Ah,0Ch..0Fh,21h..3Fh) - N/A and GP1(40h..FFh) - N/A (Mirrors). https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-display-control-commands-gp1 | ||
| + | [^spx-det]: psx-spx. Graphics Processing Unit (GPU), GPU Detection (and optional VRAM size switching). https://psx-spx.consoledev.net/graphicsprocessingunitgpu/#gpu-versions | ||
| + | [^lo86]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 8-6. | ||
| + | [^lo87]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 8-7, Table 8-2. | ||
| + | [^lo817]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 8-17, Table 8-8. | ||
| + | [^lo840]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 8-40, Figure 8-24. | ||