|
|
|
@ -4,8 +4,12 @@ |
|
|
|
; |
|
|
|
;====================================================================== |
|
|
|
; |
|
|
|
; @3.579545 OCTAVE RANGE IS 2 - 7 (Bb2/A#2 .. A7) |
|
|
|
; @4.000000 OCTAVE RANGE IS 2 - 7 (B2 .. A7) |
|
|
|
; AY-3-8910 & YM2149 PSG CHIPS NEED AN INPUT CLOCK FREQUENCY OF |
|
|
|
; NO MORE THAN 2 MHZ. THE CLOSEST THING THERE IS TO A STANDARD |
|
|
|
; IS THE MSX FREQ OF 1.7897725 MHZ. |
|
|
|
; |
|
|
|
; @1.7897725 OCTAVE RANGE IS 2 - 7 (Bb2/A#2 .. A7) |
|
|
|
; @2.0000000 OCTAVE RANGE IS 2 - 7 (B2 .. A7) |
|
|
|
; |
|
|
|
AY_RCSND .EQU 0 ; 0 = EB MODULE, 1=MF MODULE |
|
|
|
; |
|
|
|
@ -14,7 +18,6 @@ AY_RSEL .EQU $9A |
|
|
|
AY_RDAT .EQU $9B |
|
|
|
AY_RIN .EQU AY_RSEL |
|
|
|
AY_ACR .EQU $9C |
|
|
|
AY_CLK .SET 3579545 ; MSX NTSC COLOUR BURST FREQ = 315/88 |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (AYMODE == AYMODE_N8) |
|
|
|
@ -53,7 +56,6 @@ AY_RSEL .EQU $A0 |
|
|
|
AY_RDAT .EQU $A1 |
|
|
|
AY_RIN .EQU AY_RSEL |
|
|
|
AY_ACR .EQU $A2 |
|
|
|
AY_CLK .SET 3579545 ; MSX NTSC COLOUR BURST FREQ = 315/88 |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
;====================================================================== |
|
|
|
@ -92,14 +94,16 @@ AY_IDAT .EQU 0 ; NO INSTANCE DATA ASSOCIATED WITH THIS DEVICE |
|
|
|
; |
|
|
|
AY_TONECNT .EQU 3 ; COUNT NUMBER OF TONE CHANNELS |
|
|
|
AY_NOISECNT .EQU 1 ; COUNT NUMBER OF NOISE CHANNELS |
|
|
|
;; |
|
|
|
;#IF (AY_CLK > 3579545) ; DEPENDING ON THE |
|
|
|
;AY_SCALE .EQU 2 ; INPUT CLOCK FREQUENCY |
|
|
|
;#ELSE ; PRESCALE THE TONE PERIOD |
|
|
|
;AY_SCALE .EQU 3 ; DATA TO MAINTAIN MAXIMUM |
|
|
|
;#ENDIF ; RANGE AND ACCURACY |
|
|
|
; |
|
|
|
#IF (AY_CLK > 3579545) ; DEPENDING ON THE |
|
|
|
AY_SCALE .EQU 2 ; INPUT CLOCK FREQUENCY |
|
|
|
#ELSE ; PRESCALE THE TONE PERIOD |
|
|
|
AY_SCALE .EQU 3 ; DATA TO MAINTAIN MAXIMUM |
|
|
|
#ENDIF ; RANGE AND ACCURACY |
|
|
|
; |
|
|
|
AY_RATIO .EQU (AY_CLK * 100) / (16 >> AY_SCALE) |
|
|
|
.ECHO "SN76489 CLOCK: " |
|
|
|
.ECHO SN7CLK |
|
|
|
.ECHO "\n" |
|
|
|
; |
|
|
|
#INCLUDE "audio.inc" |
|
|
|
; |
|
|
|
@ -306,38 +310,8 @@ AY_VOLUME: |
|
|
|
;====================================================================== |
|
|
|
; |
|
|
|
AY_NOTE: |
|
|
|
AUDTRACE(AYT_NOTE) |
|
|
|
AUDTRACE_HL |
|
|
|
AUDTRACE_CR |
|
|
|
; |
|
|
|
; CALL PRTHEXWORDHL |
|
|
|
; CALL PC_COLON |
|
|
|
; |
|
|
|
LD DE, AY3NOTETBL ; ON ENTRY HL IS THE NOTE TO PLAY |
|
|
|
PUSH DE ; AND DE IS THE START OF NOTE TABLE |
|
|
|
LD DE, 48 ; LOAD DE WITH NOTE TABLE SIZE |
|
|
|
CALL DIV16 ; AND CALCULATE OCTAVE COUNT IN BC |
|
|
|
; |
|
|
|
ADD HL, HL ; HL IS THE REMAINDER FROM ABOVE DIVISION (0-47) AND THE NOTE |
|
|
|
POP DE ; TO PLAY IN THE OCTAVE. ADD IT TO THE START OF THE NOTE TABLE |
|
|
|
ADD HL, DE ; TO POINT TO THE PERIOD FOR THE NOTE WE WANT TO PLAY. |
|
|
|
; |
|
|
|
LD A, (HL) ; HL POINT TO CURRENT PERIOD COUNT WE WANT TO PLAY |
|
|
|
INC HL ; SO LOAD PERIOD COUNT FROM NOTE TABLE INTO HL |
|
|
|
LD H, (HL) ; SO WE CAN UPDATE IT FOR THE REQUIRED OCTAVE |
|
|
|
LD L, A |
|
|
|
; |
|
|
|
;LD A,AY_SCALE - 1 ; THE NOTE TABLE PERIOD DATA HAS BEEN |
|
|
|
LD A,AY_SCALE ; THE NOTE TABLE PERIOD DATA HAS BEEN |
|
|
|
ADD A,C ; PRESCALED TO MAINTAIN RANGE SO ALLOW |
|
|
|
LD B,A ; FOR THIS WHEN CHANGING OCTAVE |
|
|
|
AY_NOTE1: |
|
|
|
SRL H ; ADJUST THE PERIOD DATA |
|
|
|
RR L ; FOR THE DESIRED OCTAVE |
|
|
|
DJNZ AY_NOTE1 ; FALL THROUGH TO SET PERIOD AND RANGE CHECK |
|
|
|
; |
|
|
|
; CALL PRTHEXWORDHL |
|
|
|
; CALL NEWLINE |
|
|
|
LD DE, AY3NOTETBL |
|
|
|
CALL AUD_NOTE ; RETURNS PERIOD IN HL, FALL THRU |
|
|
|
; |
|
|
|
;====================================================================== |
|
|
|
; SOUND DRIVER FUNCTION - PERIOD |
|
|
|
@ -347,21 +321,22 @@ AY_PERIOD: |
|
|
|
AUDTRACE(AYT_PERIOD) |
|
|
|
AUDTRACE_HL |
|
|
|
AUDTRACE_CR |
|
|
|
|
|
|
|
LD A, H ; IF ZERO - ERROR |
|
|
|
; |
|
|
|
LD A,H ; IF ZERO - ERROR |
|
|
|
OR L |
|
|
|
JR Z, AY_PERIOD1 |
|
|
|
JR Z,AY_PERIOD1 |
|
|
|
; |
|
|
|
LD A, H ; MAXIMUM TONE PERIOD IS 12-BITS |
|
|
|
LD A,H ; MAXIMUM TONE PERIOD IS 12-BITS |
|
|
|
AND 11110000B ; ALLOWED RANGE IS 0001-0FFF (4095) |
|
|
|
JR NZ, AY_PERIOD1 ; RETURN NZ IF NUMBER TOO LARGE |
|
|
|
LD (AY_PENDING_PERIOD), HL ; SAVE AND RETURN SUCCESSFUL |
|
|
|
JR NZ,AY_PERIOD1 ; RETURN NZ IF NUMBER TOO LARGE |
|
|
|
LD (AY_PENDING_PERIOD),HL ; SAVE AND RETURN SUCCESSFUL |
|
|
|
XOR A ; SET SUCCESS |
|
|
|
RET |
|
|
|
; |
|
|
|
AY_PERIOD1: |
|
|
|
LD A, $FF ; REQUESTED PERIOD IS LARGER |
|
|
|
LD (AY_PENDING_PERIOD), A ; THAN THE DEVICE CAN SUPPORT |
|
|
|
LD (AY_PENDING_PERIOD+1), A; SO SET PERIOD TO FFFF |
|
|
|
LD HL,$FFFF ; REQUESTED PERIOD IS LARGER |
|
|
|
LD (AY_PENDING_PERIOD),HL ; THAN PSG CAN SUPPORT, SO |
|
|
|
OR $FF ; SET PERIOD TO $FFFF |
|
|
|
RET ; AND RETURN FAILURE |
|
|
|
; |
|
|
|
;====================================================================== |
|
|
|
@ -612,10 +587,32 @@ AYT_REGWR .DB "\r\nOUT AY-3-8910 $" |
|
|
|
; QUARTER TONE FREQUENCY TABLE |
|
|
|
;====================================================================== |
|
|
|
; |
|
|
|
; THE FREQUENCY BY QUARTER TONE STARTING AT A0# OCTAVE 0 |
|
|
|
; USED TO MAP EACH OCTAVE (DIV BY 2 TO JUMP AN OCTAVE UP) |
|
|
|
; FIRST PLAYABLE NOTE WILL BE 0 |
|
|
|
; ASSUMING A CLOCK OF 1843200 THIS MAPS TO A0# |
|
|
|
; THE FOLLOWING TABLE MAPS A FULL OCTAVE OF QUARTER-NOTES |
|
|
|
; STARTING AT A# IN OCTAVE 0 TO THE CORRESPONDING PERIOD |
|
|
|
; VALUE TO USE ON THE PSG TO ACHIEVE THE DESIRED NOTE FREQUENCY. |
|
|
|
; |
|
|
|
; THE FREQUENCY PRODUCED BY THE AY-3-8910 IS: |
|
|
|
; FREQ = CLOCK / 16 / PERIOD |
|
|
|
; |
|
|
|
; SO, TO MAP A DESIRED FREQUENCY TO A PERIOD, WE USE: |
|
|
|
; PERIOD = CLOCK / 16 / FREQ |
|
|
|
; |
|
|
|
; IN ORDER TO IMPROVE THE RESOLUTION OF THE FREQUENCY |
|
|
|
; VALUE USED, WE ALSO MULTPLY BOTH SIDES OF THE EQUATION |
|
|
|
; BY 100: |
|
|
|
; PERIOD * 100 = (CLOCK / 16 / FREQ) * 100 |
|
|
|
; |
|
|
|
; THE RESULTING PERIOD VALUE CAN BE REPEATEDLY HALVED |
|
|
|
; TO TO JUMP UP AS MANY OCTAVES AS DESIRED. |
|
|
|
; |
|
|
|
; THE FINAL VALUE IS SHIFTED BY AUD_SCALE BITS |
|
|
|
; IN ORDER TO IMPROVE THE RESOLUTION. THIS FINAL SHIFT |
|
|
|
; IS REMOVED WHEN IN THE AY_NOTE ROUTINE. |
|
|
|
; |
|
|
|
; ASSUMING A CLOCK OF 1.7897725 MHZ, THE FIRST PLAYABLE |
|
|
|
; NOTE WILL BE A0#/B0b (HBIOS NOTE CODE 0). |
|
|
|
; |
|
|
|
AY_RATIO .EQU (AY_CLK * 100) / (16 >> AUD_SCALE) |
|
|
|
; |
|
|
|
AY3NOTETBL: |
|
|
|
.DW AY_RATIO / 2913 ; A0#/B0b 178977250 / 2913 = 61440; PROOF: 61440 >> 3 = 7680, 3579545 / 7680 / 16 = 29.13 |
|
|
|
|