Difference between revisions of "HuC6270"

From Archaic Pixels
Jump to: navigation, search
Line 1: Line 1:
 
{{:Styled Table}}
 
{{:Styled Table}}
<css> .styled_table_min { text-align: center; } </css>
+
[[Image:HuC6260.jpg | thumbnail | upright=2.5 | The HuC6260]]
  
[[Image:HuC6270.jpg | thumbnail | upright=2.5 | The HuC6270]]
+
VCE. Referred to as 鉄観音 - "TETSU" by NEC-HE.
  
Video Display controller (VDC). Referred to as "7UP" by NEC-HE.
+
The HuC6260 Video Color Encoder basically supplies the picture on your television.
  
[b]Notes:[/b]
+
It is connected to the VDC and coordinates the palette processing as its most important job.
* all mentions of "dot" have been replaced with "pixel" (DCC is now PCC)
+
* all registers accept 16 bit values.
+
* read and write operations for the same address do not always access the same memory.
+
  
= Specifications =
+
= Notes =
  
* 64 simultaneous sprites
+
* all mentions of "dot" have been replaced with "pixel" (PCC is now PCC)
* 64KB of VRAM
+
* all registers are 16 bit.
* a background and foreground layer
+
  
= Interface =
+
= Registers =
[code]
+
    Address  | Access | Description
+
    (Mapped  |  mode  |
+
    to $FF)  |        |
+
--------------+--------+---------------------------------------------------
+
      $0000  |  R    | 6270 Status register
+
              |        |
+
              |        |  Different bits flag different conditions.
+
              |        |  Not all are known.
+
              |        |  (Note: can use special ST0 opcode to store
+
              |        |  an immediate value.)
+
              |        |    b 7 = 0
+
              |        |    b 6 = 'BSY' flag
+
              |        |        I believe this is '1' when a DMA transfer
+
              |        |        is happening
+
              |        |    b 5 = 'VD' flag
+
              |        |        I believe this is a '1' when Vertical Sync
+
              |        |        happens, otherwise a '0' (uncertain)
+
              |        |    b 4 = 'DV' flag (unknown)
+
              |        |    b 3 = 'DS' flag (unknown)
+
              |        |    b 2 = 'RR' flag
+
              |        |        Set during a Scanline interrupt (see RCR
+
              |        |        register)otherwise '0'
+
              |        |    b 1 = 'OR' flag (unknown)
+
              |        |    b 0 = 'CR' flag (unknown)
+
              |        |
+
      $0000  |  W    | 6270 Address register
+
              |        |
+
              |        |    b 7-5 = ignored
+
              |        |    b 4-0 = 6270 register number to access using
+
              |        |            the 6270 data registers
+
              |        |            ($0002 and $0003). Please see 6270
+
              |        |            register list (SECTION 4) for details.
+
              |        |
+
      $0002  |  R/W  | 6270 data LSB
+
              |        |
+
              |        |  Note: can use special ST1 opcode to store
+
              |        |        an immediate value.)
+
              |        |
+
      $0003  |  R/W  | 6270 data MSB
+
              |        |
+
              |        |  Note: can use special ST2 opcode to store
+
              |        |        an immediate value.)
+
--------------+--------+---------------------------------------------------
+
[/code]
+
  
== Status Register ==
+
== $0400 - CR - Control Register ==
          A bit corresponding to one of interruption jobs is set to be "H" in the status register
+
          to make the interruption active when a cause of the interruption which is enabled by an
+
          interruption permission bit of a control register and DMA control register as showing in
+
          Figures 3G and 3Q is occurred.  When the status is read from the status register, the
+
          corresponding bit is cleared automatically.
+
  
          The status indicating bits are as follows.
+
Write only register.
  
=== Read Behavior ===
 
 
{| class="styled_table"
 
{| class="styled_table"
 
|-
 
|-
! Bit(s) !! Name !! Description !! Details
+
! Bit(s) || Description || Values
 
|-
 
|-
| 0 || CR || sprite collision || Sprite #0 has collided with another sprite (1 to 63).
+
| 0 - 1 || PCC - Pixel Clock Control ||
 +
0 = 5.37 MHz[br]
 +
1 = 7.16 MHz[br]
 +
2 = 10.7 MHz[br]
 +
3 = 10.7 MHz
 
|-
 
|-
| 1 || OR || sprite overflow ||
+
| 2 || Frame/Field Configuration ||
* More than 17 sprites are detected on a single raster line.
+
00 = 262-line frame[br]
* Data of a sprites which is designated are not transferred to a data buffer in a horizontal trance period.
+
01 = 263-line frame
* A bit of CGX in control data of a sprite by which two sprites are joined in a horizontal direction is set so that data of the sprites are not transferred to a data buffer.
+
 
|-
 
|-
| 2 || PR || scanline interrupt || A value of a raster counter becomes a predetermined value of a raster detecting register.
+
| 3 - 6 || ??? || ???
 
|-
 
|-
| 3 || DS || VRAM to SATB end of transfer. || Data transfer between the VRAM and sprite attribute table buffer is finished.
+
| 7 || Strip Colorburst ||
 +
0 = Colorburst intact[br]
 +
1 = Strip colorburst
 
|-
 
|-
| 4 || DV || VRAM DMA end of transfer || Data transfer between two regions of VRAM has finished.
+
| 8 - 15 || ??? || ???
|-
+
| 5 || VD || vertical blanking || The VRAM accessed for the writing or reading of data by the CPU so that the BUSY terminals is "0".
+
|-
+
| 6 || BSY || DMA busy || A DMA transfer is in progress.
+
|-
+
| 7 - 15 || || (unused) ||
+
 
|}
 
|}
  
=== Write Behavior ===
+
== $0402 - CTA - Color Table Address Register ==
{| class="styled_table"
+
|-
+
! Bit(s) !! Description
+
|-
+
| 0 - 4 || VDC register index (0-19)
+
|-
+
| 5 - 15 || (unused)
+
|}
+
  
== Address Register ==
+
Write only register.
          A register number "AR" is exclusive written into the address register designating one of
+
          the memory address write register to DMA VRAM-SATB source address register as shown in
+
          Figures 3C to 3U so that data are writing into the video display controller(1) under the
+
          condition that the A1 and CS terminals thereof are "L".
+
 
+
          In a case where 16 bit data bus is selected, the EX 8/[o]16[/o] terminal is "0", the A1
+
          terminal is "0", the "R/W" terminal is "W", and the A0 terminal is no matter.
+
 
+
          In a case where 8 bit data bus is selected, the EX 8/[o]16[/o] terminal is "1", the A0
+
          and A1 terminals are "0", and the "R/W" terminal is "W".
+
 
+
== Data Register ==
+
 
+
Read/Write register.
+
 
+
Data in the VDC register selected/indexed by the Status Register.
+
 
+
= VRAM Registers =
+
== $00 - MAWR - Memory Address Write Register (VRAM Write Address) ==
+
 
+
          A starting address "MAWR" is written into the memory address write register so that the
+
          writing of data begins at the starting address of the VRAM(7).
+
 
+
MAWR specifies a word offset into VRAM for writing. Subsequent writes to register $02 (VWR) will store data at the offset specified by MAWR. After each write, MAWR is incremented by the amount specified in the IW bits of CR. MAWR wraps back to zero when it's value exceeds $FFFF.
+
 
+
The LSB and MSB of MAWR can be updated independently of each other; accessing either half directly updates the MAWR register rather than any temporary storage. This allows quick non-sequential addressing of VRAM without having to set the entire address every time.
+
 
+
== $01 - MARR - Memory Address Read Register (VRAM Read Address) ==
+
 
+
          A starting address "MARR" is written into the memory address read register.  When the
+
          upper byte of the starting address is written thereinto, data are begun to be read from
+
          the starting address of the VRAM(7) so that data thus read are written into a VRAM data
+
          read register as showing in Figure 3F.  There after, the starting address "MARR" is
+
          automatically incremented by one.
+
 
+
MARR specifies a word offset into VRAM for reading. When the MSB is written, VRAM data from the current offset is transferred into a read buffer, and then MARR is incremented by the amount specified in the IW bits of CR. For any following VRR reads, the buffered value is immediately returned and this process repeats; the buffer is loaded from data at the current offset and MARR is incremented again.
+
 
+
The LSB of MARR can be updated independently of the MSB. This does not cause the buffer to be loaded, only a write to the MSB will do that.
+
 
+
== $02 - VRR - VRAM Data Read Register ==
+
 
+
          A starting address "MARR" is written into the memory address read register. When the
+
          upper byte of the starting address is written thereinto, data are begun to be read from
+
          the starting address of the VRAM(7) so that data thus read are written into a VRAM data
+
          read register as showing in Figure 3F.  There after, the starting address "MARR" is
+
          automatically incremented by one.
+
 
+
Reading the LSB of VRR returns the LSB of the read buffer. Reading the MSB returns the MSB of the read buffer immediately, then loads the buffer with VRAM from the current offset MARR represents and increments MARR by the value specified by the IW bits of CR. To read only the MSB of multiple words, the MSB of VRR can be repeatedly read instead of reading both the LSB and MSB.
+
 
+
Note: when reading from VDC addresses $0002 or $0003 when VRR is not selected, the buffer will not be reloaded nor will MARR increment when the MSB is read. The buffer contents will always return the last-loaded value but never update.
+
 
+
== $02 - VWR - VRAM Data Write Register ==
+
 
+
          Data which are transferred from the CPU(2) to the VRAM(7) are written into the VRAM data
+
          write register.  When the upper byte of the data "VWR" is written thereinto, the video
+
          display controller(1) begins to write the data into the VRAM(7) and the address "MAWR" of
+
          the memory address write register is automatically incremented by one upon writing of the
+
          data.
+
 
+
When writing to VWR, the LSB is stored in a latch rather than VRAM. Any additional writes to the LSB only update the latch contents and do not affect VRAM. When the MSB is written to, the latched LSB and new MSB data are stored to VRAM at the current offset specified by MAWR. By loading the LSB with a given value and writing to the MSB repeatedly, you can fill VRAM with a constant LSB value and variable MSB value.
+
 
