Difference between revisions of "How to access the PSG via PPI"

From CPCWiki - THE Amstrad CPC encyclopedia!
Jump to: navigation, search
(Reading to the selected PSG register: section title was missing (format))
 
(17 intermediate revisions by 4 users not shown)
Line 1: Line 1:
PSG Stands for '''Programmable Sound Generator'''
+
The [[Amstrad CPC]], CPC+ and [[KC Compact]] use a AY-3-8912 Programmable sound generator (referred to as [[PSG]] in this document), operating at 1Mhz. This document will describe it's role in these systems. To understand the full functions please read the [[Datasheet AY-8913|datasheet]].
  
The Amstrad CPC,CPC+ and KC Compact use a AY-3-8912 Programmable sound generator (referred to as PSG in this document), operating at 1Mhz. This document will describe it's role in these systems. To understand the full functions please read the datasheet.
+
== Role of the AY-3-8912 ==
  
 
In these systems it is accessed through and connected to the [[8255]] PPI. (You should understand the operation of the 8255 if you wish to access the PSG)  
 
In these systems it is accessed through and connected to the [[8255]] PPI. (You should understand the operation of the 8255 if you wish to access the PSG)  
Line 11: Line 11:
 
The PSG function, defined by the BC1,BC2 and BDIR signals, is controlled by bit 7 and bit 6 of PPI Port C.  
 
The PSG function, defined by the BC1,BC2 and BDIR signals, is controlled by bit 7 and bit 6 of PPI Port C.  
  
PSG signals:
+
=== PSG function selection ===
  
 
{|{{Prettytable|width: 700px; font-size: 2em;}}
 
{|{{Prettytable|width: 700px; font-size: 2em;}}
|''PPI Port C Bit''||''PSG Signal''
+
|colspan=2|''PPI Port C Bits''||rowspan=2|''PSG Function''
 
|-
 
|-
|7||BDIR
+
|Bit7 BDIR||Bit6 BC1
|-
+
|6||BC1
+
|-
+
|}
+
 
+
PSG function selection:
+
 
+
{|{{Prettytable|width: 700px; font-size: 2em;}}
+
|''PPI Port C Bit''||||''PSG Function''
+
|-
+
|7||6
+
 
|-
 
|-
 
|0||0||Inactive  
 
|0||0||Inactive  
Line 38: Line 27:
 
|}
 
|}
  
Note:
+
=== Note ===
  
 
The "inactive" mode must be used between function changes.
 
The "inactive" mode must be used between function changes.
Line 44: Line 33:
 
If it is not used then there will be problems with the program on the CPC+. See the document about CPC+ extra information for a description of this.  
 
If it is not used then there will be problems with the program on the CPC+. See the document about CPC+ extra information for a description of this.  
  
The "inactive" mode can be used to prevent register corruption between changing modes.  
+
The "inactive" mode can be used to prevent register corruption between changing modes.
  
 
== Programming the PSG ==
 
== Programming the PSG ==
Line 71: Line 60:
 
The data will then be written into the register.  
 
The data will then be written into the register.  
  
Reading from the selected PSG register
+
=== Reading from the selected PSG register ===
  
 
To read data from the PSG, PPI Port A must be operating as input. (See the document on the 8255 to see how to do this)  
 
To read data from the PSG, PPI Port A must be operating as input. (See the document on the 8255 to see how to do this)  
Line 79: Line 68:
 
set bit 7 to "0" and bit 6 to "1" of PPI Port C  
 
set bit 7 to "0" and bit 6 to "1" of PPI Port C  
 
read data from PPI Port A,  
 
read data from PPI Port A,  
The register data is available at PPI Port A.  
+
The register data is available at PPI Port A.
  
Notes
+
=== Notes ===
  
 
If the tone period is in the range 0-4 I can not hear any tone output.  
 
If the tone period is in the range 0-4 I can not hear any tone output.  
Programming Examples
+
 
Reading a value from a PSG register.  
+
== Programming Examples ==
 +
 
 +
=== Reading a value from a PSG register. ===
 +
 
 
This routine can be used to read data from a PSG register.  
 
This routine can be used to read data from a PSG register.  
  
Line 99: Line 91:
  
 
.read_from_psg
 
.read_from_psg
ld b,&f4            ;} Setup register index on PPI port A
+
ld b,&f4            ; Setup register index on PPI port A
out (c),c               ;}
+
out (c),c           ;
  
ld bc,&f6c0           ;} Tell PSG to select register using data on PPI port A
+
ld bc,&f6c0         ; Tell PSG to select register using data on PPI port A
out (c),c               ;}
+
out (c),c           ;
  
