Browse Source

Audio driver updates

pull/134/head
b1ackmai1er 6 years ago
parent
commit
b015cecb2a
  1. 42
      Source/Doc/Architecture.md
  2. 88
      Source/HBIOS/ay38910.asm
  3. 87
      Source/HBIOS/hbios.asm
  4. 8
      Source/HBIOS/spk.asm

42
Source/Doc/Architecture.md

@ -1429,23 +1429,32 @@ Increase by steps of 48 to select the same note in next octave.
If the driver is able to generate the requested note, a success (0) is
returned, otherwise a non-zero error state will be returned.
The sound chip resolution and its oscillator limit the range and
accuracy of the notes played. The typically range of the AY-3-8910
is six octaves, Bb2/A#2-A7, where each value is a unique tone. Values
above and below can still be played but each quarter tone step may not
result in a note change.
The following table shows the mapping of the input value in HL
to the corresponding octave and note.
| Note | Octave 0 | Octave 1 | Octave 2 | Octave 3 | Octave 4 | Octave 5 | Octave 6 |
|-------|----------|----------|----------|----------|----------|----------|----------|
| Bb/A# | 0 | 48 | 96 | 144 | 192 | 240 | 288 |
| B | 4 | 52 | 100 | 148 | 196 | 244 | 292 |
| C | 8 | 56 | 104 | 152 | 200 | 248 | 296 |
| C#/Db | 12 | 60 | 108 | 156 | 204 | 252 | 300 |
| D | 16 | 64 | 112 | 160 | 208 | 256 | 304 |
| Eb/D# | 20 | 68 | 116 | 164 | 212 | 260 | 308 |
| E | 24 | 72 | 120 | 168 | 216 | 264 | 312 |
| F | 28 | 76 | 124 | 172 | 220 | 268 | 316 |
| F#/Gb | 32 | 80 | 128 | 176 | 224 | 272 | 320 |
| G | 36 | 84 | 132 | 180 | 228 | 276 | 324 |
| Ab/G# | 40 | 88 | 136 | 184 | 232 | 280 | 328 |
| A | 44 | 92 | 140 | 188 | 236 | 284 | 332 |
+-------------------------------------------------------+
| | OCTAVE |
| Note |-----------------------------------------------+
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|-------|-----|-----|-----|-----|-----|-----|-----|-----+
| Bb/A# | 0 | 48 | 96 | 144 | 192 | 240 | 288 | 336 |
| B | 4 | 52 | 100 | 148 | 196 | 244 | 292 | 340 |
| C | 8 | 56 | 104 | 152 | 200 | 248 | 296 | 344 |
| C#/Db | 12 | 60 | 108 | 156 | 204 | 252 | 300 | 348 |
| D | 16 | 64 | 112 | 160 | 208 | 256 | 304 | 352 |
| Eb/D# | 20 | 68 | 116 | 164 | 212 | 260 | 308 | 356 |
| E | 24 | 72 | 120 | 168 | 216 | 264 | 312 | 360 |
| F | 28 | 76 | 124 | 172 | 220 | 268 | 316 | 364 |
| F#/Gb | 32 | 80 | 128 | 176 | 224 | 272 | 320 | 368 |
| G | 36 | 84 | 132 | 180 | 228 | 276 | 324 | 372 |
| Ab/G# | 40 | 88 | 136 | 184 | 232 | 280 | 328 | 376 |
| A | 44 | 92 | 140 | 188 | 236 | 284 | 332 | 380 |
### Function 0x54 -- Sound Play (SNDPLAY)
@ -1529,9 +1538,6 @@ key aspects of the specific Audio Device.
Reports information about the audio device unit specified.
At this stage, only one driver type is supported (SN76489), but is
envisaged that more will be added in the future.
Register B reports the audio device type (see below).
Registers HL and DE contain relevant port addresses for the hardware
@ -1543,7 +1549,7 @@ AUDIO ID | Value | Device | Returned registers
-------------- | ----- | ---------- | --------------------------------------------
SND_SN76489 | 0x01 | SN76489 | E: Left channel port, L: Right channel port
SND_AY38910 | 0x02 | AY-3-8910 | D: Address port, E: Data port
SND_BITMODE | 0x03 | I/O PORT | D: Address port, E: Bit mask
`\clearpage`{=latex}

