Difference between revisions of "Programming:Source code to show it is possible to store data in PSG register 14 and 15 even if the port has been set to input"
From CPCWiki - THE Amstrad CPC encyclopedia!
(No difference)
|
Revision as of 03:14, 15 March 2007
;; This source is part of the AY-3-8912 PSG additional notes document ;; and shows that it is possible to change the output latch data ;; when the corresponding port has been set to input. ;; ;; Example 1 showed that it is possible to write any 8-bit data to the output latch ;; and read it back. The test used port B as an example. ;; ;; ;; This example will setup a initial value in the output latch, set the port to input, ;; then attempt to write to the output latch. If the data has changed, then it is possible ;; to change the output latch when the port is set to input. ;; To read the output latch, we must set the port to output mode. ;; The code can be adjusted (as indicated below) to select either port ;; A or port B. ;; ;; Note: This test relies on the following facts: ;; - the input to port B is always &ff. ;; - the input to port A is &ff if NO key is pressed ;; ;; 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. ;; this is the index of the PSG port register to test ;; (14 for PSG port A, 15 for PSG port B) ;; comment this line to test port A ;; uncomment this line to test port B .psg_port_register equ 15 ;; comment this line to test port B ;; uncomment this line to test port A ;;.psg_port_register equ 14 ;; comment this line to test port A ;; uncomment this line to test port B .psg_port_mixer_enable equ %10000000 ;; comment this line to test port B ;; uncomment this line to test port A ;;.psg_port_mixer_enable equ %01000000 org &8000 ;; disable interrupts ;; (do not let CPC firmware effect this test) di ;;------------------------------------------------------------------------------- ;; set port to output ld c,7 ;; PSG mixer register ld a,%00111111 ;; port A input, port B output ;; disable noise for channels A,B and C ;; disable tone for channels A,B and C or psg_port_mixer_enable ;; set port A or B (depending on setting ;; of psg_port_mixer_enable) to output call write_reg ;;------------------------------------------------------------------------------- ;; write &ff into output latch of port. From example 1 we have proved that this ;; will store data into the output latch. ld c,psg_port_register ld a,&ff call write_reg ;;------------------------------------------------------------------------------- ;; set port to input ld c,7 ;; PSG mixer register ld a,%00111111 ;; port A input, port B output ;; disable noise for channels A,B and C ;; disable tone for channels A,B and C call write_reg ;;------------------------------------------------------------------------------- ;; write 10 into output latch of port. If the data is written to the output latch, ;; then it will change from &ff (the value written above) to 10 (the new value). ld c,psg_port_register ld a,10 call write_reg ;;------------------------------------------------------------------------------- ;; set port to output ld c,7 ld a,%00111111 or psg_port_mixer_enable call write_reg ;;------------------------------------------------------------------------------- ;; now read the output latch ld c,psg_port_register call read_reg ;; enable interrupts ei ;; display contents of register A as hex call print_hex_number ret ;;------------------------------------------------------------------------------- ;; 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