ld bc,&f600           ;} Put PSG into inactive state
+
ld bc,&f600         ; Put PSG into inactive state
out (c),c
+
out (c),c           ;
  
                        ;** Set PPI port A to input mode. **
+
                    ; ** Set PPI port A to input mode. **
 
ld b,&f7            ; 8255 PPI Control
 
ld b,&f7            ; 8255 PPI Control
ld c,%10010010         ; mode and port configuration
+
ld c,%10010010     ; mode and port configuration
out (c),c               ; Port A input, Port B input, Port C output
+
out (c),c           ; Port A input, Port B input, Port C output
                        ; All operating in mode 0. (see Programming
+
                    ; All operating in mode 0. (see Programming
                        ; 8255 PPI)
+
                    ; 8255 PPI)
  
ld bc,&f640           ;} Tell PSG to put the data of the selected register to PPI port A to
+
ld bc,&f640         ; Tell PSG to put the data of the selected register to PPI port A to
out (c),c               ;}
+
out (c),c           ;
  
ld b,&f4            ;} Read data from PPI port A
+
ld b,&f4            ; Read data from PPI port A
in a,(c)               ;}
+
in a,(c)           ;
  
                        ;** Set PPI port A to output mode. *
+
                    ; ** Set PPI port A to output mode. *
ld b,&f7            ;8255 PPI control
+
ld b,&f7            ; 8255 PPI control
 
ld c,%10000010
 
ld c,%10000010
out (c),c               ;Port A output, Port B input, Port C output
+
out (c),c           ; Port A output, Port B input, Port C output
  
ld bc,&f600           ;} Return PSG to inactive mode.
+
ld bc,&f600         ; Return PSG to inactive mode.
out (c),c               ;}
+
out (c),c           ;
 
ret
 
ret
 +
</pre>
 +
 +
=== Writing to a PSG register ===
  
=== Writing to a PSG register. ===
 
 
This routine can be used to write to registers on the PSG. C contains the index of the PSG register to write. A contains the data to write to the PSG register.  
 
This routine can be used to write to registers on the PSG. C contains the index of the PSG register to write. A contains the data to write to the PSG register.  
  
 +
<pre>
 
;; entry conditions:
 
;; entry conditions:
 
;; C = register number
 
;; C = register number
Line 142: Line 137:
  
 
.write_to_psg
 
.write_to_psg
ld b,&f4            ;} setup PSG register number on PPI port A
+
ld b,&f4            ; setup PSG register number on PPI port A
out (c),c               ;}
+
out (c),c           ;
  
ld bc,&f6c0           ;} Tell PSG to select register from data on PPI port A
+
ld bc,&f6c0         ; Tell PSG to select register from data on PPI port A
out (c),c               ;}
+
out (c),c           ;
  
ld bc,&f600           ;} Put PSG into inactive state.
+
ld bc,&f600         ; Put PSG into inactive state.
out (c),c               ;}
+
out (c),c           ;
  
ld b,&f4            ;} setup register data on PPI port A
+
ld b,&f4            ; setup register data on PPI port A
out (c),a               ;}
+
out (c),a           ;
  
ld bc,&f680           ;} Tell PSG to write data on PPI port A into selected register
+
ld bc,&f680         ; Tell PSG to write data on PPI port A into selected register
out (c),c               ;}
+
out (c),c           ;
  
ld bc,&f600           ;} Put PSG into inactive state
+
ld bc,&f600         ; Put PSG into inactive state
out (c),c               ;}
+
out (c),c           ;
 
ret
 
ret
 
</pre>
 
</pre>
  
 
+
== Resources ==
 +
* [[Media:Ay3-891x.pdf|AY-3-891x datasheet]]
  
 
== Links ==
 
== Links ==
Line 179: Line 175:
  
 
[[Category:Stub]]
 
[[Category:Stub]]
[[Category:Hardware]]
+
[[Category:Programming]]
[[Category:Music and sound]]
+
[[Category:Music and sound| ]]
[[Category:Video contents]]
+
[[Category:Video contents]][[Category:CPC Internal Components]]

Latest revision as of 18:48, 10 February 2021

The Amstrad CPC, CPC+ and KC Compact use a AY-3-8912 Programmable sound generator (referred to as PSG in this document), operating at 1Mhz. This document will describe it's role in these systems. To understand the full functions please read the datasheet.

Role of the AY-3-8912

In these systems it is accessed through and connected to the 8255 PPI. (You should understand the operation of the 8255 if you wish to access the PSG)

