    ;; This source is part of the AY-3-8912 PSG additional notes document
    ;; and shows:
    ;;
    ;; when port B is set to input, the input data to the port is 0x0ff.
    ;;
    ;; This code is designed for port B only.
    ;;
    ;; 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

    ;; firmware function to set x,y coordinate of text cursor
    .txt_set_cursor	equ &bb75

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

    ;;-------------------------------------------------------------------------------
    ;; set port B to input
    ld c,7								;; PSG mixer register
    ld a,%00111111						;; port A input, port A output
    									;; disable noise for channels A,B and C
    									;; disable tone for channels A,B and C
    call write_reg

    ;; enable interrupts
    ei

    ;;-------------------------------------------------------------------------------
    ;; loop and display register 15 contents on the screen.

    .loop
    ;; set position of text cursor
    ld h,1
    ld l,1
    call txt_set_cursor

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

    ;; read PSG register 15
    ld c,15
    call read_reg

    ei

    ;; display contents of register A in hex on the screen
    call print_hex_number
    jp loop

    ;;-------------------------------------------------------------------------------
    ;; display a number as hex
    ;;
    ;; Entry Conditions:
    ;;
    ;; A = number (0-255)
    ;;
    .print_hex_number
    push af

    ;; transfer upper nibble into lower nibble
    rrca
    rrca
    rrca
    rrca
    ;; display nibble
    call print_digit
    pop af
    ;; display lower nibble

    ;; print a hex digit on the screen
    .print_digit
    ;; mask off lower bits 3..0
    and &f
    ;; convert number (0-15) to ASCII character "0","1"..."9","A"..."F"
    add a,"0"
    cp "0"+10
    jr c,pd2
    add a,"A"-"0"-10
    .pd2
    ;; display ASCII char on screen
    jp txt_output

    ;;------------------------------------------------
    ;; 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