    ;; This source is part of the AY-3-8912 PSG additional notes document
    ;; and shows:
    ;;
    ;; when a PSG register is written to, and then read back, some bits will always
    ;; be set to 0.
    ;;
    ;; This example is for the Amstrad CPC and also shows how
    ;; to read/write data from the PSG.
    ;;
    ;; This example can be assembled using Maxam or compatible assembler.
    ;;
    ;; assemble, then jump to &8000 to begin
    ;;
    ;; (c) Kevin Thacker 2001,2002
    ;;
    ;; This source is released under the GNU Public License v2.

    org &8000

    ;; firmware function to display ASCII character on the screen at the current
    ;; text cursor location
    .txt_output		equ &bb5a

    ;; list first 14 registers
    ld b,14
    ;; start at register 0
    ld c,0
    .loop
    push bc

    ;; disable interrupts
    ;; (do not let CPC firmware effect this test)
    di

    push bc
    ;; write 0x0ff to the register (attempt to set all bits to "1")
    ld a,&ff
    call write_reg
    pop bc

    ;; read actual register's contents
    call read_reg

    ei

    ;; display number in register A as binary
    call print_binary_number

    ;; display a new-line
    ld a,10
    call txt_output
    ld a,13
    call txt_output

    pop bc
    djnz loop
    ret

    ;;-------------------------------------------------------------------------------
    ;; display a number as a 8-digit binary number
    ;;
    ;; Entry Conditions:
    ;;
    ;; A = number (0-255)
    ;;
    ;; Exit Conditions:
    ;;
    ;; A,B corrupt

    .print_binary_number
    ;; 8 digits in binary number
    ld b,8
    .pbn1
    ;; transfer bit 7 into carry
    rlca
    push af
    ;; convert to ASCII
    ;; 0-> "0" and 1-> "1"
    adc a,"0"
    ;; display digit on the screen
    call txt_output

    pop af
    djnz pbn1
    ret

    ;;------------------------------------------------
    ;; Read from a AY-3-8912 register
    ;;
    ;; Entry conditions:
    ;;
    ;; C = register number
    ;; PPI port A is assumed to be set to output.
    ;; PSG operation is assumed to be "inactive"
    ;;
    ;; Exit conditions:
    ;;
    ;; A = register data
    ;; BC corrupt
    ;;
    ;; This function is compatible with the CPC+.

    .read_reg

    ;; step 1: select register

    ;; write register index to PPI port A
    ld b,&f4
    out (c),c

    ;; set PSG operation -  "select register"
    ld bc,&f6c0
    out (c),c

    ;; set PSG operation -  "inactive"
    ld bc,&f600
    out (c),c

    ;; PPI port A set to input, PPI port B set to input,
    ;; PPI port C (lower) set to output, PPI port C (upper) set to output
    ld bc,&f700+%10010010
    out (c),c

    ;; set PSG operation -  "read register data"
    ld bc,&f640
    out (c),c

    ;; step 2 -  read data from register

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

    ;; PPI port A set to output, PPI port B set to input,
    ;; PPI port C (lower) set to output, PPI port C (upper) set to output
    ld bc,&f700+%10000010
    out (c),c

    ;; set PSG operation -  "inactive"
    ld bc,&f600
    out (c),c
    ret

    ;;------------------------------------------------
    ;; Write to a AY-3-8912 register
    ;;
    ;; Entry conditions:
    ;;
    ;; C = register number
    ;; A = data
    ;; PPI port A is assumed to be set to output.
    ;; PSG operation is assumed to be "inactive"
    ;;
    ;; Exit conditions:
    ;;
    ;; BC corrupt
    ;;
    ;; This function is compatible with the CPC+.

    .write_reg

    ;; step 1 -  select register

    ;; write register index to PPI port A
    ld b,&f4
    out (c),c

    ;; set PSG operation -  "select register"
    ld bc,&f6c0
    out (c),c

    ;; set PSG operation -  "inactive"
    ld bc,&f600
    out (c),c

    ;; step 2 -  write data to register

    ;; write data to PPI port A
    ld b,&f4
    out (c),a

    ;; set PSG operation -  "write data to register"
    ld bc,&f680
    out (c),c

    ;; set PSG operation -  "inactive"
    ld bc,&f600
    out (c),c
    ret