As well as generating sound, the PSG is also used to scan the keyboard matrix to read the state of the keyboard and joysticks. The selected keyboard matrix line data is available at PSG I/O Port A. (The selected matrix line is programmed to PPI Port C bits 3-0. See the document about scanning the keyboard matrix for a full description of the algorithm involved).

The databus of the PSG is connected to PPI Port A. Data is read from/written to the PSG through this port.

The PSG function, defined by the BC1,BC2 and BDIR signals, is controlled by bit 7 and bit 6 of PPI Port C.

PSG function selection

PPI Port C Bits PSG Function
Bit7 BDIR Bit6 BC1
0 0 Inactive
0 1 Read from selected PSG register.When function is set, the PSG will make the register data available to PPI Port A
1 0 Write to selected PSG register. When set, the PSG will take the data at PPI Port A and write it into the selected PSG register
1 1 Select PSG register. When set, the PSG will take the data at PPI Port A and select a register

Note

The "inactive" mode must be used between function changes.

If it is not used then there will be problems with the program on the CPC+. See the document about CPC+ extra information for a description of this.

The "inactive" mode can be used to prevent register corruption between changing modes.

Programming the PSG

The PSG has 16 internal registers and these control the operation. Before a register can be read from/written to it must be selected.

Register selection

To write data to the PSG, PPI Port A must be operating as output. (See the document on the 8255 to see how to do this)

To select a register, write the register number into PPI Port A, then set bit 7 and bit 6 of Port C to "1".

The register will now be selected and the user can read from or write to it.

The register will remain selected until another is chosen.

Writing to the selected PSG register

To write data to the PSG, PPI Port A must be operating as output. (See the document on the 8255 to see how to do this)

To write data into the selected PSG register:

write data to PPI Port A,

set bit 7 to "1" and bit 6 to "0" of PPI Port C The data will then be written into the register.

Reading from the selected PSG register

To read data from the PSG, PPI Port A must be operating as input. (See the document on the 8255 to see how to do this)

To read data from the selected register:

set bit 7 to "0" and bit 6 to "1" of PPI Port C read data from PPI Port A, The register data is available at PPI Port A.

Notes

If the tone period is in the range 0-4 I can not hear any tone output.

Programming Examples

Reading a value from a PSG register.

This routine can be used to read data from a PSG register.

;; entry conditions:
;; c = register index
;; exit conditions:
;; a = register data
;; b,c,f corrupt
;; PPI port A is returned to output
;; assumptions:
;; PPI port A is set to output, PPI port C is set to output.

.read_from_psg
ld b,&f4            ; Setup register index on PPI port A
out (c),c           ;

ld bc,&f6c0         ; Tell PSG to select register using data on PPI port A
out (c),c           ;

ld bc,&f600         ; Put PSG into inactive state
out (c),c           ;

                    ; ** Set PPI port A to input mode. **
ld b,&f7            ; 8255 PPI Control
ld c,%10010010      ; mode and port configuration
out (c),c           ; Port A input, Port B input, Port C output
                    ; All operating in mode 0. (see Programming
                    ; 8255 PPI)

ld bc,&f640         ; Tell PSG to put the data of the selected register to PPI port A to
out (c),c           ;

ld b,&f4            ; Read data from PPI port A
in a,(c)            ;

                    ; ** Set PPI port A to output mode. *
ld b,&f7            ; 8255 PPI control
ld c,%10000010
out (c),c           ; Port A output, Port B input, Port C output

ld bc,&f600         ; Return PSG to inactive mode.
out (c),c           ;
ret

Writing to a PSG register

This routine can be used to write to registers on the PSG. C contains the index of the PSG register to write. A contains the data to write to the PSG register.

;; entry conditions:
;; C = register number
;; A = register data
;; exit conditions:
;; b,C,F corrupt
;; assumptions:
;; PPI port A and PPI port C are setup in output mode.

.write_to_psg
ld b,&f4            ; setup PSG register number on PPI port A
out (c),c           ;

ld bc,&f6c0         ; Tell PSG to select register from data on PPI port A
out (c),c           ;

ld bc,&f600         ; Put PSG into inactive state.
out (c),c           ;

ld b,&f4            ; setup register data on PPI port A
out (c),a           ;

ld bc,&f680         ; Tell PSG to write data on PPI port A into selected register
out (c),c           ;

ld bc,&f600         ; Put PSG into inactive state
out (c),c           ;
ret

Resources

Links

Wikipedia on the PSG

Video

Introduction to the AY-3-8912

{{#ev:youtube|eSfoQKiXo5g|200}}

Amstrad CPC6128 playing MYM files

{{#ev:youtube|PTslbiAbb5A|200}}