Casio PV-1000/ASIC registers: Difference between revisions

From Obscure Wiki
Jump to navigationJump to search
(Created page with "The µPD65010G031 ULA has 10 total ports. They are fully decoded, available via Z80 I/O instructions at $F8-$FF. There are eight write-only functions and two read-only functions. === Square 1 ($F8) > write === 7 bit 0 ..PP PPPP || |||| ++-++++--- Period for first square wave. f<sub>square</sub> = f<sub>ULA</sub> ÷ 1024 ÷ (63-P) ≈ 8739 Hz ÷ (63-P) Where f<sub>ULA</sub> is the 17.897727MHz crystal divided by 2. If P is specified to be 63, it instead si...")
 
 
(25 intermediate revisions by the same user not shown)
Line 1: Line 1:
The µPD65010G031 ULA has 10 total ports. They are fully decoded, available via Z80 I/O instructions at $F8-$FF.
The µPD65010G031 gate array has 10 total ports. They are fully decoded, available via Z80 I/O instructions at $F8-$FF.


There are eight write-only functions and two read-only functions.
There are eight write-only functions and two read-only functions.
Line 10: Line 10:
   ++-++++--- Period for first square wave.
   ++-++++--- Period for first square wave.


f<sub>square</sub> = f<sub>ULA</sub> ÷ 1024 ÷ (63-P) ≈ 8739 Hz ÷ (63-P)
f<sub>square</sub> = f<sub>ASIC</sub> ÷ 1024 ÷ (63-P) ≈ 8739 Hz ÷ (63-P)


Where f<sub>ULA</sub> is the 17.897727MHz crystal divided by 2.
Where f<sub>ASIC</sub> is the 17.897727MHz crystal divided by 2.


If P is specified to be 63, it instead silences the square wave.
The output changes when the current count changes ''to'' 0. This means that:
* P=63 meaning period 0 is silent, and can leave the output in either direction
* P=62 then P=63 will instantly toggle the output
 
All three squares are running off of the same 17478Hz clock, and will change at the same moment as appropriate. This is equivalent to thinking the sound hardware has a sample rate of [crystal divided by 1024].


=== Square 2 ($F9) > write ===
=== Square 2 ($F9) > write ===


Same as Square 1, but 3dB louder.
Same as Square 1, but approximately 3dB louder.


=== Square 3 ($FA) > write ===
=== Square 3 ($FA) > write ===


Same as Square 1, but 6dB louder.
Same as Square 1, but approximately 6dB louder.


=== Unknown ($FB) > write ===
=== Sound control ($FB) > write ===


Existing games write 0, 2, or 3.
7  bit  0
.... ..ES
        ||
        |+--- 0: Normal
        |    1: XOR/ring modulation
        +---- 0: Mute
              1: Sound audible


=== Interrupt controller? ($FC) > write ===
Muting ANDs all above three channels with 0. Writes are still permitted, the period dividers still run.
 
XOR/ring modulation replaces:
* SquareF8.external ← SquareF8.internal XOR SquareF9.internal
* SquareF9.external ← SquareF9.internal XOR SquareFA
* SquareFA is unchanged
 
 
There are highpass filters on the square waves, but in normal operation they're inaudible (their corner frequencies are below the slowest period achievable). Unfortunately, when XOR modulation is enabled that's no longer true.
 
The three channels have first-order highpass filters at:
* SquareF8: 68kΩ · 47nF → 50Hz
* SquareF9: 47kΩ · 47nF → 72Hz
* SquareFA: 33kΩ · 47nF → 103Hz
 
=== Interrupt enable ($FC) > write ===


Existing games write 0, 1, or 3.
Existing games write 0, 1, or 3.


=== Interrupt status? ($FC) < read ===
7  bit  0
.... ..MP
        ||
        |+--- 1: enable prerender IRQ (1/vblank)
        +---- 1: enable matrix scan IRQ (16/vblank)
 
It is known that 0x1C bits have no effect.
 
When enabled, IRQ becomes asserted at pixel 276, immediately after the last pixel of the active area is drawn.
 
If the first active scanline is numbered 0,
* the matrix scan IRQ happens at scanlines 195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255
* the prerender IRQ happens at scanline 255 (the exact same as the last matrix scan IRQ)
 
IRQs do not care if rendering is enabled. The same 16 IRQs will fire regardless.
 
Disabling an interrupt also acknowledges it.
 
=== Interrupt status ($FC) < read ===


  7  bit  0
  7  bit  0
  ZAAA AABC
  ZAAA BBMP
  |||| ||||
  |||| ||||
  |||| |||+-- Unclear. Counts 2 scanlines?
  |||| |||+-- 1: prerender IRQ is cause of interrupt, cleared by write to port $FD
  |||| ||+--- Usually 1?
  |||| ||+--- 1: matrix scan IRQ is cause of interrupt, cleared by read from port $FD
  |+++-++---- Always 0?
  |||| ++---- Player 2 joystick inputs, same as reading from $FD