88
Source/HBIOS/ay38910.asm

@ -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"
;
AY_RCSND .EQU 0 ; 0 = EB MODULE, 1=MF MODULE
;
#IF (AYMODE == AYMODE_SCG)
@ -15,6 +16,7 @@ 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)
@ -73,10 +75,13 @@ SBCV2004 .EQU 0 ; USE SBC-V2-004 HALF CLOCK DIVIDER
AY_TONECNT .EQU 3 ; COUNT NUMBER OF TONE 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"
;
@ -96,7 +101,7 @@ AY38910_INIT:
CALL PRTHEXBYTE
;
#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
#ENDIF
;
@ -127,55 +132,50 @@ AY_FND: LD IY, AY_IDAT ; SETUP FUNCTION TABLE
LD DE,(AY_R3CHBP*256)+$00
CALL AY_WRTPSG ; R03 = $00 = XXXX0000
;
#IF (SYSTIM != TM_NONE)
LD A, TICKFREQ / 3 ; SCHEDULE IN 1/3 SECOND TO TURN OFF SOUND
LD (AY_TIMTIK), A
;
LD HL, (VEC_TICK + 1) ; GET CUR TICKS VECTOR
LD (AY_TIMHOOK), HL ; SAVE IT INTERNALLY
LD HL, AY_TIMER ; INSTALL TIMER HOOK HANDLER
LD (VEC_TICK + 1), HL
;
LD A, $02 ; NOT READY & IN INTERUPT HANDLER
LD (AY_READY), A
#ELSE
CALL LDELAY ; HALF SECOND DELAY
LD E,$00 ; SET VOLUME OFF
CALL AY_SETV ; ON ALL CHANNELS
LD A, $01 ; READY & NOT IN INTERUPT HANDLER
LD (AY_READY), A
#ENDIF
;
XOR A ; SUCCESSFULL INIT
RET
;
#IF (SYSTIM != TM_NONE)
AY_TIMER:
LD A, (AY_TIMTIK)
DEC A
LD (AY_TIMTIK), A
JR NZ, AY_TIMER1
;
LD E,$00 ; SET VOLUME OFF
CALL AY_SETV ; ON ALL CHANNELS
LD A, $01 ; READY & NOT IN INTERUPT HANDLER
LD (AY_READY), A
;
LD DE, AY_TIMER ; MAKE AY_TIMER A NO_OP HANDLER
LD HL, AY_TIMER1
LD BC, 3
LDIR
;
AY_TIMER1:
JP 0 ; OVERWRITTEN WITH NEXT HANDLER
AY_TIMHOOK: .EQU $ - 2
AY_TIMTIK .DB 0 ; COUNT DOWN TO FINISH BOOT BEEP
#ENDIF
;
;======================================================================
@ -185,7 +185,7 @@ AY_TIMTIK .DB 0 ; COUNT DOWN TO FINISH BOOT BEEP
AY_INIT:
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
;
AY_CHKREDY:
LD A, (AY_READY)
BIT 0, A
@ -219,7 +219,7 @@ AY_SV: CALL AY_WRTPSG ; CYCLING THROUGH ALL CHANNELS
AY_RESET:
AUDTRACE(AYT_INIT)
CALL AY_CHKREDY ; RETURNS TO OUR CALLER IF NOT READY
;
PUSH DE
PUSH HL
CALL AY_INIT ; SET DEFAULT CHIP CONFIGURATION
@ -261,10 +261,34 @@ AY_NOTE:
AUDTRACE(AYT_NOTE)
AUDTRACE_HL
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
@ -278,7 +302,7 @@ AY_PERIOD:
LD A, H ; IF ZERO - ERROR
OR L
JR Z, AY_PERIOD1
;
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
@ -304,7 +328,6 @@ AY_PLAY:
AUDTRACE_D
AUDTRACE_CR
CALL AY_CHKREDY ; RETURNS TO OUR CALLER IF NOT READY
;
LD A, (AY_PENDING_PERIOD + 1) ; CHECK THE HIGH BYTE OF THE PERIOD
INC A
@ -412,21 +435,20 @@ AY_QUERY_DEV:
LD DE, (AY_RSEL*256)+AY_RDAT ; AND ADDRESS AND DATA PORT
XOR A
RET
;
AY_DI:
LD A, (AY_READY)
BIT 1, A
RET NZ
HB_DI
RET
;
AY_EI:
LD A, (AY_READY)
BIT 1, A
RET NZ
HB_EI
RET
;
;======================================================================
;
@ -460,7 +482,6 @@ AY_WRTPSG:
OUT (112),A ; NORMAL CLOCK SPEED
#ENDIF
JP AY_EI
;
;======================================================================
;
@ -510,13 +531,14 @@ AYT_REGWR .DB "\r\nOUT AY-3-8910 $"
#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)
; FIRST PLAYABLE NOTE WILL BE 0
; ASSUMING A CLOCK OF 1843200 THIS MAPS TO A0#
;
AY3NOTETBL:
.DW AY_RATIO / 2913
.DW AY_RATIO / 2956

