|
|
@ -4,10 +4,11 @@ |
|
|
; |
|
|
; |
|
|
;====================================================================== |
|
|
;====================================================================== |
|
|
; |
|
|
; |
|
|
|
|
|
|
|
|
|
|
|
; @3.579545 OCTAVE RANGE IS 2 - 7 (Bb2/A#2 .. A7) |
|
|
|
|
|
; @4.000000 OCTAVE RANGE IS 2 - 7 (B2 .. A7) |
|
|
|
|
|
; |
|
|
;#include "cfg_state.inc" |
|
|
;#include "cfg_state.inc" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; |
|
|
AY_RCSND .EQU 0 ; 0 = EB MODULE, 1=MF MODULE |
|
|
AY_RCSND .EQU 0 ; 0 = EB MODULE, 1=MF MODULE |
|
|
; |
|
|
; |
|
|
#IF (AYMODE == AYMODE_SCG) |
|
|
#IF (AYMODE == AYMODE_SCG) |
|
|
@ -15,6 +16,7 @@ AY_RSEL .EQU $9A |
|
|
AY_RDAT .EQU $9B |
|
|
AY_RDAT .EQU $9B |
|
|
AY_RIN .EQU AY_RSEL |
|
|
AY_RIN .EQU AY_RSEL |
|
|
AY_ACR .EQU $9C |
|
|
AY_ACR .EQU $9C |
|
|
|
|
|
AY_CLK .SET 3579545 ; MSX NTSC COLOUR BURST FREQ = 315/88 |
|
|
#ENDIF |
|
|
#ENDIF |
|
|
; |
|
|
; |
|
|
#IF (AYMODE == AYMODE_N8) |
|
|
#IF (AYMODE == AYMODE_N8) |
|
|
@ -73,10 +75,13 @@ SBCV2004 .EQU 0 ; USE SBC-V2-004 HALF CLOCK DIVIDER |
|
|
AY_TONECNT .EQU 3 ; COUNT NUMBER OF TONE CHANNELS |
|
|
AY_TONECNT .EQU 3 ; COUNT NUMBER OF TONE CHANNELS |
|
|
AY_NOISECNT .EQU 1 ; COUNT NUMBER OF NOISE CHANNELS |
|
|
AY_NOISECNT .EQU 1 ; COUNT NUMBER OF NOISE CHANNELS |
|
|
; |
|
|
; |
|
|
AY_PHICLK .EQU 3579545 ; MSX NTSC COLOUR BURST FREQ = 315/88 |
|
|
|
|
|
;AY_PHICLK .EQU 3500000 ; ZX SPECTRUM 3.5MHZ |
|
|
|
|
|
;AY_PHICLK .EQU 4000000 ; RETROBREW SCB-SCG |
|
|
|
|
|
AY_RATIO .EQU AY_CLK * 100 / 16 |
|
|
|
|
|
|
|
|
#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) |
|
|
; |
|
|
; |
|
|
#INCLUDE "audio.inc" |
|
|
#INCLUDE "audio.inc" |
|
|
; |
|
|
; |
|
|
@ -96,7 +101,7 @@ AY38910_INIT: |
|
|
CALL PRTHEXBYTE |
|
|
CALL PRTHEXBYTE |
|
|
; |
|
|
; |
|
|
#IF ((AYMODE == AYMODE_SCG) | (AYMODE == AYMODE_N8)) |
|
|
#IF ((AYMODE == AYMODE_SCG) | (AYMODE == AYMODE_N8)) |
|
|
LD A,$FF ; ACTIVATE DEVICEBIT 4 IS AY RESET CONTROL, BIT 3 IS ACTIVE LED |
|
|
|
|
|
|
|
|
LD A,$FF ; ACTIVATE DEVICE BIT 4 IS AY RESET CONTROL, BIT 3 IS ACTIVE LED |
|
|
OUT (AY_ACR),A ; SET INIT AUX CONTROL REG |
|
|
OUT (AY_ACR),A ; SET INIT AUX CONTROL REG |
|
|
#ENDIF |
|
|
#ENDIF |
|
|
; |
|
|
; |
|
|
@ -127,55 +132,50 @@ AY_FND: LD IY, AY_IDAT ; SETUP FUNCTION TABLE |
|
|
LD DE,(AY_R3CHBP*256)+$00 |
|
|
LD DE,(AY_R3CHBP*256)+$00 |
|
|
CALL AY_WRTPSG ; R03 = $00 = XXXX0000 |
|
|
CALL AY_WRTPSG ; R03 = $00 = XXXX0000 |
|
|
; |
|
|
; |
|
|
|
|
|
|
|
|
#IF (SYSTIM != TM_NONE) |
|
|
#IF (SYSTIM != TM_NONE) |
|
|
LD A, TICKFREQ / 3 ; SCHEDULE IN 1/3 SECOND TO TURN OFF SOUND |
|
|
LD A, TICKFREQ / 3 ; SCHEDULE IN 1/3 SECOND TO TURN OFF SOUND |
|
|
LD (AY_TIMTIK), A |
|
|
LD (AY_TIMTIK), A |
|
|
|
|
|
|
|
|
|
|
|
; |
|
|
LD HL, (VEC_TICK + 1) ; GET CUR TICKS VECTOR |
|
|
LD HL, (VEC_TICK + 1) ; GET CUR TICKS VECTOR |
|
|
LD (AY_TIMHOOK), HL ; SAVE IT INTERNALLY |
|
|
LD (AY_TIMHOOK), HL ; SAVE IT INTERNALLY |
|
|
LD HL, AY_TIMER ; INSTALL TIMER HOOK HANDLER |
|
|
LD HL, AY_TIMER ; INSTALL TIMER HOOK HANDLER |
|
|
LD (VEC_TICK + 1), HL |
|
|
LD (VEC_TICK + 1), HL |
|
|
|
|
|
|
|
|
|
|
|
; |
|
|
LD A, $02 ; NOT READY & IN INTERUPT HANDLER |
|
|
LD A, $02 ; NOT READY & IN INTERUPT HANDLER |
|
|
LD (AY_READY), A |
|
|
LD (AY_READY), A |
|
|
|
|
|
|
|
|
#ELSE |
|
|
#ELSE |
|
|
CALL LDELAY ; HALF SECOND DELAY |
|
|
CALL LDELAY ; HALF SECOND DELAY |
|
|
LD E,$00 ; SET VOLUME OFF |
|
|
LD E,$00 ; SET VOLUME OFF |
|
|
CALL AY_SETV ; ON ALL CHANNELS |
|
|
CALL AY_SETV ; ON ALL CHANNELS |
|
|
LD A, $01 ; READY & NOT IN INTERUPT HANDLER |
|
|
LD A, $01 ; READY & NOT IN INTERUPT HANDLER |
|
|
LD (AY_READY), A |
|
|
LD (AY_READY), A |
|
|
|
|
|
|
|
|
#ENDIF |
|
|
#ENDIF |
|
|
; |
|
|
; |
|
|
XOR A ; SUCCESSFULL INIT |
|
|
XOR A ; SUCCESSFULL INIT |
|
|
RET |
|
|
RET |
|
|
|
|
|
|
|
|
|
|
|
; |
|
|
#IF (SYSTIM != TM_NONE) |
|
|
#IF (SYSTIM != TM_NONE) |
|
|
|
|
|
|
|
|
AY_TIMER: |
|
|
AY_TIMER: |
|
|
LD A, (AY_TIMTIK) |
|
|
LD A, (AY_TIMTIK) |
|
|
DEC A |
|
|
DEC A |
|
|
LD (AY_TIMTIK), A |
|
|
LD (AY_TIMTIK), A |
|
|
JR NZ, AY_TIMER1 |
|
|
JR NZ, AY_TIMER1 |
|
|
|
|
|
|
|
|
|
|
|
; |
|
|
LD E,$00 ; SET VOLUME OFF |
|
|
LD E,$00 ; SET VOLUME OFF |
|
|
CALL AY_SETV ; ON ALL CHANNELS |
|
|
CALL AY_SETV ; ON ALL CHANNELS |
|
|
LD A, $01 ; READY & NOT IN INTERUPT HANDLER |
|
|
LD A, $01 ; READY & NOT IN INTERUPT HANDLER |
|
|
LD (AY_READY), A |
|
|
LD (AY_READY), A |
|
|
|
|
|
|
|
|
|
|
|
; |
|
|
LD DE, AY_TIMER ; MAKE AY_TIMER A NO_OP HANDLER |
|
|
LD DE, AY_TIMER ; MAKE AY_TIMER A NO_OP HANDLER |
|
|
LD HL, AY_TIMER1 |
|
|
LD HL, AY_TIMER1 |
|
|
LD BC, 3 |
|
|
LD BC, 3 |
|
|
LDIR |
|
|
LDIR |
|
|
|
|
|
|
|
|
|
|
|
; |
|
|
AY_TIMER1: |
|
|
AY_TIMER1: |
|
|
JP 0 ; OVERWRITTEN WITH NEXT HANDLER |
|
|
JP 0 ; OVERWRITTEN WITH NEXT HANDLER |
|
|
AY_TIMHOOK: .EQU $ - 2 |
|
|
AY_TIMHOOK: .EQU $ - 2 |
|
|
|
|
|
|
|
|
AY_TIMTIK .DB 0 ; COUNT DOWN TO FINISH BOOT BEEP |
|
|
AY_TIMTIK .DB 0 ; COUNT DOWN TO FINISH BOOT BEEP |
|
|
|
|
|
|
|
|
#ENDIF |
|
|
#ENDIF |
|
|
; |
|
|
; |
|
|
;====================================================================== |
|
|
;====================================================================== |
|
|
@ -185,7 +185,7 @@ AY_TIMTIK .DB 0 ; COUNT DOWN TO FINISH BOOT BEEP |
|
|
AY_INIT: |
|
|
AY_INIT: |
|
|
LD DE,(AY_R7ENAB*256)+$F8 ; SET MIXER CONTROL / IO ENABLE. $F8 - 11 111 000 |
|
|
LD DE,(AY_R7ENAB*256)+$F8 ; SET MIXER CONTROL / IO ENABLE. $F8 - 11 111 000 |
|
|
JP AY_WRTPSG ; I/O PORTS = OUTPUT, NOISE CHANNEL C, B, A DISABLE, TONE CHANNEL C, B, A ENABLE |
|
|
JP AY_WRTPSG ; I/O PORTS = OUTPUT, NOISE CHANNEL C, B, A DISABLE, TONE CHANNEL C, B, A ENABLE |
|
|
|
|
|
|
|
|
|
|
|
; |
|
|
AY_CHKREDY: |
|
|
AY_CHKREDY: |
|
|
LD A, (AY_READY) |
|
|
LD A, (AY_READY) |
|
|
BIT 0, A |
|
|
BIT 0, A |
|
|
@ -219,7 +219,7 @@ AY_SV: CALL AY_WRTPSG ; CYCLING THROUGH ALL CHANNELS |
|
|
AY_RESET: |
|
|
AY_RESET: |
|
|
AUDTRACE(AYT_INIT) |
|
|
AUDTRACE(AYT_INIT) |
|
|
CALL AY_CHKREDY ; RETURNS TO OUR CALLER IF NOT READY |
|
|
CALL AY_CHKREDY ; RETURNS TO OUR CALLER IF NOT READY |
|
|
|
|
|
|
|
|
|
|
|
; |
|
|
PUSH DE |
|
|
PUSH DE |
|
|
PUSH HL |
|
|
PUSH HL |
|
|
CALL AY_INIT ; SET DEFAULT CHIP CONFIGURATION |
|
|
CALL AY_INIT ; SET DEFAULT CHIP CONFIGURATION |
|
|
@ -261,10 +261,34 @@ AY_NOTE: |
|
|
AUDTRACE(AYT_NOTE) |
|
|
AUDTRACE(AYT_NOTE) |
|
|
AUDTRACE_HL |
|
|
AUDTRACE_HL |
|
|
AUDTRACE_CR |
|
|
AUDTRACE_CR |
|
|
|
|
|
|
|
|
LD DE, AY3NOTETBL |
|
|
|
|
|
CALL AUD_NOTE ; RETURNS PERIOD IN HL, FALL THRU |
|
|
|
|
|
; TO SET THIS PERIOD |
|
|
|
|
|
|
|
|
; |
|
|
|
|
|
; 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 |
|
|
|
|
|
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 |
|
|
; |
|
|
; |
|
|
;====================================================================== |
|
|
;====================================================================== |
|
|
; SOUND DRIVER FUNCTION - PERIOD |
|
|
; SOUND DRIVER FUNCTION - PERIOD |
|
|
@ -278,7 +302,7 @@ AY_PERIOD: |
|
|
LD A, H ; IF ZERO - ERROR |
|
|
LD A, H ; IF ZERO - ERROR |
|
|
OR L |
|
|
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) |
|
|
AND 11110000B ; ALLOWED RANGE IS 0001-0FFF (4095) |
|
|
JR NZ, AY_PERIOD1 ; RETURN NZ IF NUMBER TOO LARGE |
|
|
JR NZ, AY_PERIOD1 ; RETURN NZ IF NUMBER TOO LARGE |
|
|
@ -304,7 +328,6 @@ AY_PLAY: |
|
|
AUDTRACE_D |
|
|
AUDTRACE_D |
|
|
AUDTRACE_CR |
|
|
AUDTRACE_CR |
|
|
CALL AY_CHKREDY ; RETURNS TO OUR CALLER IF NOT READY |
|
|
CALL AY_CHKREDY ; RETURNS TO OUR CALLER IF NOT READY |
|
|
|
|
|
|
|
|
; |
|
|
; |
|
|
LD A, (AY_PENDING_PERIOD + 1) ; CHECK THE HIGH BYTE OF THE PERIOD |
|
|
LD A, (AY_PENDING_PERIOD + 1) ; CHECK THE HIGH BYTE OF THE PERIOD |
|
|
INC A |
|
|
INC A |
|
|
@ -412,21 +435,20 @@ AY_QUERY_DEV: |
|
|
LD DE, (AY_RSEL*256)+AY_RDAT ; AND ADDRESS AND DATA PORT |
|
|
LD DE, (AY_RSEL*256)+AY_RDAT ; AND ADDRESS AND DATA PORT |
|
|
XOR A |
|
|
XOR A |
|
|
RET |
|
|
RET |
|
|
|
|
|
|
|
|
|
|
|
; |
|
|
AY_DI: |
|
|
AY_DI: |
|
|
LD A, (AY_READY) |
|
|
LD A, (AY_READY) |
|
|
BIT 1, A |
|
|
BIT 1, A |
|
|
RET NZ |
|
|
RET NZ |
|
|
HB_DI |
|
|
HB_DI |
|
|
RET |
|
|
RET |
|
|
|
|
|
|
|
|
|
|
|
; |
|
|
AY_EI: |
|
|
AY_EI: |
|
|
LD A, (AY_READY) |
|
|
LD A, (AY_READY) |
|
|
BIT 1, A |
|
|
BIT 1, A |
|
|
RET NZ |
|
|
RET NZ |
|
|
HB_EI |
|
|
HB_EI |
|
|
RET |
|
|
RET |
|
|
|
|
|
|
|
|
; |
|
|
; |
|
|
;====================================================================== |
|
|
;====================================================================== |
|
|
; |
|
|
; |
|
|
@ -460,7 +482,6 @@ AY_WRTPSG: |
|
|
OUT (112),A ; NORMAL CLOCK SPEED |
|
|
OUT (112),A ; NORMAL CLOCK SPEED |
|
|
#ENDIF |
|
|
#ENDIF |
|
|
JP AY_EI |
|
|
JP AY_EI |
|
|
|
|
|
|
|
|
; |
|
|
; |
|
|
;====================================================================== |
|
|
;====================================================================== |
|
|
; |
|
|
; |
|
|
@ -510,13 +531,14 @@ AYT_REGWR .DB "\r\nOUT AY-3-8910 $" |
|
|
#ENDIF |
|
|
#ENDIF |
|
|
; |
|
|
; |
|
|
;====================================================================== |
|
|
;====================================================================== |
|
|
; BBC MICRO QUARTER TONE FREQUENCY TABLE |
|
|
|
|
|
|
|
|
; QUARTER TONE FREQUENCY TABLE |
|
|
;====================================================================== |
|
|
;====================================================================== |
|
|
; |
|
|
; |
|
|
; THE FREQUENCY BY QUARTER TONE STARTING AT A0# OCATVE 0 |
|
|
|
|
|
|
|
|
; THE FREQUENCY BY QUARTER TONE STARTING AT A0# OCTAVE 0 |
|
|
; USED TO MAP EACH OCTAVE (DIV BY 2 TO JUMP AN OCTAVE UP) |
|
|
; USED TO MAP EACH OCTAVE (DIV BY 2 TO JUMP AN OCTAVE UP) |
|
|
; FIRST PLAYABLE NOTE WILL BE 0 |
|
|
; FIRST PLAYABLE NOTE WILL BE 0 |
|
|
; ASSUMING A CLOCK OF 1843200 THIS MAPS TO A0# |
|
|
; ASSUMING A CLOCK OF 1843200 THIS MAPS TO A0# |
|
|
|
|
|
; |
|
|
AY3NOTETBL: |
|
|
AY3NOTETBL: |
|
|
.DW AY_RATIO / 2913 |
|
|
.DW AY_RATIO / 2913 |
|
|
.DW AY_RATIO / 2956 |
|
|
.DW AY_RATIO / 2956 |
|
|
|