|+++------- Always 0
  +---------- Always 1 (Probably pulled up by resistor next to Z80)
  +---------- Always 1 (Probably pulled up by resistor next to Z80)


=== GPO ($FD) > write ===
=== GPO ($FD) > write ===
Also acknowledges prerender IRQ.


  7  bit  0
  7  bit  0
Line 48: Line 94:
   ||| ||||
   ||| ||||
   ||| ++++-- 4 general purpose outputs, accessible via both [[Casio PV-1000/Controller port pinout|controller ports]]
   ||| ++++-- 4 general purpose outputs, accessible via both [[Casio PV-1000/Controller port pinout|controller ports]]
   +++------- Strongly implied to exist on the ULA, but not accessible externally
   +++------- Strongly implied to exist on the gate array, but not accessible externally


=== GPI ($FD) < read ===
=== GPI ($FD) < read ===
Also acknowledges Matrix scan IRQ.


  7  bit  0
  7  bit  0
Line 57: Line 105:
  |||| ||++-- 2 general purpose inputs for reading the player 1 joystick
  |||| ||++-- 2 general purpose inputs for reading the player 1 joystick
  |||| ++---- 2 general purpose inputs for reading the player 2 joystick
  |||| ++---- 2 general purpose inputs for reading the player 2 joystick
  |+++------- Always 0. (Strongly implied to exist on the ULA, but grounded there)
  |+++------- Always 0. (Strongly implied to exist on the gate array, but grounded there)
  +---------- Always 1. (Probably pulled up by resistor next to Z80)
  +---------- Always 1. (Probably pulled up by resistor next to Z80)


=== Tilemap address ($FE) > write ===
=== Tilemap and pattern RAM address ($FE) > write ===


  7  bit  0
  7  bit  0
  AAAA AA..
  BBBB AA..
  |||| ||
  |||| ||
  ++++-++---- Address A15-A10 from where to fetch the tilemap.  
  ++++-++---- Address A15-A10 from where to fetch the tilemap.  
            Almost all software write $B8, meaning the ULA fetches tiles from $B802 through $BAFD.
||||        Almost all software write $B8, meaning the gate array fetches tilemap from $B802 through $BAFD.
 
++++------- Address A15-A12 from where to fetch pattern RAM tiles (A11-A10 always 1)
It's not yet confirmed whether the 2 lsbits do nothing at all.
            The common value of $B8 means that gate array fetches data for tiles $E0-$FF from $BC08-$BFFF


