diff --git a/Source/Apps/Tune/Tune.asm b/Source/Apps/Tune/Tune.asm index aa28cb95..1b523d3c 100644 --- a/Source/Apps/Tune/Tune.asm +++ b/Source/Apps/Tune/Tune.asm @@ -1998,11 +1998,11 @@ PLAYVIAHBIOS: LD L, A RST 08 - LD B, BF_SNDPIT + LD B, BF_SNDPRD LD C, 0 LD HL, (AYREGS+TonA) ld a, h - AND $3F + AND $0F LD H, A RST 08 @@ -2023,11 +2023,11 @@ PLAYVIAHBIOS: LD L, A RST 08 - LD B, BF_SNDPIT + LD B, BF_SNDPRD LD C, 0 LD HL, (AYREGS+TonB) ld a, h - AND $3F + AND $0F LD H, A RST 08 @@ -2048,11 +2048,11 @@ PLAYVIAHBIOS: LD L, A RST 08 - LD B, BF_SNDPIT + LD B, BF_SNDPRD LD C, 0 LD HL, (AYREGS+TonC) ld a, h - AND $3F + AND $0F LD H, A RST 08 diff --git a/Source/Apps/Tune/hbios.inc b/Source/Apps/Tune/hbios.inc index 874a9699..f2442f78 100644 --- a/Source/Apps/Tune/hbios.inc +++ b/Source/Apps/Tune/hbios.inc @@ -10,6 +10,6 @@ BF_SYSGET .EQU $F8 ; HBIOS: SYSGET function BF_SND .EQU $50 BF_SNDRESET .EQU BF_SND + 0 ; RESET SOUND SYSTEM BF_SNDVOL .EQU BF_SND + 1 ; REQUEST SOUND VOL - D IS CHANNEL, E CONTAINS VOLUME (255 MAX, 0 SILENT) - SCALED AS REQUIRED BY DRIVER (EG: MAPS TO JUST 4 BIT RESOLUTION FOR SN76489) -BF_SNDPIT .EQU BF_SND + 2 ; REQUEST SOUND PITCH - D IS CHANNEL, HL CONTAINS PITCH (0 LOWEST NOTE, FFFF HIGHEST NOTE) - SCALED BY DRIVER (EG: MAPS TO JUST 10 BITS FOR SN76489 ) +BF_SNDPRD .EQU BF_SND + 2 ; REQUEST SOUND PERIOD - D IS CHANNEL, HL CONTAINS PERIOD (0 LOWEST NOTE) - SCALED BY DRIVER (EG: MAPS TO JUST 10 BITS FOR SN76489 ) BF_SNDPLAY .EQU BF_SND + 4 ; INITIATE THE REQUESTED SOUND COMMAND BF_SNDQUERY .EQU BF_SND + 5 ; D IS CHANNEL, E IS SUBCOMMAND diff --git a/Source/Doc/Architecture.md b/Source/Doc/Architecture.md index 94c9a85d..c618667e 100644 --- a/Source/Doc/Architecture.md +++ b/Source/Doc/Architecture.md @@ -1324,17 +1324,20 @@ Note that not all sounds chips implement 256 volume levels. The driver will scale the volume to the closest possible level the chip provides. -### Function 0x52 -- Sound Pitch (SNDPIT) +### Function 0x52 -- Sound period (SNDPRD) | _Entry Parameters_ | B: 0x52 | C: Audio Device Unit ID -| HL: Pitch (0000=lowest note, FFFF=highest note) +| HL: period (0000=lowest note, FFFF=highest note) -This function sets the sound chip pitch parameter. The pitch will +| _Returned Values_ +| A: Status (0=OK, else error) + +This function sets the sound chip period parameter. The period will be applied when the next SNDPLAY function is invoked. -The pitch value is a driver specific value. To play standardized +The period value is a driver specific value. To play standardized notes, use the SNDNOTE function. ### Function 0x53 -- Sound Note (SNDNOTE) @@ -1344,14 +1347,17 @@ notes, use the SNDNOTE function. | C: Audio Device Unit ID | L: Note (0 to 255 quarter notes) -This function sets the sound chip pitch parameter according to +| _Returned Values_ +| A: Status (0=OK, else error) + +This function sets the sound chip period parameter according to standardized notes. -The value corresponds to standard musical notes. The value allows -for selection of a quarter of a semitone by giving a value between 0 +The value corresponds to standard musical notes. The value allows +for selection of a quarter of a semitone by giving a value between 0 and up to the drivers maximum supported value. The lowest note is (0). -For the SN76490 chip, 0 corresponds to note A1# and the value 249 is +For the SN76490 chip, 0 corresponds to note A1# and the value 249 is the maximum supported value, and it corresponds to note C7. ### Function 0x54 -- Sound Play (SNDPLAY) @@ -1359,9 +1365,12 @@ the maximum supported value, and it corresponds to note C7. | _Entry Parameters_ | B: 0x54 | C: Audio Device Unit ID -| D: Channel +| E: Channel -This function applies the previously specified volume and pitch by +| _Returned Values_ +| A: Status (0=OK, else error) + +This function applies the previously specified volume and period by programming the sound chip with the appropriate values. The values are applied to the specified channel of the chip. @@ -1374,6 +1383,81 @@ HBIOS B=53 C=00 L=69 ; Select Middle C (C4) assuming SN76489 HBIOS B=54 C=00 D=01 ; Play note on Channel 1 ``` +### Function 0x55 -- Sound Play (SNDQUERY) + +| _Entry Parameters_ +| B: 0x54 +| C: Audio Device Unit ID +| E: Subfunction + +| _Returned Values_ +| A: Status (0=OK, else error) + +This function will return the status of current pending command or +key aspects of the specific Audio Device. + +#### SNDQUERY Subfunction 0x01 -- Get count of audio channels supported (SNDQ_CHCNT) + +| _Entry Parameters_ +| B: 0x54 +| E: 0x01 + +| _Returned Values_ +| A: Status (0=OK, else error) +| B: Count of standard tone channels +| C: Count of noise tone channels + +#### SNDQUERY Subfunction 0x01 -- Get current volume setting (SNDQ_VOL) + +| _Entry Parameters_ +| B: 0x54 +| E: 0x02 + +| _Returned Values_ +| A: Status (0=OK, else error) +| H: 0 +| L: Current volume setting + +#### SNDQUERY Subfunction 0x03 -- Get current period setting (SNDQ_PERIOD) + +| _Entry Parameters_ +| B: 0x54 +| E: 0x03 + +| _Returned Values_ +| A: Status (0=OK, else error) +| HL: Current period setting + +#### SNDQUERY Subfunction 0x04 -- Get device details (SNDQ_DEV) + +| _Entry Parameters_ +| B: 0x54 +| E: 0x04 + +| _Returned Values_ +| A: Status (0=OK, else error) +| B: Driver identity +| HL: Driver specific port settings +| DE: Driver specific port settings + +Reports information about the audio device unit specified. + +At this stage, only one driver type is supported (SN76489), but is +envisage that more will be added in the future. + +Register B reports the audio device type (see below). + +Registers HL and DE contain relevant port address for the hardware +as such are specific to each device type. + +The currently defined audio device types are: + +AUDIO ID | Value | Device | Returned registers +-------------- | ----- | ---------- | -------------------------------------------- +SND_SN76489 | 0x01 | SN76489 | E: Left channel port, L: Right channel port +SND_SNAY38910 | 0x02 | AY-3-8910 | D: Address port, E: Data port + + `\clearpage`{=latex} System (SYS) diff --git a/Source/HBIOS/hbios.inc b/Source/HBIOS/hbios.inc index 17a9ae23..e3fe6667 100644 --- a/Source/HBIOS/hbios.inc +++ b/Source/HBIOS/hbios.inc @@ -55,16 +55,22 @@ BF_VDAKRD .EQU BF_VDA + 14 ; READ KEYBOARD BF_SND .EQU $50 BF_SNDRESET .EQU BF_SND + 0 ; RESET SOUND SYSTEM BF_SNDVOL .EQU BF_SND + 1 ; REQUEST SOUND VOL - L CONTAINS VOLUME (255 MAX, 0 SILENT) - SCALED AS REQUIRED BY DRIVER (EG: MAPS TO JUST 4 BIT RESOLUTION FOR SN76489) -BF_SNDPIT .EQU BF_SND + 2 ; REQUEST SOUND PITCH - HL CONTAINS PITCH DRIVER SPECIFIC VALUE +BF_SNDPRD .EQU BF_SND + 2 ; REQUEST SOUND PERIOD - HL CONTAINS DRIVER SPECIFIC VALUE BF_SNDNOTE .EQU BF_SND + 3 ; REQUEST NOTE - L CONTAINS NOTE - EACH VALUE IS QUARTER NOTE BF_SNDPLAY .EQU BF_SND + 4 ; INITIATE THE REQUESTED SOUND COMMAND -BF_SNDQUERY .EQU BF_SND + 5 ; D IS CHANNEL, E IS SUBCOMMAND +BF_SNDQUERY .EQU BF_SND + 5 ; E IS SUBFUNCTION ; ; BF_SNDQUERY SUBCOMMANDS BF_SNDQ_STATUS .EQU 0 BF_SNDQ_CHCNT .EQU BF_SNDQ_STATUS + 1 ; RETURN COUNT OF CHANNELS -BF_SNDQ_SVOLUME .EQU BF_SNDQ_STATUS + 2 ; 8 BIT NUMBER -BF_SNDQ_SPITCH .EQU BF_SNDQ_STATUS + 3 ; 16 BIT NUMBER +BF_SNDQ_VOLUME .EQU BF_SNDQ_STATUS + 2 ; 8 BIT NUMBER +BF_SNDQ_PERIOD .EQU BF_SNDQ_STATUS + 3 ; 16 BIT NUMBER +BF_SNDQ_DEV .EQU BF_SNDQ_STATUS + 4 ; RETURN DEVICE TYPE CODE AND IO PORTS - TYPE IN B, PORTS IN DE, HL + +BF_SNDDEV .EQU 0 ; TYPES OF SOUND DRIVERS +BF_SND_SN76489 .EQU BF_SNDDEV + 1 +BF_SND_SNAY38910 .EQU BF_SNDDEV + 2 + ; BF_SYS .EQU $F0 BF_SYSRESET .EQU BF_SYS + 0 ; SOFT RESET HBIOS diff --git a/Source/HBIOS/sn76489.asm b/Source/HBIOS/sn76489.asm index 3c12acb6..4ce9546b 100644 --- a/Source/HBIOS/sn76489.asm +++ b/Source/HBIOS/sn76489.asm @@ -33,9 +33,9 @@ SN7_LAST_NOTE .EQU 209300 ; C7 A1S .EQU SN7RATIO / SN7_FIRST_NOTE C7 .EQU SN7RATIO / SN7_LAST_NOTE - .ECHO "SN76489: range of A1# (pitch: " + .ECHO "SN76489: range of A1# (period: " .ECHO A1S - .ECHO ") to C7 (pitch: " + .ECHO ") to C7 (period: " .ECHO C7 .ECHO ")\n" @@ -132,48 +132,78 @@ SN7_NOTE: LD HL, SN7NOTETBL ADD HL, DE - LD A, (HL) ; RETRIEVE PITCH COUNT FROM SN7NOTETBL + LD A, (HL) ; RETRIEVE PERIOD COUNT FROM SN7NOTETBL INC HL LD H, (HL) LD L, A - JR SN7_PITCH ; APPLY PITCH + JR SN7_PERIOD ; APPLY PERIOD SN7_NOTE1: OR $FF ; NOT IMPLEMENTED YET RET -SN7_PITCH: - AUDDEBUG("SN7PIT ") +SN7_PERIOD: + AUDDEBUG("SN7PRD ") AUDTRACE_HL AUDDEBUG("\r\n") - LD (PENDING_PITCH), HL + LD A, H + CP $04 + JP NC, SN7_QUERY_PERIOD1 ; RETURN NZ IF NUMBER TOO LARGE + + LD (PENDING_PERIOD), HL XOR A ; SIGNAL SUCCESS RET +SN7_QUERY_PERIOD1: ; REQUESTED PERIOD IS LARGER THAN THE SN76489 CAN SUPPORT + LD L, $FF + LD H, $FF + LD (PENDING_PERIOD), HL + + OR $FF ; SIGNAL FAILURE + RET + SN7_PLAY: AUDDEBUG("SN7PLY ") AUDTRACE_D AUDDEBUG("\r\n") + LD A, (PENDING_PERIOD + 1) + CP $FF + JR Z, SN7_PLAY1 ; PERIOD IS TOO LARGE, UNABLE TO PLAY CALL SN7_APPLY_VOL - CALL SN7_APPLY_PIT + CALL SN7_APPLY_PRD XOR A ; SIGNAL SUCCESS RET +SN7_PLAY1: ; TURN CHANNEL VOL TO OFF AND STOP PLAYING + LD A, (PENDING_VOLUME) + PUSH AF + LD A, 0 + LD (PENDING_VOLUME), A + CALL SN7_APPLY_VOL + POP AF + LD (PENDING_VOLUME), A + + OR $FF ; SIGNAL FAILURE + RET + SN7_QUERY: LD A, E CP BF_SNDQ_CHCNT JR Z, SN7_QUERY_CHCNT - CP BF_SNDQ_SPITCH - JR Z, SN7_QUERY_PITCH + CP BF_SNDQ_PERIOD + JR Z, SN7_QUERY_PERIOD - CP BF_SNDQ_SVOLUME + CP BF_SNDQ_VOLUME JR Z, SN7_QUERY_VOLUME + CP BF_SNDQ_DEV + JR Z, SN7_QUERY_DEV + OR $FF ; SIGNAL FAILURE RET @@ -183,9 +213,8 @@ SN7_QUERY_CHCNT: XOR A RET -SN7_QUERY_PITCH: - LD HL, (PENDING_PITCH) - +SN7_QUERY_PERIOD: + LD HL, (PENDING_PERIOD) XOR A RET @@ -197,6 +226,14 @@ SN7_QUERY_VOLUME: XOR A RET +SN7_QUERY_DEV: + + LD B, BF_SND_SN76489 + LD DE, SN76489_PORT_LEFT ; E WITH LEFT PORT + LD HL, SN76489_PORT_RIGHT ; L WITH RIGHT PORT + + XOR A + RET ; ; UTIL FUNCTIONS ; @@ -238,11 +275,11 @@ SN7_APPLY_VOL: ; APPLY VOLUME TO BOTH LEFT AND RIGHT CHANNELS POP BC RET -SN7_APPLY_PIT: +SN7_APPLY_PRD: PUSH DE PUSH BC PUSH AF - LD HL, (PENDING_PITCH) + LD HL, (PENDING_PERIOD) LD A, D AND $3 @@ -252,11 +289,11 @@ SN7_APPLY_PIT: RLCA RLCA OR $80 - LD B, A ; PITCH COMMAND 1 - CONTAINS CHANNEL ONLY + LD B, A ; PERIOD COMMAND 1 - CONTAINS CHANNEL ONLY LD A, L ; GET LOWER 4 BITS FOR COMMAND 1 AND $F - OR B ; A NOW CONATINS FIRST PITCH COMMAND + OR B ; A NOW CONATINS FIRST PERIOD COMMAND AUDTRACE(TRACE_PORT_WR) AUDTRACE_A @@ -279,7 +316,7 @@ SN7_APPLY_PIT: RLCA RLCA RLCA ; AND PLACE IN BITS 5 AND 6 - OR B ; OR THE TWO SETS OF BITS TO MAKE 2ND PITCH COMMAND + OR B ; OR THE TWO SETS OF BITS TO MAKE 2ND PERIOD COMMAND AUDTRACE(TRACE_PORT_WR) AUDTRACE_A @@ -297,7 +334,7 @@ SN7_APPLY_PIT: SN7_FNTBL: .DW SN7_RESET .DW SN7_VOLUME - .DW SN7_PITCH + .DW SN7_PERIOD .DW SN7_NOTE .DW SN7_PLAY .DW SN7_QUERY @@ -307,8 +344,8 @@ SN7_FNTBL: !!!!! #ENDIF -PENDING_PITCH - .DW 0 ; PENDING PITCH (10 BITS) +PENDING_PERIOD + .DW 0 ; PENDING PERIOD (10 BITS) PENDING_VOLUME .DB 0 ; PENDING VOL (8 BITS -> DOWNOVERTED TO 4 BITS AND INVERTED) @@ -322,8 +359,8 @@ TRACE_VOLUME_SET .DB "\r\nSN7_VOLUME_SET CH: $" TRACE_PLAY .DB "\r\nPLAY\r\n$" TRACE_VOLUME .DB ", VOL: $" TRACE_PORT_WR .DB "\r\nOUT SN76489, $" -TRACE_PITCH_SET .DB "\r\nSN7_PITCH_SET CH: $" -TRACE_PITCH .DB ", PITCH: $" +TRACE_PERIOD_SET .DB "\r\nSN7_PERIOD_SET CH: $" +TRACE_PERIOD .DB ", PERIOD: $" TRACE_NEWLINE .DB "\r\n$" #ENDIF diff --git a/Source/HBIOS/util.asm b/Source/HBIOS/util.asm index a1ca84ff..8dc066db 100644 --- a/Source/HBIOS/util.asm +++ b/Source/HBIOS/util.asm @@ -187,9 +187,9 @@ PRTHEXWORD: ; PRTHEXWORDHL: PUSH AF - LD A,D + LD A,H CALL PRTHEXBYTE - LD A,E + LD A,L CALL PRTHEXBYTE POP AF RET