87
Source/HBIOS/hbios.asm

@ -1628,6 +1628,7 @@ HB_INIT_REC:
#IF (PLATFORM == PLT_SBC)
.DW UART_INIT
.DW MD_INIT
.DW PPIDE_INIT
#ENDIF
HB_INITRLEN .EQU (($ - HB_INIT_REC) / 2)
;
@ -1673,14 +1674,14 @@ HB_INITTBL:
#IF (CTCENABLE)
.DW CTC_INIT
#ENDIF
#IF (SPKENABLE)
.DW SP_INIT ; AUDIBLE INDICATOR OF BOOT START
#IF (AY38910ENABLE)
.DW AY38910_INIT ; AUDIBLE INDICATOR OF BOOT START
#ENDIF
#IF (SN76489ENABLE)
.DW SN76489_INIT
#ENDIF
#IF (AY38910ENABLE)
.DW AY38910_INIT ; AUDIBLE INDICATOR OF BOOT START
#IF (SPKENABLE)
.DW SP_INIT ; AUDIBLE INDICATOR OF BOOT START
#ENDIF
#IF (ASCIENABLE)
.DW ASCI_INIT
@ -3680,10 +3681,14 @@ PRTSUM:
LD C,BF_SYSGET_DIOCNT ; DISK DRIVES
LD HL,PS_DISK
CALL PRT_ALLD
;
LD C,BF_SYSGET_VDACNT ; VIDEO DEVICES
LD HL,PS_VIDEO
CALL PRT_ALLD
;
LD C,BF_SYSGET_SNDCNT ; SOUND DEVICES
LD HL,PS_SOUND
CALL PRT_ALLD
RET
;
PRT_ALLD:
@ -4026,6 +4031,68 @@ PS_PRTVC:
CALL PRTDECB
RET
;
; PRINT SOUND CONFIG
;
PS_SOUND:
PUSH BC
; UNIT COLUMN
PRTS("Sound $")
LD A,C ; MOVE UNIT NUM TO A
CALL PRTDECB ; PRINT IT
CP 10 ; CHECK FOR MULTIPLE DIGITS
CALL C,PC_SPACE ; EXTRA SPACE IF NEEDED
PRTS(" $") ; PAD TO NEXT COLUMN
; DEVICE COLUMN
PUSH BC ;
LD E,C
XOR A
LD DE,PS_SDSND ; POINT TO DEVICE TYPE NAME TABLE
CALL PRTIDXDEA ; PRINT DEVICE NMEMONIC PADDED TO FIELD WIDTH
LD A,C ; MOVE UNIT NUM TO A
CALL PRTDECB ; PRINT IT
CALL PC_COLON
CP 10 ; CHECK FOR MULTIPLE DIGITS
CALL C,PC_SPACE ; EXTRA SPACE IF NEEDED
LD A,(PRTIDXCNT)
SUB 9+1
CPL
CALL PS_PAD
POP BC
; DEVICE TYPE
;
LD B,BF_SNDQUERY ; FUNC=GET DEVICE INFO, UNIT NUM STILL IN C
LD E,BF_SNDQ_DEV
RST 08
LD A,B
DEC A
LD DE,PS_SDSN76489
CALL PRTIDXDEA
LD A,(PRTIDXCNT)
SUB 18+1
CPL
CALL PS_PAD ; PAD N SPACES (SPECIFIED IN A)
; DEVICE CHARACTERISTICS
;
LD B,BF_SNDQUERY ; FUNC=GET DEVICE INFO, UNIT NUM STILL IN C
LD E,BF_SNDQ_CHCNT
RST 08
LD A,B
CALL PRTDECB
LD A,'+'
CALL COUT
LD A,C
CALL PRTDECB
PRTS(" CHANNELS$")
CALL NEWLINE
;
POP BC
RET
;
; PRINT DEVICE NMEMONIC, DEVTYP/NUM SPECIFIED IN DE
;
PS_PRTDEV:
@ -4182,6 +4249,16 @@ PS_VDVGA .TEXT "VGA$"
;
PS_VTCRT .TEXT "CRT$"
;
; SOUND DEVICE STRINGS
;
PS_SDSND .TEXT "SND$"
;
; SOUND TYPE STRINGS
;
PS_SDSN76489 .TEXT "SN76489$"
PS_SDAY38910 .TEXT "AY-3-8910$"
PS_SDBITMODE .TEXT "I/O PORT$"
;
; 0 1 2 3 4 5 6 7
; 01234567890123456789012345678901234567890123456789012345678901234567890123456789
PS_STRHDR .TEXT "Unit Device Type Capacity/Mode\r\n"