=== Display properties ($FF) > write ===
=== Display properties ($FF) > write ===


  7  bit  0
  7  bit  0
  AAAB CDDD
  AAAD FBGR
  |||| ||||
  |||| ||||
  |||| |+++-- Border color. (0=black, 1=red, 2=green, 3=yellow, 4=blue, &c).
  |||| |+++-- Border color. (0=black, 1=red, 2=green, 3=yellow, 4=blue, &c).
  |||| +----- Display disable? (faster Z80?)
  |||| +----- 1: Display disable. (Screen solid border color, faster Z80)
  |||+------- Pattern RAM disable  
  |||+------- Pattern RAM disable  
  |||          (0: Tiles $E0-$FF are fetched from $BC08-$BFFF
  |||          (0: Tiles $E0-$FF are fetched from address specified by port $FE
  |||          1: Tiles $E0-$FF are fetched from normal address)
  |||          1: Tiles $E0-$FF are fetched from address specified by port $FF)
  +++-------- Address A15-A13 from where to fetch patterns
  +++-------- Address A15-A13 from where to fetch patterns
               (0: Patterns are fetched from $0008-$1BFF or -$1FFF
               (0: Patterns are fetched from $0008-$1BFF or -$1FFF
Line 85: Line 133:
               2: starting at $4008 &c
               2: starting at $4008 &c


It's not yet confirmed that the pattern fetch is a full three bits wide. At least ''Dig Dug'' uses both B and the lsbit of AAA.
''Dig Dug'' uses both D and the lsbit of AAA.
 
Enabling the display in the middle of a scanline causes 8 to 16 pixels of noise, specific origin unknown.


Other sources (e.g. [http://www43.tok2.com/home/cmpslv/Pv1000/EnrPV1.htm Enri] refer to the pattern memory as "PCG")
Other sources (e.g. [http://cmpslv2.starfree.jp/Pv1000/EnrPV1.htm Enri]) refer to the pattern memory as "PCG"

Latest revision as of 18:20, 18 July 2024

The µPD65010G031 gate array has 10 total ports. They are fully decoded, available via Z80 I/O instructions at $F8-$FF.

There are eight write-only functions and two read-only functions.

Square 1 ($F8) > write

7  bit  0
..PP PPPP
  || ||||
  ++-++++--- Period for first square wave.

fsquare = fASIC ÷ 1024 ÷ (63-P) ≈ 8739 Hz ÷ (63-P)

Where fASIC is the 17.897727MHz crystal divided by 2.

The output changes when the current count changes to 0. This means that:

  • P=63 meaning period 0 is silent, and can leave the output in either direction
  • P=62 then P=63 will instantly toggle the output

All three squares are running off of the same 17478Hz clock, and will change at the same moment as appropriate. This is equivalent to thinking the sound hardware has a sample rate of [crystal divided by 1024].

Square 2 ($F9) > write

Same as Square 1, but approximately 3dB louder.

Square 3 ($FA) > write

Same as Square 1, but approximately 6dB louder.

Sound control ($FB) > write

7  bit  0
.... ..ES
       ||
       |+--- 0: Normal
       |     1: XOR/ring modulation
       +---- 0: Mute
             1: Sound audible

Muting ANDs all above three channels with 0. Writes are still permitted, the period dividers still run.

XOR/ring modulation replaces:

  • SquareF8.external ← SquareF8.internal XOR SquareF9.internal
  • SquareF9.external ← SquareF9.internal XOR SquareFA
  • SquareFA is unchanged


There are highpass filters on the square waves, but in normal operation they're inaudible (their corner frequencies are below the slowest period achievable). Unfortunately, when XOR modulation is enabled that's no longer true.

The three channels have first-order highpass filters at:

  • SquareF8: 68kΩ · 47nF → 50Hz
  • SquareF9: 47kΩ · 47nF → 72Hz
  • SquareFA: 33kΩ · 47nF → 103Hz

Interrupt enable ($FC) > write

Existing games write 0, 1, or 3.

7  bit  0
.... ..MP
       ||
       |+--- 1: enable prerender IRQ (1/vblank) 
       +---- 1: enable matrix scan IRQ (16/vblank)

It is known that 0x1C bits have no effect.

When enabled, IRQ becomes asserted at pixel 276, immediately after the last pixel of the active area is drawn.

If the first active scanline is numbered 0,

  • the matrix scan IRQ happens at scanlines 195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255
  • the prerender IRQ happens at scanline 255 (the exact same as the last matrix scan IRQ)

IRQs do not care if rendering is enabled. The same 16 IRQs will fire regardless.

Disabling an interrupt also acknowledges it.

Interrupt status ($FC) < read

7  bit  0
ZAAA BBMP
|||| ||||
|||| |||+-- 1: prerender IRQ is cause of interrupt, cleared by write to port $FD
|||| ||+--- 1: matrix scan IRQ is cause of interrupt, cleared by read from port $FD
|||| ++---- Player 2 joystick inputs, same as reading from $FD
|+++------- Always 0
+---------- Always 1 (Probably pulled up by resistor next to Z80)

GPO ($FD) > write

Also acknowledges prerender IRQ.

7  bit  0
.AAA BBBB
 ||| ||||
 ||| ++++-- 4 general purpose outputs, accessible via both controller ports
 +++------- Strongly implied to exist on the gate array, but not accessible externally

GPI ($FD) < read

Also acknowledges Matrix scan IRQ.

7  bit  0
ZAAA BBCC
|||| ||||
|||| ||++-- 2 general purpose inputs for reading the player 1 joystick
|||| ++---- 2 general purpose inputs for reading the player 2 joystick
|+++------- Always 0. (Strongly implied to exist on the gate array, but grounded there)
+---------- Always 1. (Probably pulled up by resistor next to Z80)

Tilemap and pattern RAM address ($FE) > write

7  bit  0
BBBB AA..
|||| ||
++++-++---- Address A15-A10 from where to fetch the tilemap. 
||||        Almost all software write $B8, meaning the gate array fetches tilemap from $B802 through $BAFD.
++++------- Address A15-A12 from where to fetch pattern RAM tiles (A11-A10 always 1)
            The common value of $B8 means that gate array fetches data for tiles $E0-$FF from $BC08-$BFFF

Display properties ($FF) > write

7  bit  0
AAAD FBGR
|||| ||||
|||| |+++-- Border color. (0=black, 1=red, 2=green, 3=yellow, 4=blue, &c).
|||| +----- 1: Display disable. (Screen solid border color, faster Z80)
|||+------- Pattern RAM disable 
|||          (0: Tiles $E0-$FF are fetched from address specified by port $FE
|||           1: Tiles $E0-$FF are fetched from address specified by port $FF)
+++-------- Address A15-A13 from where to fetch patterns
             (0: Patterns are fetched from $0008-$1BFF or -$1FFF
              1: starting at $2008
              2: starting at $4008 &c

Dig Dug uses both D and the lsbit of AAA.

Enabling the display in the middle of a scanline causes 8 to 16 pixels of noise, specific origin unknown.

Other sources (e.g. Enri) refer to the pattern memory as "PCG"