+
== $05 - CR - Control Register ==
+
  
 
{| class="styled_table"
 
{| class="styled_table"
 
|-
 
|-
! Bit(s) !! Description
+
! Bit(s) || Description || Values
 
|-
 
|-
| 0 - 3 || (IE) enable/[o]disable[/o] interrupt flags
+
| 0 - 8 || index for the color table || 0 to 511
 
|-
 
|-
| 0 || collision detection (between sprite #0 and any other sprites).
+
| 9 - 15 || (unused) ||  
|-
+
| 1 || sprite overflow, more than 16 sprites on a scanline.
+
|-
+
| 2 || scanline match flag.
+
|-
+
| 3 || vertical blanking.
+
|-
+
| 4 || (EX) [o]input[/o]/output hsync signal
+
|-
+
| 5 || (EX) [o]input[/o]/output vsync signal
+
|-
+
| 6 || (SB) sprites enable/[o]disable[/o] flag
+
|-
+
| 7 || (BB) background enable/[o]disable[/o] flag
+
|-
+
| 8 - 9 || (DR) selects DISP terminal (pin 27?) output
+
{| class="styled_table"
+
! 9 !! 8 !! Output !! DISP Content
+
|-
+
| 0 || 0 || DISP || output "H" during display
+
|-
+
| 0 || 1 || BURST || color burst inserting position is indicated by output "L"
+
|-
+
| 1 || 0 || INTHSYNC || internal horizontal synchronous signal
+
|-
+
| 1 || 1 || || not used
+
 
|}
 
|}
|-
 
| 10 || (DR) dynamic RAM refresh enable/[o]disable[/o] flag
 
Refresh address MA0-MA15 upon setting the flag in a case where a
 
  
VRAM pixel width (see [[HuC6270#.2409_-_MWR_-_Memory_Width_Register | register $09]]) is of 2 pixels or 4 pixels in a Memory Width Register ($09)
+
Note: This register is auto-incremented after each access to the color data register.
|-
+
| 11 - 12 || read/write address auto-increment
+
  
{| class="styled_table"
 
! 12 !! 11 !! Increment
 
|-
 
| 0 || 0 || 0x01
 
|-
 
| 0 || 1 || 0x20
 
|-
 
| 1 || 0 || 0x40
 
|-
 
| 1 || 1 || 0x80
 
|}
 
Affect by how much are incremented the address register $00 and $01.
 
|-
 
| 13 - 15 || (unused)
 
|}
 
  
== $06 - RCR - Raster Counter Register ==
+
== $0404 - CTW - Color Table Write Register / CTR - Color Table Read Register ==
 +
 
 +
Write/Read register.
  
          A raster number "RCR" at which an interruption job is performed is written into the
+
Access (read/write) to this register causes CTA register to increment.
          raster detecting register.  An interruption signal is produced when a value of a raster
+
          counter is equal to the raster number "RCR".  The raster counter is preset to be "64" at
+
          a preceding scanning raster line to a display starting raster line as described in more
+
          detail later, and is increased at each raster line by one.
+
  
 
{| class="styled_table"
 
{| class="styled_table"
 
|-
 
|-
! Bit(s) !! Description
+
! Bit(s) || Description
 
|-
 
|-
| 0 - 9 || The rcr bit controls the generation of a raster counter IRQ. The VDC generates an IRQ, when the scanline specified in the RCR register is displayed. You need to add 64 to the RCR register to get the correct scanline.
+
| 0 - 2 || Blue
 
|-
 
|-
| 10 - 15 || (unused)
+
| 3 - 5 || Red
|}
+
 
+
A raster number "RCR" at which an interruption job is performed is written into the raster detecting register.
+
An interruption signal is produced when a value of a raster counter is equal to the raster number "RCR".  The raster counter is preset to be "64" at a preceding scanning raster line to a display starting raster line as described in more detail later, and is increased at each raster line by one.
+
 
+
== $07 - BXR - Background X-Scroll Register ==
+
          The BGX scroll register is used for a horizontal scroll of background on a screen.  When
+
          a content "BXR" is rewritten therein, the content is effective in the following raster
+
          line.
+
 
+
The value written to BXR is latched on each scanline, preventing mid-scanline changes to BXR. Further changes to BXR will not change the display until the next scanline is displayed. When the VDC generates synchronization signals this duration is in units of VDC scanlines, and when the VDC inputs external synchronization signals this is in units of VCE scanlines.
+
 
+
For example if the VDC displays multiple VDC scanlines in one VCE scanline, the same BXR value applies to all VDC scanlines until the current VCE scanline ends.
+
 
+
== $08 - BYR - Background Y-Scroll Register ==
+
 
+
          The BGY scroll register is used for a vertical scroll of background on a screen.  When a
+
          content "BYR" is rewritten therein, the content is effective to be as "BYR+1" in the
+
          following raster line.
+
 
+
The value written to BYR is latched on each scanline, preventing mid-scanline changes to BYR. Further changes to BYR will not change the display until the next scanline is displayed. When the VDC generates synchronization signals this duration is in units of VDC scanlines, and when the VDC inputs external synchronization signals this is in units of VCE scanlines.
+
 
+
For example if the VDC displays multiple VDC scanlines in one VCE scanline, the same BYR value applies to all VDC scanlines until the current VCE scanline ends.
+
 
+
== $09 - MWR - Memory Width Register ==
+
 
+
=== Character cycles ===
+
The fundamental unit of time observed by the VDC is the duration of one pixel clock cycle. The pixel clock is output by the VCE and can be any of the following:
+
 
+
* 5.36 MHz - ~186 ns per pixel
+
* 7.16 MHz - ~140 ns per pixel
+
* 10.73 MHz - ~93 ns per pixel
+
 
+
The VDC accesses VRAM in groups called character cycles. Each character cycle can be split into eight slots, which have a duration of one pixel clock each. The actual VRAM read or write cycle spans one or more slots, selectable in units of 1, 2, or 4 slots each.
+
 
+
Here's a diagram showing the number of VRAM accesses that can be made in one character cycle depending on number of slots allocated to read or write cycle:
+
 
+
{| class="styled_table_min"
+
|-
+
! VRAM cycle width !! Slot 1 !! Slot 2 !! Slot 3 !! Slot 4 !! Slot 5 !! Slot 6 !! Slot 7 !! Slot 8
+
|-
+
! 1 slot
+
| 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8
+
 
|-
 
|-
! 2 slots
+
| 6 - 8 || Green
| colspan="2" | 1
+
| colspan="2" | 2
+
| colspan="2" | 3
+
| colspan="2" | 4
+
 
|-
 
|-
! 4 slots
+
| 9 - 15 || (unused)
| colspan="4" | 1
+
| colspan="4" | 2
+
 
|}
 
|}
  
Within the same period of time a character cycle spans, up to 8 accesses can be done when the VRAM access cycle width is 1 slot, 4 accesses can be done when cycle width is 2 slots, and only two access can be done when the cycle width is 4 slots.
+
= Notes =
 +
'''Display artifact'''[br]
 +
When bit 2 of $0400 is set, a flip-flop is toggled once per frame that offsets the entire frame by one pixel. I'll call this the pixel shift state. Depending on the last state of the flip-flop when bit 2 of $0400 is reset, the pixel shift state can be forced to zero or one. When enabled this completely eliminates the color fringe artifact that is apparent for PCC settings $00-$03.
  
The PCE uses 100ns SRAM chips as it's video RAM, so the only situation that is problematic is using a 1-cycle pixel width along with the 10.73 MHz pixel clock. In this case each cycle is ~93 ns which violates the minimum access time requirements of the SRAM. In practice this does not cause any problems, however it does mean operating the memory 7% faster than it's guaranteed to work. This can be remedied by using a pixel width mode with longer cycles.
+
The VCE applies a 1/2 pixel shift on every even or odd scanline. The selection of even or odd scanlines is inverted on every frame, and is further inverted by the pixel shift state, however in all but 2 settings this is unnoticable.
  
=== VRAM pixel width ===
+
In "C" pseudocode these work like so:
The VDC will make as many sequential character cycles as the screen is wide as specified in the HDW field plus two, regardless of any horizontal scroll setting. These occur back-to-back in realtime as the display is rendered (I think there is a 1 or 2 character pipeline before any pixels are actually output). For example if the screen is 32 characters wide, 34 character cycles occur.
+
  
Bits 1, 0 of MWR set the VRAM access cycle grouping, referred to as the 'VRAM pixel width'. Bit 7 sets the character generator read mode when only two of four bitplanes can be read, due to insufficient VRAM access cycles available.
+
[code]
 +
  //each frame
 +
  if(PCC & 4) pixelShiftState ^= 1;
 +
  //each scanline
 +
  halfPixelShiftState = (framecount & 1) ^ (scanline & 1) ^ (pixelShiftState & 1);
 +
[/code]
  
Bits 1-0&nbsp;: VRAM pixel width.
+
Here are the results of some tests I did when the screen is filled with alternating white and black pixels on even scanlines and black and white pixels on odd scanlines.
 
+
{| class="styled_table_min"
+
|-
+
! D1-D0 !! Slot 1 !! Slot 2 !! Slot 3 !! Slot 4 !! Slot 5 !! Slot 6 !! Slot 7 !! Slot 8
+
|-
+
! 00[sub]b[/sub]
+
| CPU || BAT || CPU ||  || CPU || CG0 || CPU || CG1
+
|-
+
! 01[sub]b[/sub]
+
| colspan="2" | BAT
+
| colspan="2" | CPU
+
| colspan="2" | CG0
+
| colspan="2" | CG1
+
|-
+
! 10[sub]b[/sub]
+
| colspan="2" | BAT
+
| colspan="2" | CPU
+
| colspan="2" | CG0
+
| colspan="2" | CG1
+
|-
+
! 11[sub]b[/sub]
+
| colspan="4" | BAT
+
| colspan="4" | CG0 / CG1
+
|}
+
 
+
* BAT is a read from the BAT region of VRAM. (word contains palette, character name)
+
* CPU is a CPU access, either read or write.
+
* CG0 is a read from the character generator region of VRAM. (word contains bitplane 0 and 1 bytes)
+
* CG1 is a read from the character generator region of VRAM. (word contains bitplane 2 and 3 bytes)
+
 
+
The first three modes function identically. The last mode only has enough spare time in each character cycle to read CG0 or CG1, but not both. Selection of either bitplane group is done by the character generator mode bit (CM), which is bit 7 of MWR. It specifies 0= CG0 or 1= CG1. Internally, the VDC assumes the missing bitplane data is forced to zero. This means that tiles displayed when CM=0 use colors 0,1,2,3, and tiles displayed when CM=1 use colors 0,4,8,C.
+
 
+
=== Sprite pixel width ===
+
During the horizontal blanking period, the VDC fetches character generator data for the sprites (up to 16) that passed y-evaluation and have their respective data buffered in the VDC's on-chip sprite storage. The bitplane data is loaded into shift registers and will be output serially during the next scanline.
+
 
+
The duration of the fetch period directly relates to how much horizontal blanking time is available, as defined by the HSW, HDS, HDW, and HDE registers. If the period is too short, the process is aborted. It seems the sprites that weren't loaded have their shift registers reset to zero, as previously loaded sprite data or garbage data is not shown (this needs more testing).
+
 
+
Much like background rendering, bits 3-2 of MWR set the character cycle allocation for sprites, referred to as the 'Sprite pixel width'.
+
 
+
Bits 3-2&nbsp;: Sprite pixel width.
+
 
+
{| class="styled_table_min"
+
|-
+
! D1-D0 !! Slot 1 !! Slot 2 !! Slot 3 !! Slot 4 !! Slot 5 !! Slot 6 !! Slot 7 !! Slot 8
+
|-
+
! 00[sub]b[/sub]
+
| SP0 || SP1 || SP2 || SP3 || SP0 || SP1 || SP2 || SP3
+
|-
+
! 01[sub]b[/sub]
+
| colspan="2" | SP0, SP2
+
| colspan="2" | SP1, SP3
+
| colspan="2" | SP0, SP2
+
| colspan="2" | SP1, SP3
+
|-
+
! 10[sub]b[/sub]
+
| colspan="2" | SP0
+
| colspan="2" | SP1
+
| colspan="2" | SP2
+
| colspan="2" | SP3
+
|-
+
! 11[sub]b[/sub]
+
| colspan="4" | SP0 / SP2
+
| colspan="4" | SP1 / SP3
+
|}
+
 
+
* SP0-3 are sprite bitplanes 0,1,2,3.
+
* 00b reads data for two sprites in one cycle.
+
* 01b reads data for two sprites in two cycles (bitplanes 0,1 for sprites 1,2 in cycle, bitplanes 2,3 for sprites 1,2 in the next).
+
* 10b reads data for one sprite in one cycle.
+
* 11b reads data for one sprite in one cycle, but only bitplanes 0,1 or 2,3 can be read.
+
 
+
Bit 0 of the pattern code field of each sprite entry specifies which bitplanes are read for a sprite pixel width setting of 11b. It can be 0= SP0,SP1 or 1= SP2,SP3. The unused bitplanes are forced to zero so that the colors used out of a 16-color palette are 0,1,2,3 when SP0,SP1 are read, or 0,4,8,C when SP2,SP3 are read.
+
 
+
= Display Registers =
+
 
+
== $0A - HPR - Horizontal Synchronous Register ==
+
          (1) bits 1 to 4 (HSW) - horizontal synchronous pulse
+
              A pulse width of "L" level of a horizontal synchronous pulse is set as an unit of a
+
              character cycle. One of 1 to 32 is selected by using 5 bits to comply with the
+
              specification of a CRT display.
+
 
+
          (2) bits 8 to 14 (HDS) - starting position of horizontal display
+
              A period between a rising edge of a character cycle.  An optimum position in a
+
              horizontal direction on a CRT display is decided by a content of the 7 bits.  When
+
              it is assumed that a horizontal display position (horizontal back porch) is "N",
+
              "N-1" is written into HDS bits.
+
Bits 4-0&nbsp;: Horizontal Sync Width (HSW)<br>
+
Bits 14-8&nbsp;: Horizontal Display Start (HDS)
+
 
+
HSW defines the width of the horizontal sync pulse in 8-pixel (character) units. The range is 1 to 32 characters.
+
 
+
HDS defines the interval after the horizontal sync pulse to the start of the horizontal display period in character units. The range is 1 to 128 characters.
+
 
+
 
+
When the VDC inputs external synchronization signals, the function of HSW changes. It no longer affects the width of the horizontal sync pulse. Instead, if during the processing of any VDC-generated scanline the HDE state expires prior to an external /HSYNC pulse, the number of characters as specified by HSW are taken up before the next VDC-generated scanline starts.
+
 
+
This distinction is important; increasing values of HSW do not displace the horizontal display area immediately following an external /HSYNC pulse, but they will for all subsequent VDC-generated scanlines before /HSYNC occurs again.
+
 
+
== $0B - HDR - Horizontal Display Register ==
+
          (1) bits 0 to 6 (HDW) - horizontal display width
+
              A display period in each raster line is set as an unit of a character cycle, and is
+
              decided in accordance with the number of characters in the horizontal direction on a
+
              CRT screen dependent on a content of the 7 bits.  If it is assumed that a horizontal
+
              display position is "N", "N-1" is written into HDW bits.
+
 
+
          (2) bits 8 to 11 (HDE) - horizontal display ending position
+
              A period between an ending of a horizontal display period and a rising edge of a
+
              horizontal synchronous signal is set as an unit of a character cycle.  An optimum
+
              position of a horizontal display is set on a CRT display by the 7 bits.  When it is
+
              assumed that a horizontal display ending position (horizontal back porch) is "N",
+
              "N-1" is written into HDE bits.
+
Bits 6-0&nbsp;: Horizontal Display Width (HDW)<br>
+
Bits 14-8&nbsp;: Horizontal Display End (HDE)
+
 
+
HDW defines the width of the horizontal active display period in character units. The range is 1 to 128 characters.
+
 
+
HDE defines the interval following HDE to the end of the scanline, at which poinst the HSW state is entered and a horizontal sync pulse is generated. The range is 1 to 128 characters. It should be set to the remainder from the desired number of characters per scanline, minus HSW, HDS, and HDW.
+
 
+
== $0C - VSR - Vertical Synchronous Register ==
+
          (1) bits 0 to 4 (VSW) - vertical synchronous pulse width
+
              A pulse width of a vertical synchronous signal is decided in a width of "L" level
+
              as a unit of a raster line.  One of 1 to 32 is selected to comply with a
+
              specification of a CRT display.
+
 
+
          (2) bits 8 to 15 (VDS) - vertical display starting position
+
              A period between a rising edge of a vertical synchronous signal and a vertical
+
              synchronous starting position is set as an unit of a raster line.  When it is assumed
+
              that a vertical display starting position (vertical back porch) is "N", "N-2" is
+
              written into the bits.
+
 
+
== $0D - VDR - Vertical Display Register ==
+
 
+
          A vertical display period (display region) is set as an unit of a raster line.  A
+
          vertical display width is decided in accordance with the number of raster lines to be
+
          displayed on a CRT display which is defined by a content of the 9 bits.  When it is
+
          assumed that a vertical display width is "N", "N-1" is written into the VDW bits.
+
 
+
== $0E - VCR - Vertical Display Ending Postition Register ==
+
          A period between a vertical display ending position and a rising edge of a vertical
+
          synchronous signal is set as an unit of a raster line.  When it is assumed that a
+
          vertical optimum position (vertical front porch) is "N" to be defined by the 8 bits,
+
          "N" is written into the VCR bits.
+
Bits 7-0&nbsp;: Vertical Display Position End (VCR)
+
 
+
VCR defines the interval following VDW to the end of the frame, at which point the VSW state is entered and a vertical sync pulse is generated. The range is 0 to 255 scanlines. It should be set to the remainder from the desired number of scanlines per frame, minus VSW, VDS, and VDW.
+
 
+
When the VDC inputs external synchronization signals, VCR should be set to a value equal to or larger than the number of scanlines the hardware generates from one edge of /VSYNC to the next. Otherwise the VDC will start generating another frame within the current display frame. This can be used to arbitrarily force additional VD interrupts and VRAM to SAT DMA transfers within a single VCE-defined frame.
+
 
+
= DMA Registers =
+
 
+
== $0F - DCR - DMA Control Register ==
+
 
+
          (1) bit 0 (DSC) - enable and interruption at the finishing of transfer between the
+
              VRAM(7) and sprite attribute table buffer (23)
+
              It is decided whether or not an interruption is enabled at the finishing time of
+
              the transfer.
+
              (1.1) "0" - disable
+
              (1.2) "1" - enabled
+
 
+
          (2) bit 1 (DVC) - enable of interruption at the finishing of transfer between two
+
              regions of the VRAM(7).
+
              It is decided whether or not an interruption is enabled finishing time of the
+
              transfer
+
              (2.1) "0" - disable
+
              (2.2) "1" - enabled
+
 
+
          (3) bit 2 (SI/D) - increment/decrement of a source address
+
              One of automatically increment and decrement of a source address is selected in a
+
              transfer between two regions of VRAM(7).
+
              (4.1) "0" - disable
+
              (4.2) "1" - enabled
+
 
+
          (5) bit 5 (DSR) - repetition of a transfer between the VRAM(7) and the sprite
+
              attribute table buffer(23) is enabled.
+
 
+
== $10 - SOUR - Source Address Register ==
+
 
+
          A starting address of a source address is allocated in a transfer between two regions
+
          of the VRAM(7).
+
 
+
== $11 - DESR - DMA Destination Address Register ==
+
 
+
          A starting address of a destination address is allocated in a transfer between two
+
          regions of the VRAM(7).
+
 
+
== $12 - LENR - DMA Block Length Register ==
+
          A length of a block is defined in a transfer between two regions of the VRAM(7).
+
 
+
== $13 - SATB - Sprite Attribute Table Address Register ==
+
 
+
The address of the Sprite Attribute Table.  This is the only address used for access to the SATB.
+
 
+
= VRAM Access =
+
Typically when loading large amounts of data into VRAM the screen is turned off for several frames. In most video hardware turning the screen off stops display related DMA and gives the CPU full access to VRAM.
+
 
+
The VDC handles things a bit differently. BURST mode is when the color bus outputs $0100 on VD8-VD0 (sprite palette #0, color #0), display DMA is stopped (no fetching of BAT data, background patterns, sprite patterns), and the CPU has unrestricted access to VRAM regardless of the MWR settings. BURST mode is enabled in two situations:
+
 
+
1. Any display state outside of VDW is considered to be in the BURST mode. A possible exception is that display DMA needs to be done on line 262 or 263 (depending on the frame height) for graphics to be displayed on scanline 0.
+
 
+
2. If bits 7 and 6 of CR are reset prior to VDW occurring, BURST mode is forcibly entered for the entire duration of VDW. Any changes to bits 7 and 6 have no effect until the next transition into VDW, at which point they are sampled again.
+
 
+
Note that this means simply turning off the background and/or sprites during VDW does *not* select BURST mode, and VRAM access is still restricted. When the background is turned off during the display, the color bus outputs $0000 on VD8-VD0 (background palette #0, color #0).
+
 
+
To maximize VRAM throughput, it isn't necessary to force a BURST-in-VDW display condition. The duration of VDW can just be shortened to letterbox the screen and allocate more scanlines to to the other display periods, giving more BURST time.
+
 
+
A MWR setting of $00 gives the CPU the largest amount of access cycles (twice per 8 pixels) which seems to be exactly equal to the amount of accesses available during BURST mode.
+
 
+
= Pin assignments =
+
  
 +
This is a worst-case test pattern for observing artifacting (note that artifacting only affects composite and RF output not RGB)
 
{| class="styled_table"
 
{| class="styled_table"
 
|-
 
|-
! Pin !!  Signal !!  Direction !!  Description
+
! PCC || Effect
 
|-
 
|-
| || /[o]CS[/o] || in || VDC chip select
+
| $00 || There is a repeating pattern of pink and green columns across the display. Depending on the pixel shift state, the color order is reversed (pink, green, pink.. or green, pink, green...).
 
|-
 
|-
| || /[o]RD[/o] || in || Write??? strobe
+
| $01 || The entire screen is filled with what appears as solid orange or sky blue depending on the pixel shift state.
 
|-
 
|-
| || /[o]WR[/o] || in || Read??? strobe
+
| $02 || Same as $00, except for the columns are thinner due to the increased resolution.
 
|-
 
|-
| || D15 || in / out || Data bus, bit 15
+
| $03 || Same as $02. In this mode the half pixel shift state is not selected by the frame count anymore, just by the scanline LSB and pixel shift state. If you toggle the pixel shift state you can control if the even or odd lines have a half pixel offset. This causes a highly visible skew between pairs of scanlines due to the horizontal offset every one of two scanlines has.
 
|-
 
|-
| || D14 || in / out || Data bus, bit 14
+
| $04 || The rainbow pattern alternates at 30 Hz between pink and green. The result is a mostly white area.
 
|-
 
|-
| || D13 || in / out || Data bus, bit 13
+
| $05 || The entire screen alternates at 30 Hz between orange and sky blue. It is horrible to look at.
 
|-
 
|-
| || D12 || in / out || Data bus, bit 12
+
| $06 || Same as $00, except for the columns are thinner due to the increased resolution. The columns appear to move horizontally across the screen due to their positions changing at 30 Hz.
 
|-
 
|-
| || D11 || in / out || Data bus, bit 11
+
| $07 || Same as $06. Because the pixel shift state is being toggled, the skew is almost not noticeable.
|-
+
| 9  || D10 || in / out || Data bus, bit 10
+
|-
+
| 10 || D9 || in / out || Data bus, bit 9
+
|-
+
| 11 || Ground ||  || Power supply
+
|-
+
| 12 || D8 || in / out || Data bus, bit 8
+
|-
+
| 13 || D7 || in / out || Data bus, bit 7 (16 bit mode)
+
|-
+
| 14 || D6 || in / out || Data bus, bit 6 (16 bit mode)
+
|-
+
| 15 || D5 || in / out || Data bus, bit 5 (16 bit mode)
+
|-
+
| 16 || D4 || in / out || Data bus, bit 4 (16 bit mode)
+
|-
+
| 17 || D3 || in / out || Data bus, bit 3 (16 bit mode)
+
|-
+
| 18 || +5V ||  || Power supply
+
|-
+
| 19 || D2 || in / out || Data bus, bit 2 (16 bit mode)
+
|-
+
| 20 || D1 || in / out || Data bus, bit 1 (16 bit mode)
+
|-
+
| 21 || D0 || in / out || Data bus, bit 0 (16 bit mode)
+
|-
+
| 22 || EX || in || Data bus width select ([o]16[/o]/8-bit)
+
|-
+
| 23 || CK || in || Clock input
+
|-
+
| 24 || /[o]RESET[/o] || in || Reset input
+
|-
+
| 25 || /[o]VSYNC[/o] || in / out || /VSYNC
+
|-
+
| 26 || /[o]HSYNC[/o] || in / out || /HSYNC
+
|-
+
| 27 || DISP || out || Screen blanking status ([o]blanked[/o]/displayed)
+
|-
+
| 28 || SPBG(VD8) || in / out || Pixel bus (sprite/[o]background[/o])
+
|-
+
| 29 || VD7 || in / out || Pixel bus (palette value, bit 3)
+
|-
+
| 30 || VD6 || in / out || Pixel bus (palette value, bit 2)
+
|-
+
| 31 || VD5 || in / out || Pixel bus (palette value, bit 1)
+
|-
+
| 32 || +5V ||  || Power supply
+
|-
+
| 33 || Ground ||  || Power supply
+
|-
+
| 34 || VD4 || in / out || Pixel bus (palette value, bit 0)
+
|-
+
| 35 || VD3 || in / out || Pixel bus (pixel value, bit 3)
+
|-
+
| 36 || VD2 || in / out || Pixel bus (pixel value, bit 2)
+
|-
+
| 37 || VD1 || in / out || Pixel bus (pixel value, bit 1)
+
|-
+
| 38 || VD0 || in / out || Pixel bus (pixel value, bit 0)
+
|-
+
| 39 || /[o]MWR[/o] || out || VRAM write strobe
+
|-
+
| 40 || /[o]MRD[/o] || out || VRAM read strobe
+
|-
+
| 41 || MD0 || in / out || VRAM data bus, bit 0 (VRAM chip 1)
+
|-
+
| 42 || MD1 || in / out || VRAM data bus, bit 1 (VRAM chip 1)
+
|-
+
| 43 || MD2 || in / out || VRAM data bus, bit 2 (VRAM chip 1)
+
|-
+
| 44 || MD3 || in / out || VRAM data bus, bit 3 (VRAM chip 1)
+
|-
+
| 45 || MD4 || in / out || VRAM data bus, bit 4 (VRAM chip 1)
+
|-
+
| 46 || MD5 || in / out || VRAM data bus, bit 5 (VRAM chip 1)
+
|-
+
| 47 || +5V ||  || Power supply
+
|-
+
| 48 || MD6 || in / out || VRAM data bus, bit 6 (VRAM chip 1)
+
|-
+
| 49 || MD7 || in / out || VRAM data bus, bit 7 (VRAM chip 1)
+
|-
+
| 50 || MD8 || in / out || VRAM data bus, bit 8 (bit 0 - VRAM chip 2)
+
|-
+
| 51 || MD9 || in / out || VRAM data bus, bit 9 (bit 1 - VRAM chip 2)
+
|-
+
| 52 || MD10 || in / out || VRAM data bus, bit 10 (bit 2 - VRAM chip 2)
+
|-
+
| 53 || MD11 || in / out || VRAM data bus, bit 11 (bit 3 - VRAM chip 2)
+
|-
+
| 54 || MD12 || in / out || VRAM data bus, bit 12 (bit 4 - VRAM chip 2)
+
|-
+
| 55 || Ground ||  || Power supply
+
|-
+
| 56 || MD13 || in / out || VRAM data bus, bit 13 (bit 5 - VRAM chip 2)
+
|-
+
| 57 || MD14 || in / out || VRAM data bus, bit 14 (bit 6 - VRAM chip 2)
+
|-
+
| 58 || MD15 || in / out || VRAM data bus, bit 15 (bit 7 - VRAM chip 2)
+
|-
+
| 59 || MA0 || out || VRAM address bus, bit 0
+
|-
+
| 60 || MA1 || out || VRAM address bus, bit 1
+
|-
+
| 61 || MA2 || out || VRAM address bus, bit 2
+
|-
+
| 62 || MA3 || out || VRAM address bus, bit 3
+
|-
+
| 63 || MA4 || out || VRAM address bus, bit 4
+
|-
+
| 64 || MA5 || out || VRAM address bus, bit 5
+
|-
+
| 65 || MA6 || out || VRAM address bus, bit 6
+
|-
+
| 66 || MA7 || out || VRAM address bus, bit 7
+
|-
+
| 67 || MA8 || out || VRAM address bus, bit 8
+
|-
+
| 68 || MA9 || out || VRAM address bus, bit 9
+
|-
+
| 69 || MA10 || out || VRAM address bus, bit 10
+
|-
+
| 70 || MA11 || out || VRAM address bus, bit 11
+
|-
+
| 71 || Ground ||  || Power supply
+
|-
+
| 72 || +5V ||  || Power supply
+
|-
+
| 73 || MA12 || out || VRAM address bus, bit 12
+
|-
+
| 74 || MA13 || out || VRAM address bus, bit 13
+
|-
+
| 75 || MA14 || out || VRAM address bus, bit 14
+
|-
+
| 76 || MA15 || out || VRAM address bus, bit 15
+
|-
+
| 77 || /[o]IRQ[/o] || out || /IRQ output to HuC6280 /IRQ1 input
+
|-
+
| 78 || [o]BUSY[/o] || out || BUSY status output
+
|-
+
| 79 || A0 || in || Address bus, bit 0
+
|-
+
| 80 || A1 || in || Address bus, bit 1
+
 
|}
 
|}
 
+
For settings that give a 7.16 MHz pixel clock ($01 and $05), the pixel rate is exactly twice of the color subcarrier frequency (3.58 MHz). I think this is what causing alternating pixels to appear as a single color rather than two distinct ones.
D15-D8 pin ordering is guessed based on D7-D0.
+
 
+
Not sure which half of the data bus is the MSB or the LSB, so both are D7-D0 in groups a,b
+
 
+
Clock input should be equal to the display pixel clock rate; e.g. 5.36 MHz.
+
 
+
The function of DISP, /VSYNC, /HSYNC is programmable.
+
 
+
The PCE uses MA15 as a chip-enable for the 64K of VRAM available in the PCE; access to addresses $8000-$FFFF means VRAM is disabled.
+
 
+
= Other/External Documentation =
+
 
+
[code]
+
*****************************************************************
+
*      PC-Engine Video Display Controller Documentation        *
+
*      .                                              .        *
+
*  ---+----------------------------------------------+---      *
+
*      |  MOST COMPLETE HuC6270 INTERNAL WORKINGS    |        *
+
*      |    DOCUMENT. IF YOU HAPPEN TO FIND *ANY*    |        *
+
*      |  WRONG INFORMATION, PLEASE CONTACT ME VIA  |        *
+
*      |  EMAIL AS SOON AS POSSIBLE SO I CAN FIX IT.  |        *
+
*  ---+----------------------------------------------+---      *
+
*      :                                              :        *
+
*                                                              *
+
*      document revision 0.3 (3rd release)                      *
+
*                                                              *
+
*      written by Emanuel Schleussinger in Feb 1998            *
+
*                ( eschleus@luva.lb.bawue.de )                *
+
*      Thanks to:                                              *
+
*          DAVID MICHEL for LOTS of information!!!!!!!!!! ;)    *
+
*          JENS CHR. RESTEMEIER for his EXCELLENT PCE-docu      *
+
*          DAVE SHADOFF for his emails and his TGSim source    *
+
*          NIMAI MALLE for his VDC explanations                *
+
*          VIDEOMAN for his excellent Hacking Web-Page          *
+
*                  and some documents in there                *
+
*          PAUL CLIFFORD for an excellent HuC6270 register docu *
+
*****************************************************************
+
 
+
Revision reference:
+
-----+-----------------------------+---------------+----------
+
| rev 0.3:
+
|  - improved the VDC register table A LOT thanks to the
+
|    help of PAUL CLIFFORD. Thx for that cool doc, dude!
+
|      (all those nasty 'unknown's are now eliminated)
+
|  - more examples here and there.
+
|  - fixed some docu bugs with help of David Michel.
+
|  - Added Video Color Encoder reference.
+
|  - Sprite storage description was WRONG, corrected now.
+
|
+
| rev 0.2:
+
|  - Added Sprite information.
+
|  - Fixed some major bugs in the docu.
+
|  - Registers updated.
+
|
+
| rev 0.1 (initial release):
+
|  - Still missing sprite docu, lots of undocumented registers.
+
-----+-----------------------------+---------------+----------
+
 
+
 
+
Document preface:
+
 
+
  This document has been created for both beginners and advanced
+
  programmers. There may be some information that you may well
+
  consider 'unnecessary' (such as the introduction to planar image
+
  storage), but please think of people who would really like to
+
  program the PC-Engine, but dont have a clue on how some basic
+
  techniques (like planar) work.
+
 
+
  This document is in very early state and may well contain
+
  a lot of information not being correct. For any wrong in-
+
  formation in this document you may discover, please write
+
  me a mail at eschleus@luva.lb.bawue.de so I can fix it and
+
  release a new version.
+
  The latest version of this document can always be obtained
+
  at my homepage located at:
+
 
+
          www.classicgaming.com/aec/
+
 
+
  or just write me an email and ask me to send you the latest
+
  revision.
+
 
+
  Any help on improving this document is highly appreciated!
+
 
+
  I think its the most complete one out there at this time.
+
 
+
  Yours,
+
  Manuel
+
 
+
  eschleus@luva.lb.bawue.de
+
  www.classicgaming.com/aec/
+
 
+
--------------------------------------------------------
+
-----          T  O  P  I  C  S      -------------
+
--------------------------------------------------------
+
 
+
 
+
        +-------------------------------------------+
+
        | 1. Purpose of the VDC / General info      |
+
        |                                          |
+
        | 2. The VRAM structure / encoding VRAM data|
+
        |                                          |
+
        | 3. Accessing the VDC from the CPU        |
+
        |                                          |
+
        | 4. The VDC registers in detail            |
+
        |                                          |
+
        | 5. The Sprites in the VRAM                |
+
        |                                          |
+
        | 6. The Sprite attribute table (SATB)      |
+
        |                                          |
+
        | 7. The Video Color Encoder                |
+
        |                                          |
+
        +-------------------------------------------+
+
 
+
--------------------------------------------------------
+
----- 1. Purpose of the VDC / General info -------------
+
--------------------------------------------------------
+
 
+
  The VDC (Video Display Processor), also known as the HuC6270,
+
  is the main graphics processing unit in the PC-Engine. Despite
+
  the CPU of the PC-Engine is only 8-bit, the VDC is a full 16-bit
+
  processor with very powerful capabilities. Its accessible from
+
  the main system via 3 special opcodes that write/read data from/
+
  into the Video Display. The VDC is connected to another chip known
+
  as the HuC6260 VCE (Video Color Encoder), which supplies the color
+
  palette data for the Video System.
+
 
+
  The VDC in the PC-Engine has two modes of operation:
+
 
+
    1. Background character processing
+
    2. Sprite processing
+
 
+
  The 64 kB VRAM that the VDC is connected to does NOT contain one big
+
  bitmap with all the display information stored pixel by pixel like
+
  on a Amiga or PC, the Graphics are stored tile-based. In case you do
+
  not know what tile-based graphics are, be sure to read section 2
+
  very carefully.
+
 
+
 
+
 
+
--------------------------------------------------------
+
----- 2. The VRAM structure / encoding VRAM data -------
+
--------------------------------------------------------
+
 
+
  The VRAM of the PC-Engine is 64 kBytes in size. No chip other
+
  than the VDC can access it. It contains all the important data
+
  needed for the display generation.
+
 
+
  The way graphical data is organized in the VRAM is called 'tile
+
  based'. This means there is NOT a huge bitmap containing a color
+
  index for every pixel, but only a list of pointers to small,
+
  rectangular areas in the VRAM that will, aligned to each other,
+
  make up the display. Explanation follows.
+
 
+
  Think of it like this:
+
  We have a 512*256 pixel 256 color screen. On a PC, for instance,
+
  we would have to have the following VRAM structure:
+
 
+
        +---------------------------------------+
+
        |      <--512 pixels across -->        |
+
        |                                      |
+
        |                                      | 256
+
        |                                      | pixels
+
        |                                      | down
+
        |                                      |
+
        |                                      |
+
        |                                      |
+
        |                                      |
+
        |                                      |
+
        +---------------------------------------+
+
  The color depth is 8 bit ^= 256 colors
+
 
+
  This would result in        512 * 256 * 8
+
                            = 1.048.576 bit
+
                            = 130 kbytes (roughly)
+
 
+
  So, if the PC-Engine would do it the same way, it would not be
+
  able to have such high resolutions due to the lack of VRAM.
+
  Thats why data is stored in the VRAM as follows:
+
 
+
  The screen background area is made up out of 8*8 pixels large
+
  blocks, called the 'tiles', each tile having a color palette of
+
  16 colors. There are 16 different palettes to choose from for
+
  each tile, resulting in 256 different colors for the background
+
  generation (the other 256 colors are reserved for sprite usage
+
  which will be described later).
+
  In the background, colour 0 of all palettes are equal. Colour 0 of
+
  palette 0 determines colour 0 of all the background palettes. Even
+
  though these colour CAN be set independently, the screen will not
+
  reflect these settings.
+
 
+
-----Now, how are those tiles aligned to each other?
+
 
+
  Starting at the very beginning of the VRAM ($0) there is the so-
+
  called BAT (Block Attribute Table), which is a list of pointers
+
  to tiles stored in the Video RAM. The amount of pointers varies
+
  depending on how big the actual screen is. (As I told you, you
+
  have 8*8 pixel tiles, so if the screen is larger, theres more
+
  tiles). For our test screen (512*256), we would need:
+
 
+
                            512 / 8    = 64 tiles per line
+
                            256 / 8    = 32 tiles vertical
+
                              64 * 32    = 2048 tiles
+
 
+
  That means, we would be in need of a BAT 2048 words in lenght.
+
 
+
-----WHY WORDS? How does a BAT pointer to the VRAM look like?
+
 
+
  A Pointer to a tile in the VRAM must contain palette information
+
  as well as the actual VRAM address where to find the tile. This
+
  ONE WORD LONG index pointer looks like this:
+
 
+
      PPPPAAAAAAAAAAAA
+
      |      |
+
      |      |
+
      |      +------- 12 lower bits:  Index of the tile
+
      |
+
      +--------------- 4  upper bits:  Palette number (0-15)
+
 
+
  If you multiply the tile index by 32 (LSL #5 ;-), you will get
+
  the actual VRAM pointer address.
+
 
+
  The pointers in the BAT are ordered from the left to the right
+
  and top to down.
+
 
+
  ----->Small example:<-----
+
 
+
  Here is the first few words of data in the VRAM of HATRIS, just having
+
  the intro screen up. If you look closely, note how VRAM was saved using
+
  the same tiles over and over again in the BAT:
+
 
+
 
+
 
+
-----HOW CAN I SET THE SIZE OF THE BAT?
+
 
+
  Easy, theres a VDC register dedicated to it, called the MWR register.
+
  (find more about the MWR in SECTION 4)
+
 
+
    MWR register mask:
+
  xxxxxxxxxxHWWxxx (16 bits)
+
                  | |
+
                  | +--- width in tiles/pixels
+
                  |      00 = 32/256
+
                  |      01 = 64/512
+
                  |      10 = 128/1024
+
                  |      11 = 128/1024
+
                  |
+
                  +----- height in tiles/pixels
+
                        0  = 32/256
+
                        1  = 64/512
+
 
+
  If you understood everything, you should now be asking:
+
  "No TV can display a resolution of 1024 pixels across, so whats
+
    this mode for?"
+
 
+
  Answer: Check out the BXR and BYR registers used for SCROLLING ;)
+
          (see SECTION 4)
+
 
+
 
+
-----HOW DOES THE TILE ITSELF LOOK LIKE IN THE VRAM?
+
 
+
  Well, the tile itself is a piece of memory sized like this:
+
 
+
      8 * 8 * 4 bits = 256 bits
+
      |  |  |
+
      |  |  +------- color index (4 bits per pixel)
+
      |  +----------- height in pixels
+
      +--------------- width in pixels
+
 
+
  On this issue, David Michel posted me a VERY good explanation on
+
  how the data of a single tile is organized in the VRAM:
+
 
+
    The PC-Engine use a planar mode rather than the well known chunky
+
    mode of PCs, if you already have some experience decoding Atari ST
+
    or Amiga gfx, you should easily understand the following.
+
 
+
    In planar mode the 4 bits that form the color index are stored
+
    in 4 separate bytes, let's say that we want to extract the color
+
    index for the third pixel from the left :
+
 
+
      color index
+
      3rd pixel
+
 
+
    +---+---+---+---+          +---+---+---+---+---+---+---+---+
+
    | 3 | 2 | 1 | 0 |  byte 1  | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+
    +---+---+---+---+          +---+---+---+---+---+---+---+---+
+
      |  |  |  |                      |
+
      |  |  |  +-----------------------+
+
      |  |  |
+
      |  |  |                +---+---+---+---+---+---+---+---+
+
      |  |  |        byte 2  | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+
      |  |  |                +---+---+---+---+---+---+---+---+
+
      |  |  |                          |
+
      |  |  +---------------------------+
+
      |  |
+
      |  |                    +---+---+---+---+---+---+---+---+
+
      |  |            byte 3  | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+
      |  |                    +---+---+---+---+---+---+---+---+
+
      |  |                              |
+
      |  +-------------------------------+
+
      |
+
      |                        +---+---+---+---+---+---+---+---+
+
      |                byte 4  | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+
      |                        +---+---+---+---+---+---+---+---+
+
      |                                  |
+
      +-----------------------------------+
+
 
+
    It's as simple as that :)
+
 
+
    The funny part is that those 4 bytes are not placed in order,
+
    they are interleaved. Byte 1 & 2 are stored first, and bytes
+
    2 & 3 are stored 16 bytes after, here is another nice drawing:
+
 
+
  VRAM OFFSET
+
        on pointer
+
        (in bytes)
+
                  +---------------------+
+
              0    | byte 1 & 2 of line 1|
+
                  +---------------------+
+
              2    | byte 1 & 2 of line 2|
+
                  +---------------------+
+
              4    | byte 1 & 2 of line 3|
+
                  +---------------------+
+
              6    | byte 1 & 2 of line 4|
+
                  +---------------------+
+
              8    | byte 1 & 2 of line 5|
+
                  +---------------------+
+
            10    | byte 1 & 2 of line 6|
+
                  +---------------------+
+
            12    | byte 1 & 2 of line 7|
+
                  +---------------------+
+
            14    | byte 1 & 2 of line 8|
+
                  +---------------------+
+
 
+
                  +---------------------+
+
            16    | byte 3 & 4 of line 1|
+
                  +---------------------+
+
            18    | byte 3 & 4 of line 2|
+
                  +---------------------+
+
            20    | byte 3 & 4 of line 3|
+
                  +---------------------+
+
            22    | byte 3 & 4 of line 4|
+
                  +---------------------+
+
            24    | byte 3 & 4 of line 5|
+
                  +---------------------+
+
            26    | byte 3 & 4 of line 6|
+
                  +---------------------+
+
            28    | byte 3 & 4 of line 7|
+
                  +---------------------+
+
            30    | byte 3 & 4 of line 8|
+
                  +---------------------+
+
 
+
  I think everyone should have got that right now. Thx David!
+
  If you ask yourself what this was about, consider reading part
+
  2 again. Part 3 won't be better ;-)
+
 
+
 
+
 
+
--------------------------------------------------------
+
----- 3. Accessing the VDC from the CPU ----------------
+
--------------------------------------------------------
+
 
+
---HOW CAN I TRANSFER DATA INTO THE VRAM?
+
 
+
  Well, there are three memory locations involved that can be read/
+
  written by the CPU to supply the VDC with data / read data from
+
  the VDC (all in the I/O Memory Segment $FF):
+
 
+
  Full address    Access Purpose
+
 
+
  $1FE000          R/W    VDC Register select
+
  $1FE002    R/W    Low Data register
+
  $1FE003          R/W    High Data register
+
 
+
    The first of the three locations here is the so-called REGISTER
+
    SELECT. The VDC has 19 Registers (several of them being totally
+
    unknown, btw) to access. To tell the VDC to which register you
+
    want to write the value contained in $1FE002 (and $1FE003), simply
+
    write the number of the register to write to into the low 5 bits
+
    of $1FE000. As the VDC is a 16 bit processor (ALL VDC registers
+
    are one word wide) in most cases you will need to supply both
+
    of the data values.
+
 
+
    Detailed description of the VDC ports by Videoman (slightly changed):
+
 
+
    Address  | Access | Description
+
    (Mapped  |  mode  |
+
    to $FF)  |        |
+
--------------+--------+---------------------------------------------------
+
      $0000  |  R    | 6270 Status register
+
              |        |
+
              |        |  Different bits flag different conditions.
+
              |        |  Not all are known.
+
              |        |  (Note: can use special ST0 opcode to store
+
              |        |  an immediate value.)
+
              |        |    b 7 = 0
+
              |        |    b 6 = 'BSY' flag
+
              |        |        I believe this is '1' when a DMA transfer
+
              |        |        is happening
+
              |        |    b 5 = 'VD' flag
+
              |        |        I believe this is a '1' when Vertical Sync
+
              |        |        happens, otherwise a '0' (uncertain)
+
              |        |    b 4 = 'DV' flag (unknown)
+
              |        |    b 3 = 'DS' flag (unknown)
+
              |        |    b 2 = 'RR' flag
+
              |        |        Set during a Scanline interrupt (see RCR
+
              |        |        register)otherwise '0'
+
              |        |    b 1 = 'OR' flag (unknown)
+
              |        |    b 0 = 'CR' flag (unknown)
+
              |        |
+
      $0000  |  W    | 6270 Address register
+
              |        |
+
              |        |    b 7-5 = ignored
+
              |        |    b 4-0 = 6270 register number to access using
+
              |        |            the 6270 data registers
+
              |        |            ($0002 and $0003). Please see 6270
+
              |        |            register list (SECTION 4) for details.
+
              |        |
+
      $0002  |  R/W  | 6270 data LSB
+
              |        |
+
              |        |  Note: can use special ST1 opcode to store
+
              |        |        an immediate value.)
+
              |        |
+
      $0003  |  R/W  | 6270 data MSB
+
              |        |
+
              |        |  Note: can use special ST2 opcode to store
+
              |        |        an immediate value.)
+
--------------+--------+---------------------------------------------------
+
 
+
  ----->One short example on this one:<------
+
 
+
    To read the contents of Register 2 (VRAM-Read-Register) simply use the
+
    following line of code:
+
 
+
      ST0 #2
+
      ...and then the two data values will sort of 'mirror' the value in
+
      this VDC register.
+
 
+
 
+
--------------------------------------------------------
+
----- 4. The VDC registers -----------------------------
+
--------------------------------------------------------
+
 
+
This huge and very complete list has been taken from Videomans
+
hardwaremap document,  Jens' PCE documentation, and some information
+
to it was added by me.
+
 
+
 
+
REG    ACCESS  DESCRIPTION+
+
NO.    MODE    DETAILS
+
------------------------------------------------------------------------
+
0      R?/W    MAWR - 'Memory Address Write Register'
+
 
+
        b 15-0  this is the internal
+
                register used as an address-counter when writing to VRAM.
+
                All bits used (although no VRAM above $7FFF).
+
 
+
1      R?/W    MARR - 'Memory Address Read Register'
+
 
+
        b 15-0  this is the internal
+
                register used as an address-counter when reading from VRAM.
+
                All bits used (although no VRAM above $7FFF).
+
 
+
2      R      VRR - 'VRAM Read Register'
+
 
+
        b 15-0  this is the only valid read-access
+
                from the data port.  It reads the value from VRAM at the
+
                address specified by the MARR.  When the value is read
+
                from the second byte-port at $0003, the MARR register
+
                (ie. the 'address to read from') is auto-incremented
+
                (although this may be a configurable behaviour).
+
                All bits used.
+
 
+
2      W      VWR - 'VRAM Write Register'
+
 
+
                (write-access version of the above)
+
        b 15-0  Write value to VRAM at the address specified by the MAWR.
+
                When the value is written to the second byte-port at $0003,
+
                the MAWR register (ie. the 'address to write to') is
+
                auto-incremented (although this may be a configurable behaviour).
+
 
+
3      ?      (unused) ?
+
 
+
4      ?      (unused) ?
+
 
+
5      ?      CR - 'Control Register'
+
 
+
                    b 15-13 unused
+
                    b 12-11 'IW' Address register auto-Increment
+
                                  of the MAWR register
+
                                  00 - normal increment (+1)
+
                                  01 - +32
+
                                  10 - +64
+
                                  11 - +128
+
 
+
                    b 10    'DR' Dynamic RAM refresh (unknown by me though)
+
                    b 9-8  'TE' Selection of DISP terminal outputs
+
                                  00 - DISP output "H" during display
+
                                  01 - BURST colour burst inserting position is
+
                                      indicated by output "L"
+
                                  10 - INTHSYNC internal horizontal synchronous
+
                                      signal
+
                                  11 - not used
+
                    b 7    'BB' background (on/off)    --+
+
                                  1  - display background  |
+
                                  0  - no background        > gets effective in
+
                    b 6    'SB' sprites (on/off)          |  next horizontal
+
                                  1  - display sprites      |  display period.
+
                                  0  - no sprites        --+
+
                    b 5-4  'EX' (name unknown by me)
+
                                  00 - vsync and hsync inputs
+
                                  01 - vsync input, hsync output
+
                                  10 - not used
+
                                  11 - vsync and hsync outputs
+
 
+
                    b 3    irq  (on/off)
+
                                  0 = disabled
+
                                  1 = enabled
+
                    b 2    rcr  (on/off)
+
                                  0 = disabled
+
                                  1 = enabled
+
                    b 1    Enable interrupt for excess number detection of
+
                            sprites.
+
                                  0 = disabled
+
                                  1 = enabled
+
                    b 0    Enable interrupt for sprite collision detection.
+
                                  0 = disabled
+
                                  1 = enabled
+
 
+
                    Editor's note: bits 3-0 sound suspiciously like
+
                    interrupt-enable flags. Given what we know about
+
                    the interrupt vector table, is it logical to assume
+
                    that the remaining two IE bits stand for the
+
                    remaining two interrupt vectors? Then again, maybe not.
+
                      $FFFC-$FFFD    NMI Vector
+
                      $FFFA-$FFFB    TIMER Vector
+
                      $FFF8-$FFF9    IRQ1 Vector (for Video)
+
                      $FFF6-$FFF7    IRQ2 Vector (for BRK)
+
 
+
 
+
6      R      RCR - 'Raster Counter Register'
+
 
+
                    b 15-10 ?
+
                    b 9-0  The rcr bit controls the generation of a raster
+
                            counter IRQ. The VDC generates an IRQ, when the
+
                            scanline specified in the RCR register is displayed.
+
                            You need to add 64 to the RCR register to get the
+
                            correct scanline.
+
 
+
7      R?/W    BXR - 'Background X-Scroll Register'
+
 
+
                    b 15-10 (not used)
+
                    b 9-0  when the background map is a larger virtual
+
                            size than the viewing screen shows, this is
+
                            the viewing screen's x-offset (in pixels)
+
                            from the origin of the virtual background map.
+
 
+
8      R?/W    BYR - 'Background Y-Scroll Register'
+
 
+
                    b 15-9  (not used)
+
                    b 8-0  when the background map is a larger virtual
+
                            size than the viewing screen shows, this is
+
                            the viewing screen's y-offset (in pixels)
+
                            from the origin of the virtual background map.
+
 
+
9      R?/W    MWR - 'Memory-access Width Register'
+
 
+
                    Used to configure the size of the virtual background
+
                    map.
+
 
+
                    b 15-8  (not used)
+
                    b 7    'CM' (unknown - presumably 'Color Mode')
+
                    b 6-4  'SCREEN' These bits control virtual map size
+
                            as noted below.
+
                            b 6    virtual screen height
+
                                    0 = 256 pixels / 32 tiles
+
                                    1 = 512 pixels / 64 tiles
+
                            b 5-4  virtual screen width
+
                                    00 = 256 pixels / 32 tiles
+
                                    01 = 512 pixels / 64 tiles
+
                                    10 = 1024 pixels / 128 tiles
+
                                    11 = 1024 pixels / 128 tiles
+
 
+
                                      Complete lookup of
+
                                      available sizes in tiles:
+
                                      -------------------------
+
                                        000 -  32 x 32
+
                                        001 -  64 x 32
+
                                        010 - 128 x 32
+
                                        011 - 128 x 32
+
                                        100 -  32 x 64
+
                                        101 -  64 x 64
+
                                        111 - 128 x 64
+
 
+
 
+
                    b 3-2  Sprite pixel width
+
                    b 1-0  VRAM pixel width
+
 
+
10($A)  ?      HSR - 'Horizontal Sync Register'
+
 
+
                    b 15    (not used)
+
                    b 14-8  'HDS' Horizontal display start position -1.
+
                    b 7-5  (not used)
+
                    b 4-0  'HSW' Horizontal synchronous pulse width.
+
 
+
                    Mask = $7F1F
+
 
+
11($B)  ?      HDR - 'Horizontal Display Register'
+
 
+
                    b 15    (not used)
+
                    b 14-8  'HDE' Horizontal display ending period -1.
+
                    b 7    (not used)
+
                    b 6-0  'HDW' Horizontal display width in tiles -1.
+
 
+
                    Mask = $7F7F
+
 
+
                    added from Jens' PCE-documentation: Lower half of HDR:
+
                      It controls the horizontal width of display generation.
+
                      The value in this register is the number of horizontal
+
                      tiles minus one. Normal values are 31, for 32 tiles
+
                      and 256 pixel horizontally, 39, for 40 tiles or 320
+
                      pixel and 63, for 64 tiles or 512 pixel.
+
 
+
12($C)  ?      VPR - 'Vertical synchronous register'
+
 
+
                    b 15-8  'VDS' Vertical display start position -2.
+
                    b 7-5  (not used)
+
                    b 4-0  'VSW' Vertical synchronous pulse width.
+
 
+
                    Mask = $FF1F
+
 
+
 
+
13($D)  ?      VDW - 'Vertical display register'
+
 
+
                    b 15-9  (not used)
+
                    b 8-0  Vertical display width in pixels -1.
+
 
+
                    NOTE:
+
                        Unlike the HDR register, the information on the
+
                        vertical display width is split up in two registers,
+
                        this one storing the vertical width, and the next one
+
                        (VCR) containing the vertical display end position.
+
 
+
 
+
14($E)  ?      VCR - 'Vertical display END position register'
+
 
+
                    b 15-8  (not used)
+
                    b 7-0  Vertical display end position.
+
 
+
15($F)  ?      DCR - 'DMA Control Register'
+
 
+
    The DCR, SOUR, DESR and LENR registers control
+
    DMA operations.
+
    The DMA operation starts, as soon as the length
+
    is written into the LENR register
+
 
+
                                              b 15-5 (not used)
+
                                              b 4 -  DSR DMA (VRAM-SATB transfer repetition)
+
                    b 3 -  Increment (0)/decrement (1) of
+
                          destination address.
+
                    b 2 -  Increment (0)/decrement (1) of
+
                          source address.
+
                    b 1 -  Enable interrupt at completion of
+
                          VRAM-VRAM transfer.
+
                          Checked on completion of transfer.
+
                    b 0 -  Enable interrupt at completion of
+
                          VRAM-SATB transfer.
+
                          Checked on completion of transfer.
+
 
+
16($10) R?/W    SOUR - '(DMA) Source Address Register'
+
 
+
                    b 15-0  This register sets the source address
+
                            for DMA transfers.
+
                            All bits used (address pointer).
+
 
+
17($11) R?/W    DESR - '(DMA) Destination Address Register'
+
 
+
                    b 15-0  This register sets the destination
+
                            address for DMA transfers.
+
                            All bits used
+
                            (although no VRAM above $7FFF).
+
 
+
18($12) R?/W    LENR - '(DMA) Block Length Register'
+
 
+
                    b 15-0  This register sets the length of
+
                            the DMA transfer.
+
                            All bits used
+
                            (although no VRAM above $7FFF).
+
 
+
19($13) R?/W    SATB - 'Sprite Attribute Table'
+
 
+
                    b 15-0  This register points to the start address
+
                            of the sprite attribute table.
+
                            All bits used
+
                            (although no VRAM above $7FFF).
+
 
+
 
+
 
+
--------------------------------------------------------
+
----- 5. The Sprites in the VRAM -----------------------
+
--------------------------------------------------------
+
 
+
  Well, I will not try to explain what Sprites are here. Basically,
+
  all of the PC-Engines' sprites are 16*16 to 32*64 pixels in size,
+
  and have a sprite palette of 16 colors.
+
  There are 16 separate sprite palettes available. (remember, there
+
  was 16*16 colors for the background processing, those colors are
+
  INDEPENDENT from the sprite palettes).
+
 
+
  In the Sprites colours, colour 0 is transparent in all palettes,
+
  although it does peek it's head in a peculiar place; beyond the display
+
  width of the BG.
+
  Explanation:
+
  The background display area (in it's most often used setting) is 256x216.
+
  The display width of a television may be adjusted to squash the screen
+
  vertically, or horizontally. Even normal TVs show a little more that 256
+
  TG-16 pixels wide, leaving a black border on the sides. This border colour is
+
  actually controlled by sprite colour 0. The programmer can actually set the
+
  screen width more narrow or vertically shorter, showing more of this area.
+
  It's only use that I've ever implemented was in measuring the CPU load of
+
  the TG-16 during development.
+
 
+
--HOW ARE SPRITES STORED IN THE VRAM?
+
 
+
  For the sprite characters the principe is the same as for the background
+
  tiles, but in place of using bytes (8 pixels) they use words (16 pixels).
+
  Note that the words still use the same encoding as all word data within the
+
  PC-Engine, this means that the first byte of the word is the lower byte.
+
  Sprite data is stored like in the following drawing:
+
 
+
            Byte          Data
+
          offset
+
 
+
                  +-------------------+
+
              0    | plane 1 of line 1 |
+
                  +-------------------+
+
              2    | plane 1 of line 2 |
+
                  +-------------------+
+
                  .                  .
+
                  :                  :
+
            30    | plane 1 of line 16|
+
                  +-------------------|
+
            32    | plane 2 of line 1 |
+
                  +-------------------+
+
            34    | plane 2 of line 2 |
+
                  +-------------------+
+
            36    | plane 2 of line 3 |
+
                  +-------------------+
+
                  .                  .
+
                  :                  :
+
            46    | plane 2 of line 16|
+
                  +-------------------+
+
            48    | plane 3 of line 1 |
+
                      ......and so on.
+
 
+
 
+
 
+
  Not only you can display sprites, you can do some sort of funny stuff
+
  with them, like mirroring, for instance. All this is controlled in the
+
  so-called SPRITE ATTRIBUTE TABLE.
+
 
+
 
+
 
+
--------------------------------------------------------
+
----- 6. The Sprite attribute table (SATB) -------------
+
--------------------------------------------------------
+
 
+
  The sprites' positions and attributes are defined in the so-
+
  called SPRITE ATTRIBUTE TABLE (SATB). The SATB can be contained any-
+
  where in the VRAM ($0000-$7FFF).
+
 
+
--HOW DOES THE VDC KNOW WHERE THE SATB IS TO BE FOUND?
+
 
+
  The VDC has a special register containing nothing but the start
+
  address of the SATB in the VRAM. This is register 19 (SEE SECTION 4)
+
 
+
  The actual sprite attributes are stored at the address mentioned
+
  above. For aech sprite, there is a 4 word long attribute section,
+
  which looks as follows:
+
 
+
  Word  | Access | Description
+
  offset |  mode  |
+
--------------------------------------------------------------------------
+
    0    R/W    Y position
+
 
+
                b 15-10  (unused)
+
                b 9-0    y position (relative to
+
                              virtual-screen origin)
+
 
+
    1    R/W    X position
+
 
+
                b 15-19  (unused?)
+
                b 9-0    x position (relative to
+
                              virtual-screen origin)
+
 
+
    2    R/W    Pattern address
+
 
+
                b 15-11  (unused?)
+
                b 10-0      sprite data VRAM address shifted
+
                              right 5 bits(Shift left 6 bits to
+
                              get real VRAM address)
+
 
+
    3    R/W    Sprite attributes
+
 
+
                b 15    y-invert flag (upside-down)
+
                b 14    unused
+
                b 13-12  'CGY'
+
                      00 = sprite is 1 'cell' (16 pixels) high
+
                      01 = sprite is 2 cells high (32 pixels)
+
                      10 = invalid
+
                      11 = sprite is 4 cells high (64 pixels)
+
                b 11    x-invert flag (left-right invert)
+
                b 10-9    unused
+
                b 8  'CGX'
+
                    0 = sprite is 1 'cell' wide (16 pixels)
+
                    1 = sprite is 2 cells wide (32 pixels)
+
                b 7  'SPBG'; is sprite in foreground (in front
+
                                    of CG) or background (behind CG)
+
                b 6-4    unused
+
                b 3-0    sprite colour (i.e. which of 16 sprite
+
                                            palettes to use)
+
 
+
[/code]
+
  
 
= Patents =
 
= Patents =
  
* [https://www.google.com/patents/US4951038 Displaying Sprites]
+
{{:Patent 5059955}}
* [https://www.google.com/patents/US5319786 Multiple Screen Windows]
+
* [https://www.google.com/patents/US5030946 VRAM access by VDC/CPU]
+
* [https://www.google.com/patents/US5838295 1-Bit Fonts]
+
 
+
{{:Patent 4951038}}
+
{{:Patent 5319786}}
+
{{:Patent 5030946}}
+
{{:Patent 5838295}}
+

Revision as of 22:33, 30 April 2014

The HuC6260

VCE. Referred to as 鉄観音 - "TETSU" by NEC-HE.

The HuC6260 Video Color Encoder basically supplies the picture on your television.

It is connected to the VDC and coordinates the palette processing as its most important job.

Notes

  • all mentions of "dot" have been replaced with "pixel" (PCC is now PCC)
  • all registers are 16 bit.

Registers

$0400 - CR - Control Register

Write only register.

Bit(s) Description Values
0 - 1 PCC - Pixel Clock Control

0 = 5.37 MHz
1 = 7.16 MHz
2 = 10.7 MHz
3 = 10.7 MHz

2 Frame/Field Configuration

00 = 262-line frame
01 = 263-line frame

3 - 6  ???  ???
7 Strip Colorburst

0 = Colorburst intact
1 = Strip colorburst

8 - 15  ???  ???

$0402 - CTA - Color Table Address Register

Write only register.

Bit(s) Description Values
0 - 8 index for the color table 0 to 511
9 - 15 (unused)

Note: This register is auto-incremented after each access to the color data register.


$0404 - CTW - Color Table Write Register / CTR - Color Table Read Register

Write/Read register.

Access (read/write) to this register causes CTA register to increment.

Bit(s) Description
0 - 2 Blue
3 - 5 Red
6 - 8 Green
9 - 15 (unused)

Notes

Display artifact
When bit 2 of $0400 is set, a flip-flop is toggled once per frame that offsets the entire frame by one pixel. I'll call this the pixel shift state. Depending on the last state of the flip-flop when bit 2 of $0400 is reset, the pixel shift state can be forced to zero or one. When enabled this completely eliminates the color fringe artifact that is apparent for PCC settings $00-$03.

The VCE applies a 1/2 pixel shift on every even or odd scanline. The selection of even or odd scanlines is inverted on every frame, and is further inverted by the pixel shift state, however in all but 2 settings this is unnoticable.

In "C" pseudocode these work like so:

  //each frame 
  if(PCC & 4) pixelShiftState ^= 1;
  //each scanline
  halfPixelShiftState = (framecount & 1) ^ (scanline & 1) ^ (pixelShiftState & 1);

Here are the results of some tests I did when the screen is filled with alternating white and black pixels on even scanlines and black and white pixels on odd scanlines.

This is a worst-case test pattern for observing artifacting (note that artifacting only affects composite and RF output not RGB)

PCC Effect
$00 There is a repeating pattern of pink and green columns across the display. Depending on the pixel shift state, the color order is reversed (pink, green, pink.. or green, pink, green...).
$01 The entire screen is filled with what appears as solid orange or sky blue depending on the pixel shift state.
$02 Same as $00, except for the columns are thinner due to the increased resolution.
$03 Same as $02. In this mode the half pixel shift state is not selected by the frame count anymore, just by the scanline LSB and pixel shift state. If you toggle the pixel shift state you can control if the even or odd lines have a half pixel offset. This causes a highly visible skew between pairs of scanlines due to the horizontal offset every one of two scanlines has.
$04 The rainbow pattern alternates at 30 Hz between pink and green. The result is a mostly white area.
$05 The entire screen alternates at 30 Hz between orange and sky blue. It is horrible to look at.
$06 Same as $00, except for the columns are thinner due to the increased resolution. The columns appear to move horizontally across the screen due to their positions changing at 30 Hz.
$07 Same as $06. Because the pixel shift state is being toggled, the skew is almost not noticeable.

For settings that give a 7.16 MHz pixel clock ($01 and $05), the pixel rate is exactly twice of the color subcarrier frequency (3.58 MHz). I think this is what causing alternating pixels to appear as a single color rather than two distinct ones.

Patents

Patent for Video Output

Full Patent

Original Patent

United States Patent Number: 5059955

APPARATUS FOR PRODUCING VIDEO SIGNALS

In [Figure 1], there is shown a color image displaying apparatus to which an apparatus for producing video signals is applied. The color image displaying apparatus comprises a CPU (1) for controlling the whole system, a ROM (2) for storing programs by which the whole system is controlled, a RAM (3) for storing data and calculation results temporarily, a Video Color Encoder (4) which is an apparatus for producing video signals in the invention and which produces output signals A of analog RGB signals and B of a composite signal, a Video Display Controller (5) for controlling a supply of video data to the Video Color Encoder (4), a VRAM (6) for storing video data to be supplied to the Video Color Encoder (4), and a video display (9) for displaying a color image in accordance with the analog RGB signals or the composite signal.

[Figure 1] is a block diagram showing a color image displaying apparatus to which an apparatus for producing video signals in an embodiment according to the invention is applied.

[Figure 2] shows the Video Color Encoder (4) which is an apparatus for producing video signals in the embodiment according to the invention. In the Video Color Encoder (4), a 8/16 bit data bus interface (23) and an Address Register (24) are provided to be connected through a CPU data bus (21) of 9 bits D0 to D8 to the CPU (1), and an address selector (25) is provided to be connected through a VDC data bus (22) of 9 bits VD0 to VD8 to the Video Display Controller (5). The 8/16 bit data bus interface (23) has a function that the Video Color Encoder (4) is connected to the CPU (1) of 8 bits or 16 bits, and the address selector (25) selects one data from data in the Address Register (24) and data on the VDC data bus (22) as an address signal. A color table RAM (26) is connected to the 8/16 bit data bus interface (23), and a data latch circuit (27) having three outputs for R, G and B color data is connected to the color table RAM (26) so that color data read from the color table RAM (26) are latched in the data latch circuit (27). The three outputs of the data latch circuit (27) are connected to digital to analog converters (28, 29 and 30) for R, G and B color data and to a matrix ROM (31) having a signal conversion matrix therein in which color data are converted to a luminance signal Y, and color difference signals R-Y and B-Y. The 8/16 bit data bus interface (23), the Address Register (24), the address selector (25), the color table RAM (26), and the data latch circuit (27) are controlled together with a synchronous signal producing circuit (33) by a control circuit (32) having inputs of a 8/16 bit selection signal EX 8/16, a chip selection signal (CS), a writing signal (WR), a reading signal (RD), an output control signal (CESEL) etc. The synchronous signal producing circuit (33) receives an oscillation signal of a sinusoidal wave having a frequency of, for instance, 21.47727 MHz from an oscillation circuit (33A) and produces horizontal and vertical synchronous signals (HSYNC and VSYNC), pixel clock signals (CK), color subcarriers etc. The R, G and B digital to analog converters (28, 29 and 30) are connected to an analog RGB signal output circuit (41A) to which a synchronous signal composite circuit (34) is also connected. Outputs of the matrix ROM (31) are connected to digital to analog converters (35, 36 and 37) for the luminance signal Y, and the color difference signals R-Y and B-Y. The R-Y and B-Y digital to analog converters (36 and 37) are connected to modulators (38 and 39) in which the two color subcarriers of the same frequency and different phases by ninety degrees supplied from the synchronous signal producing circuit (33) are modulated by the color difference signals R-Y and B-Y, respectively, so that color carrier signals are produced therein. One of the color subcarriers is also supplied to a burst circuit (40) in which a burst signal is produced by inserting the color subcarrier of 8 or nine cycles at a period of back porch of the horizontal synchronous signal. In the Y digital to analog converter (35), the luminance signal is combined with the synchronous signals. The Y digital to analog converter (35), the modulators (38 and 39), and the burst circuit (40) are connected to a composite signal output circuit (41B).

[Figure 2] is a block diagram showing an apparatus for producing video signals in the embodiment

In [Figure 3], there are explained a Control Register (CR), a Color Table Address register (CTA), a Color Table data Write register (CTW), and a Color Table data Read register (CTR) included in the control circuit (32). These registers are enabled with the chip selection signal (CS) 0 and one of them is selected with a content of the address A1 and A2 as follows.

In regard to a bit width selection, a bit width of 16 bits is selected when the signal EX 8/16 is 0, while a bit width of 8 bits is selected when the signal EX 8/16 is 1. In a case where the 8 bit width is selected, transferred data are of a lower byte for a register when the address A0 is 0, and transferred data are of an upper byte for a register when the address A0 is 1.

The Control Register (CR) includes frequency dividing data PCC in lower 8 bits.

[Figure 3] is an explanatory diagram explaining registers used in an apparatus for producing video signals in the embodiment

In [Figure 4], there is explained a relation between an oscillation frequency of a sinusoidal wave in the oscillation circuit (31A) and a square wave pixel clock frequency (CK) wherein the dividing ratio is four when the content PCC is 0x00, and the dividing ratio is three when the content PCC is 0x01. In [Figure 4], the expression "fsc " indicates a frequency of a color subcarrier so that the expression "6fsc " means that a sinusoidal wave having a frequency of six times that of the color subcarrier is supplied to the synchronous signal producing circuit (33). Thus, the frequency dividing ratio of the synchronous signal producing circuit (33) is controlled by the Control Register (CR).

The Color Table Address register (CTA) includes a starting address CTA at lower 9 bits. The starting address is an address for the color table RAM (26) from which data transferred from the CPU (1) are started to be written into the color table RAM (26). When an address is set in the Address Register (24), the address is automatically incremented by one each time when data are read or written.

The Color Table data Write register (CTW) and the Color Table data Read register (CTR) include 3 bit color data for R, G and B at lower 9 bits respectively, and are used for a transfer of data between the CPU (1) and the color table RAM (26).

[Figure 4] is an explanatory diagram explaining a dividing ratio of an oscillation frequency

[Figure 5] shows video data VD0 to VD8 supplied from the Video Display Controller (5). The most significant bit VD8 defines a kind of data, that is, when the bit VD8 is 0, the data VD0 to VD7 are of a background, and when the bit VD8 is 1, the data VD0 to VD7 are of a sprite. In the data VD0 to VD7, the upper 4 bits VD4 to VD7 are of an address signal for addressing area color (a designation of a block), and the lower 4 bits VD0 to VD3 are of an address signal for addressing one color data in a block.

[Figure 5] is an explanatory diagram explaining video data

[Figures 6A and 6B] show the color table RAM (26) in which a region A includes color data for a background, and a region B includes color data for sprites. The regions A and B includes 16 blocks O to F each including 16 addresses 0 to F. The color table RAM (26) includes a memory region for color data R, G and B each being of 3 bits. As apparent from the above, the regions A and B have 256 addresses respectively so that 512 colors can be displayed.

[Figures 6A and 6B] are explanatory diagrams showing a color table RAM in an apparatus for producing video signals in the embodiment

[Figure 7] shows the matrix ROM (31) which stores luminance signals Y, color difference signals B-Y and R-Y at addresses of R, G an B color signals read from the color table RAM (26) to be latched in the latch circuit (27). For instance, when the color data are that G is 000, R is 000, and B is 010, the color difference signals B-Y and R-Y are 0x14 and 0x0F, and the luminance signal is 0x01.

[Figure 7] is an explanatory diagram showing a matrix ROM in an apparatus for producing video signal in the embodiment

[Figure 8A] shows the address selector (25), the color table RAM (26) and the matrix ROM (31) as shown in [Figure 2]. A first flip-flop (25a) is provided to function as a latch circuit at a front stage of the address selector (25), and second and third flip-flops (27a and 27b) are provided as the latch circuit (27) in [Figure 2] at a rear stage of the color table RAM (26). The operation of the first to third flip-flops (25a, 27a and 27b) are controlled with timings of pixel clocks (CK), provided tat the third flip-flop (27b) is controlled with pixel clocks (CK) passed through an AND circuit (42) having two inputs connected to a pixel clock terminal and a delay circuit (43). The delay circuit (43) produces a signal 0 when the chip selection signal (CS) is 0, and a signal 1 when a predetermined time T is elapsed after the chip selection signal (CS) becomes 1 from 0. A fourth flip-flop is connected to an output of the matrix ROM (31).

In operation, color data are first written into the color table RAM (26) through a process in which the Color Table Address register (CTA) is addressed with address signals A1 and A2 of 1 and 0 so that a starting address CTA of the color table RAM (26) is set therein. In a case where the 16 bit width is selected, the starting address is set by one time. While, in a case where the 8 bit width is selected, the starting address is set in such a manner that a lower byte is first set therein and an upper byte is then set therein. Next, color data are written into the color table RAM (26) at the address in such a manner that the color data are written thereinto by one time in case of 16 bit width, while a lower byte thereof and then an upper byte thereof are written thereinto in case of 8 bit width. Then, an address of the color table RAM (26) is automatically incremented so that color data are successively written thereinto.

When video data as shown in [Figure 5] are transferred through the VDC data bus (22) from the Video Display Controller (5) to the Video Color Encoder (4), the address selector (25) selects the transferred video data to decide an address of the color table RAM (26) as shown in [Figures 6A and 6B] so that color data of R, G and B are read therefrom to be latched in the latch circuit (27) in accordance with the pixel clock (CK). At this moment, one of regions A and B is selected dependent on a content of the VD8 bit as described before, and a predetermined block is selected in the selected region A or B dependent on a content of the VD4 to VD7 bits. In the selected block, a predetermined address is accessed dependent on a content of the VD0 to VD3 bits. When color data are latched in the latch circuit (27), analog RGB signals or a composite signal can be supplied from the analog RGB signal output circuit (41A) or the composite signal output circuit (41B) through the interface 7 or 8 to the video display (9).

  1. Output of analog RGB signals

    When the frequency dividing ratio PCC of the Control Register (CR) is set to be 0x01, the frequency dividing ratio is three as shown in [Figure 4]. Digital RGB color data in the latch circuit (27) are converted in the R, G and B digital to analog converters (28, 29 and 30) to produce analog RGB signals. Simultaneously, horizontal and vertical synchronous signals HSYNC and VSYNC supplied from the synchronous signal producing circuit (33) are combined in the synchronous signal composite circuit (34) to produce a composite synchronous signal. Then, these analog RGB and composite synchronous signals are supplied from the analog RGB signal output circuit (41A) directly to the video display (9) or to an exclusively used monitor means (not shown). The analog RGB signals thus supplied thereto are of a video band of 7 MHz. On the contrary, the video band will be 5 MHz, if the frequency dividing ratio is set to four.

  2. Output of a composite signal

    When the dividing ratio PCC of the Control Register (CR) is set to be 0x00, the dividing ratio is four. A luminance signal Y and color difference signals R-Y and B-Y are supplied from the matrix ROM in accordance with R, G and B color data latched in the latch circuit (27), and then converted in the digital to analog converters 35, 36 and 37 to analog signals. At this moment, the luminance signals Y are combined with the synchronous signals from the synchronous signal producing circuit (33). On the other hand, color carriers are obtained from the balanced modulation of color subcarriers having the same frequency and different phases by ninety degrees, which are supplied from the synchronous signal producing circuit (33) in accordance with the color difference signals R-Y and B-Y. Further, a burst signal is obtained from the insertion of the color subcarrier of 8 or nine cycles into a back porch period of the horizontal synchronous signal in the burst signal producing circuit 40. These signals thus obtained are combined in the composite signal output circuit (41B) to produce a composite signal which is then supplied through the interface (8) to a receiving circuit of the video display (9) to be displayed on the video display thereof. The composite signal is of a video band of 5 MHz and is based on a system of NTSC. As a matter of course, the video band may be 7 MHz as described before.

    Next, a timing at which RGB color data are latched in the latch circuit (27) with the pixel clock (CK) will be described in more detail in conjunction with [Figures 8A and 8B].

    When video data VD0 to VD8 are transferred from the Video Display Controller (5) to the Video Color Encoder (4), the video data are latched in the first flip-flop (25a), and the color table RAM (26) is addressed with an address signal of the video data VD0 to VD8 so that RGB color data are read from the color table RAM (26) to be latched in the second flip-flop (27a). When a first bit of the second flip-flop (27a) is latched in the third flip-flop (27b), it is assumed that the chip selection signal (CS) becomes 0 for the purpose that data are written into the color table RAM (26) by the CPU (1). As a result, an output of the delay circuit (43) becomes 0 to result in no output of the pixel clock (CK) from the AND circuit (42). Therefore, a second bit and signals following after the second bit in the second flip-flop (27a) are prevented from being latched in the third flip-flop (27b). Thereafter, when the chip selection signal (CS) becomes " 1", the delay circuit (43) times a predetermined time T, and when the time T is elapsed, an output of the delay circuit (43) becomes 1. Accordingly, the pixel clock (CK) is again supplied to the third flip-flop (27b) so that an 8 bit and signals following after the 8 bit in the second flip-flop (27a) are latched in the third flip-flop (27b) to be supplied to a following stage as digital RGB signals. At this moment, an output of RGB color data is prohibited during an indeterminate period of data in the color table RAM (26) so that flicker caused by a transfer of data between the CPU (1) and the color table RAM (26) is prevented from being occurred on the display. In the color table RAM (26), one of the regions A and B is selected dependent on a content of the VD8 bit, and one of blocks is selected dependent on a content of the VD4 to VD7 bits in the selected region A or B. In the selected block, one of addresses is accessed dependent on a content of the VD0 to VD3 bit. When color data are latched in the third flip-flop (27b), analog RGB signals and a composite signal can be produced as described before.

[Figure 8A/B] [Figures 8A and 8B] are a block diagram showing an apparatus for producing video signals in the embodiment and a timing chart in operation.
[Figure 8A/B] [Figures 8A and 8B] are a block diagram showing an apparatus for producing video signals in the embodiment and a timing chart in operation.