8
Source/HBIOS/spk.asm

@ -24,6 +24,8 @@ SP_IDAT .EQU 0 ; NO INSTANCE DATA ASSOCIATED WITH THIS DEVICE
SP_TONECNT .EQU 1 ; COUNT NUMBER OF TONE CHANNELS
SP_NOISECNT .EQU 0 ; COUNT NUMBER OF NOISE CHANNELS
;
SP_RTCIOMSK .EQU 00000100B
;
; FOR OTHER DRIVERS, THE PERIOD VALUE FOR THE TONE IS STORED AT PENDING_PERIOD
; FOR THE SPK DRIVER THE ADDRESS IN THE TONE TABLE IS STORED IN PENDING_PERIOD
;
@ -139,8 +141,8 @@ SP_QUERY_VOLUME:
RET
;
SP_QUERY_DEV:
LD B, BF_SND_BITMODE ; RETURN DEVICE IDENTIFIER
LD DE, 0 ; AND ADDRESS AND DATA PORT
LD B, BF_SND_BITMODE ; RETURN DEVICE IDENTIFIER
LD DE, (RTCIO*256)+SP_RTCIOMSK ; AND ADDRESS AND DATA PORT
XOR A
RET
;
@ -273,7 +275,7 @@ BE_H_L_LP:
;
; The loudspeaker is now alternately activated and deactivated.
;
XOR %00000100 ; Flip bit 2.
XOR SP_RTCIOMSK ; Flip bit 2.
OUT (RTCIO),A ; Perform the 'OUT' operation, leaving other bits unchanged.
LD B,H ; Reset the B register.
LD C,A ; Save the A register.

Loading…
Cancel
Save