diff --git a/Source/Apps/Tune/Tune.asm b/Source/Apps/Tune/Tune.asm index 6f340a2e..fc41b087 100644 --- a/Source/Apps/Tune/Tune.asm +++ b/Source/Apps/Tune/Tune.asm @@ -40,6 +40,7 @@ ; 2020-02-11 [WBW] Made hardware config & detection more flexible ; 2020-03-29 [WBW] Fix error in Z180 I/O W/S bracketing ; 2020-04-25 [DEN] Added support to use HBIOS Sound driver +; 2020-05-02 [PMS] Add support for SBC-V2 slow-io hack ;_______________________________________________________________________________ ; ; ToDo: @@ -53,14 +54,18 @@ #include "hbios.inc" #include "cpm.inc" #include "tune.inc" - +; HEAPEND .EQU $C000 ; End of heap storage ; TYPPT2 .EQU 1 ; FILTYP value for PT2 sound file TYPPT3 .EQU 2 ; FILTYP value for PT3 sound file TYPMYM .EQU 3 ; FILTYP value for MYM sound file ; - +; HIGH SPEED CPU CONTROL +; +SBCV2004 .EQU 0 ; USE SBC-V2-004 HALF CLOCK DIVIDER +CPUFAMZ180 .EQU 1 ; USE Z180 WAIT STATE MANAGEMENT +; ;Conditional assembly - use -D switch on TASM or uz80as assembler to control _ZX .EQU 0 ; 1) Version of ROUT (ZX or MSX standards) _MSX .EQU 0 @@ -401,43 +406,44 @@ IDBIO2: ; ; ; -SLOWCPU: - LD A,(Z180) ; Z180 base I/O port - CP $FF ; Check for no value - RET Z ; Bail out if no value - ADD A,$1E ; Apply offset of CMR register - LD C,A ; And put it in C - LD B,0 ; MSB for 16-bit I/O - IN A,(C) ; Get current value - LD (CMRSAV),A ; Save it to restore later - XOR A ; Go slow - OUT (C),A ; And update CMR - INC C ; Now point to CCR register - IN A,(C) ; Get current value - LD (CCRSAV),A ; Save it to restore later - XOR A ; Go slow - OUT (C),A ; And update CCR - RET -; -; -; -NORMCPU: - LD A,(Z180) ; Z180 base I/O port - CP $FF ; Check for no value - RET Z ; Bail out if no value - ADD A,$1E ; Apply offset of CMR register - LD C,A ; And put it in C - LD B,0 ; MSB for 16-bit I/O - LD A,(CMRSAV) ; Get original CMR value - OUT (C),A ; And update CMR - INC C ; Now point to CCR register - LD A,(CCRSAV) ; Get original CCR value - OUT (C),A ; And update CCR - RET -; -; +;SLOWCPU: +; LD A,(Z180) ; Z180 base I/O port +; CP $FF ; Check for no value +; RET Z ; Bail out if no value +; ADD A,$1E ; Apply offset of CMR register +; LD C,A ; And put it in C +; LD B,0 ; MSB for 16-bit I/O +; IN A,(C) ; Get current value +; LD (CMRSAV),A ; Save it to restore later +; XOR A ; Go slow +; OUT (C),A ; And update CMR +; INC C ; Now point to CCR register +; IN A,(C) ; Get current value +; LD (CCRSAV),A ; Save it to restore later +; XOR A ; Go slow +; OUT (C),A ; And update CCR +; RET +; +; +; +;NORMCPU: +; LD A,(Z180) ; Z180 base I/O port +; CP $FF ; Check for no value +; RET Z ; Bail out if no value +; ADD A,$1E ; Apply offset of CMR register +; LD C,A ; And put it in C +; LD B,0 ; MSB for 16-bit I/O +; LD A,(CMRSAV) ; Get original CMR value +; OUT (C),A ; And update CMR +; INC C ; Now point to CCR register +; LD A,(CCRSAV) ; Get original CCR value +; OUT (C),A ; And update CCR +; RET +; +; SLOW DOWN I/O FOR FAST CPU'S ; SLOWIO: +#IF (CPUFAMZ180) LD A,(Z180) ; Z180 base I/O port CP $FF ; Check for no value RET Z ; Bail out if no value @@ -448,11 +454,17 @@ SLOWIO: LD (DCSAV),A ; Save it to restore later OR %00110000 ; Force slow operation (I/O W/S=3) OUT (C),A ; And update DCNTL +#ENDIF +#IF (SBCV2004) + LD A,8 ; sbc-v2-004 change to + OUT (112),A ; half clock speed +#ENDIF RET ; -; +; RESTORE I/O SPEED FOR FAST CPU'S ; NORMIO: +#IF (CPUFAMZ180) LD A,(Z180) ; Z180 base I/O port CP $FF ; Check for no value RET Z ; Bail out if no value @@ -461,8 +473,12 @@ NORMIO: LD B,0 ; MSB for 16-bit I/O LD A,(DCSAV) ; Get saved DCNTL value OUT (C),A ; And restore it +#ENDIF +#IF (SBCV2004) + LD A,0 ; sbc-v2-004 change to + OUT (112),A ; normal clock speed +#ENDIF RET - ; ERRBIO: ; Invalid BIOS or version LD DE,MSGBIO @@ -1982,87 +1998,93 @@ LOUT OUT (C), A ; SELECT REGISTER JP M, LOUT2 ; IF BIT 7 SET, RETURN W/O WRITING VALUE LD C, D ; SELECT DATA PORT OUT (C), A ; WRITE VALUE TO REGISTER 13 -LOUT2 - CALL NORMIO +LOUT2 CALL NORMIO EI RET ; AND DONE PLAYVIAHBIOS: - LD B, BF_SNDVOL - LD C, 0 - LD H, 0 - LD A, (AYREGS + AmplA) - AND $0F - rlca - rlca - rlca - rlca +; +; CHANNEL 0 (LEFT) +; + LD B, BF_SNDVOL ; SET VOLUME + LD C, 0 ; DEVICE 0 +; LD H, 0 + LD A, (AYREGS + AmplA) ; GET 4-BIT + AND $0F ; VOLUME 0-15 + RLCA ; AND CONVERT + RLCA ; TO HBIOS + RLCA ; RANGE 0-255 + RLCA LD L, A RST 08 - - LD B, BF_SNDPRD - LD C, 0 - LD HL, (AYREGS+TonA) - ld a, h - AND $0F +; + LD B, BF_SNDPRD ; SET PERIOD + LD C, 0 ; DEVICE 0 + LD HL, (AYREGS+TonA) ; GET 12-BIT TONE PERIOD + ld A, H ; MASK OFF HIGH + AND $0F ; NIBBLE LD H, A RST 08 - - LD B, BF_SNDPLAY - LD C, 0 - LD D, 0 +; + LD B, BF_SNDPLAY ; PLAY + LD C, 0 ; DEVICE 0 + LD D, 0 ; CHANNEL 0 RST 08 - - LD B, BF_SNDVOL - LD C, 0 - LD H, 0 - LD A, (AYREGS + AmplB) - AND $0F - rlca - rlca - rlca - rlca +; +; CHANNEL 1 (MIDDLE) +; + LD B, BF_SNDVOL ; SET VOLUME + LD C, 0 ; DEVICE 0 +; LD H, 0 + LD A, (AYREGS + AmplB) ; GET 4-BIT + AND $0F ; VOLUME 0-15 + RLCA ; AND CONVERT + RLCA ; TO HBIOS + RLCA ; RANGE 0-255 + RLCA LD L, A RST 08 - - LD B, BF_SNDPRD - LD C, 0 - LD HL, (AYREGS+TonB) - ld a, h - AND $0F +; + LD B, BF_SNDPRD ; SET PERIOD + LD C, 0 ; DEVICE 0 + LD HL, (AYREGS+TonB) ; GET 12-BIT ONE PERIOD + ld a, h ; MASK OFF HIGH + AND $0F ; NIBBLE LD H, A RST 08 - - LD B, BF_SNDPLAY - LD C, 0 - LD D, 1 +; + LD B, BF_SNDPLAY ; PLAY + LD C, 0 ; DEVICE 0 + LD D, 1 ; CHANNEL 1 RST 08 - - LD B, BF_SNDVOL - LD C, 0 - LD H, 0 - LD A, (AYREGS + AmplC) - AND $0F - rlca - rlca - rlca - rlca +; +; CHANNEL 2 (RIGHT) +; + LD B, BF_SNDVOL ; SET VOLUME + LD C, 0 ; DEVICE 0 +; LD H, 0 + LD A, (AYREGS + AmplC) ; GET 4-BIT + AND $0F ; VOLUME 0-15 + RLCA ; AND CONVERT + RLCA ; TO HBIOS + RLCA ; RANGE 0-255 + RLCA LD L, A RST 08 - - LD B, BF_SNDPRD - LD C, 0 - LD HL, (AYREGS+TonC) - ld a, h - AND $0F +; + LD B, BF_SNDPRD ; SET PERIOD + LD C, 0 ; DEVICE 0 + LD HL, (AYREGS+TonC) ; GET 12-BIT ONE PERIOD + ld A, H ; MASK OFF HIGH + AND $0F ; NIBBLE LD H, A RST 08 - - LD B, BF_SNDPLAY - LD C, 0 - LD D, 2 - RST 08 - +; + LD B, BF_SNDPLAY ; PLAY + LD C, 0 ; DEVICE 0 + LD D, 2 ; CHANNEL 2 + RST 08 ; HBIOS CALL + RET #ENDIF diff --git a/Source/Doc/Architecture.md b/Source/Doc/Architecture.md index 9d61590f..1d430e74 100644 --- a/Source/Doc/Architecture.md +++ b/Source/Doc/Architecture.md @@ -1404,7 +1404,7 @@ 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 SN76489 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) @@ -1412,7 +1412,7 @@ the maximum supported value, and it corresponds to note C7. | _Entry Parameters_ | B: 0x54 | C: Audio Device Unit ID -| E: Channel +| D: Channel | _Returned Values_ | A: Status (0=OK, else error) @@ -1433,7 +1433,7 @@ HBIOS B=54 C=00 D=01 ; Play note on Channel 1 ### Function 0x55 -- Sound Query (SNDQUERY) | _Entry Parameters_ -| B: 0x54 +| B: 0x55 | C: Audio Device Unit ID | E: Subfunction @@ -1446,7 +1446,7 @@ key aspects of the specific Audio Device. #### SNDQUERY Subfunction 0x01 -- Get count of audio channels supported (SNDQ_CHCNT) | _Entry Parameters_ -| B: 0x54 +| B: 0x55 | E: 0x01 | _Returned Values_ @@ -1454,10 +1454,10 @@ key aspects of the specific Audio Device. | B: Count of standard tone channels | C: Count of noise tone channels -#### SNDQUERY Subfunction 0x01 -- Get current volume setting (SNDQ_VOL) +#### SNDQUERY Subfunction 0x02 -- Get current volume setting (SNDQ_VOL) | _Entry Parameters_ -| B: 0x54 +| B: 0x55 | E: 0x02 | _Returned Values_ @@ -1468,7 +1468,7 @@ key aspects of the specific Audio Device. #### SNDQUERY Subfunction 0x03 -- Get current period setting (SNDQ_PERIOD) | _Entry Parameters_ -| B: 0x54 +| B: 0x55 | E: 0x03 | _Returned Values_ @@ -1478,7 +1478,7 @@ key aspects of the specific Audio Device. #### SNDQUERY Subfunction 0x04 -- Get device details (SNDQ_DEV) | _Entry Parameters_ -| B: 0x54 +| B: 0x55 | E: 0x04 | _Returned Values_ @@ -1502,7 +1502,7 @@ 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 +SND_AY38910 | 0x02 | AY-3-8910 | D: Address port, E: Data port `\clearpage`{=latex} diff --git a/Source/HBIOS/ay.asm b/Source/HBIOS/ay.asm index 85d9b9e2..6c03d2eb 100644 --- a/Source/HBIOS/ay.asm +++ b/Source/HBIOS/ay.asm @@ -57,10 +57,10 @@ AY_INIT1: CALL AY_BEEP AY_INIT2: LD D,AY_R7ENAB ; SET MIXER CONTROL / IO ENABLE - LD E,$FF ; $FF - 11 111 111 - CALL AY_WRTPSG ; I/O PORTS DISABLED, NOISE CHANNEL C, B, A DISABLE, TONE CHANNEL C, B, A DISABLE + LD E,$F8 ; $FF - 11 111 111 + CALL AY_WRTPSG ; I/O PORTS DISABLED, NOISE CHANNEL C, B, A DISABLE, TONE CHANNEL C, B, A ENABLE ; - LD B,2 + LD B,3 LD D,AY_R8AVOL ; SET VOLUME TO 0 LD E,$00 AY_QUIET: @@ -73,7 +73,7 @@ AY_QUIET: ; AY_BEEP: LD D,AY_R2CHBP ; SET TONE PERIOD - LD E,$55 ; CHANNEL B - R00 & R01 + LD E,$55 ; CHANNEL B - R02 & R03 CALL AY_WRTPSG ; $0055 = XXXX0000 01010101 LD D,AY_R3CHBP LD E,0 @@ -90,7 +90,7 @@ AY_BEEP: CALL LDELAY ; HALF SECOND RET ; -; WRITE DATA E TO PSG REG A +; WRITE DATA E TO PSG REG D ; AY_WRTPSG: HB_DI @@ -100,10 +100,10 @@ AY_WRTPSG: OR %00110000 ; FORCE SLOW OPERATION (I/O W/S=3) OUT0 (Z180_DCNTL),A ; AND UPDATE DCNTL #ENDIF - LD A,D - OUT (AY_RSEL),A - LD A,E - OUT (AY_RDAT),A + LD A,D ; SELECT THE REGISTER WE + OUT (AY_RSEL),A ; WANT TO WRITE TO + LD A,E ; WRITE THE VALUE TO + OUT (AY_RDAT),A ; THE SELECTED REGISTER #IF (CPUFAM == CPU_Z180) POP AF ; GET SAVED DCNTL VALUE OUT0 (Z180_DCNTL),A ; AND RESTORE IT diff --git a/Source/HBIOS/ay38910.asm b/Source/HBIOS/ay38910.asm new file mode 100644 index 00000000..8fe13b25 --- /dev/null +++ b/Source/HBIOS/ay38910.asm @@ -0,0 +1,556 @@ +;====================================================================== +; +; AY-3-8910 / YM2149 SOUND DRIVER +; +;====================================================================== +; +#IF (AYMODE == AYMODE_SCG) +AY_RSEL .EQU $9A +AY_RDAT .EQU $9B +AY_ACR .EQU $9C +#ENDIF +; +#IF (AYMODE == AYMODE_N8) +AY_RSEL .EQU $9C +AY_RDAT .EQU $9D +AY_ACR .EQU N8_DEFACR +#ENDIF +; +#IF (AYMODE == AYMODE_RCZ80) +AY_RSEL .EQU $D8 +AY_RDAT .EQU $D0 +#ENDIF +; +#IF (AYMODE == AYMODE_RCZ180) +AY_RSEL .EQU $68 +AY_RDAT .EQU $60 +#ENDIF +; +;====================================================================== +; +; REGISTERS +; +AY_R2CHBP .EQU $02 +AY_R3CHBP .EQU $03 +AY_R7ENAB .EQU $07 +AY_R8AVOL .EQU $08 +; +;====================================================================== +; +; DRIVER FUNCTION TABLE AND INSTANCE DATA +; +AY_FNTBL: + .DW AY_RESET + .DW AY_VOLUME + .DW AY_PERIOD + .DW AY_NOTE + .DW AY_PLAY + .DW AY_QUERY + +#IF (($ - AY_FNTBL) != (SND_FNCNT * 2)) + .ECHO "*** INVALID SND FUNCTION TABLE ***\n" + !!!!! +#ENDIF +; +AY_IDAT .EQU 0 ; NO INSTANCE DATA ASSOCIATED WITH THIS DEVICE +; +;====================================================================== +; +; DEVICE CAPABILITIES AND CONFIGURATION +; +SBCV2004 .EQU 1 ; 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 3579500 +AY_CLKDIV .EQU 2 +AY_CLK .EQU AY_PHICLK / AY_CLKDIV +; +#INCLUDE "audio.inc" +; +;====================================================================== +; +; DRIVER INITIALIZATION (THERE IS NO PRE-INITIALIZATION) +; +; ANNOUNCE DEVICE ON CONSOLE. ACTIVATE DEVICE IF REQUIRED. +; SETUP FUNCTION TABLES. SETUP THE DEVICE. +; ANNOUNCE DEVICE WITH BEEP. SET VOLUME OFF. +; RETURN INITIALIZATION STATUS +; +AY38910_INIT: + CALL NEWLINE ; ANNOUNCE + PRTS("AY: IO=0x$") + LD A,AY_RSEL + CALL PRTHEXBYTE +; +#IF ((AYMODE == AYMODE_SCG) | (AYMODE == AYMODE_N8)) + ; ACTIVATE DEVICE + LD A,$FF ; BIT 4 IS AY RESET CONTROL, BIT 3 IS ACTIVE LED + OUT (AY_ACR),A ; SET INIT AUX CONTROL REG +#ENDIF +; + LD IY, AY_IDAT ; SETUP FUNCTION TABLE + LD BC, AY_FNTBL ; POINTER TO INSTANCE DATA + LD DE, AY_IDAT ; BC := FUNCTION TABLE ADDRESS + CALL SND_ADDENT ; DE := INSTANCE DATA PTR +; + CALL AY_INIT ; SET DEFAULT CHIP CONFIGURATION +; + LD E,$07 ; SET VOLUME TO 50% + CALL AY_SETV ; ON ALL CHANNELS +; + LD D,AY_R2CHBP ; BEEP ON CHANNEL B (CENTER) + LD E,$55 + CALL AY_WRTPSG ; R02 = $55 = 01010101 + LD D,AY_R3CHBP + LD E,$00 + CALL AY_WRTPSG ; R03 = $00 = XXXX0000 +; + CALL LDELAY ; HALF SECOND +; + LD E,$00 ; SET VOLUME OFF + CALL AY_SETV ; ON ALL CHANNELS +; +; RET +; +;====================================================================== +; INITIALIZE DEVICE +;====================================================================== +; +AY_INIT: + LD D,AY_R7ENAB ; SET MIXER CONTROL / IO ENABLE + LD E,$F8 ; $F8 - 11 111 000 + CALL AY_WRTPSG ; I/O PORTS = OUTPUT, NOISE CHANNEL C, B, A DISABLE, TONE CHANNEL C, B, A ENABLE + RET +; +;====================================================================== +; SET VOLUME ALL CHANNELS +;====================================================================== +; +AY_SETV: + LD B,AY_TONECNT ; NUMBER OF CHANNELS + LD D,AY_R8AVOL ; BASE REGISTER FOR VOLUME +AY_SV: CALL AY_WRTPSG ; CYCLING THROUGH ALL CHANNELS + INC D + DJNZ AY_SV + RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - RESET +; +; INITIALIZE DEVICE. SET VOLUME OFF. RESET VOLUME AND TONE VARIABLES. +; +;====================================================================== +; +AY_RESET: + AUDTRACE(TRACE_INIT) +; + CALL AY_INIT ; SET DEFAULT CHIP CONFIGURATION +; + AUDTRACE(TRACE_VOLUME_OFF) + LD E,0 ; SET VOLUME OFF + CALL AY_SETV ; ON ALL CHANNELS +; + XOR A ; SIGNAL SUCCESS + LD (PENDING_VOLUME),A ; SET VOLUME TO ZERO + LD H,A + LD L,A + LD (PENDING_PERIOD),HL ; SET TONE PERIOD TO ZERO +; + RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - VOLUME +;====================================================================== +; +AY_VOLUME: + AUDDEBUG("AY3VOL ") + AUDTRACE_L + AUDDEBUG("\r\n") + LD A,L ; SAVE VOLUME + LD (PENDING_VOLUME), A +; + XOR A ; SIGNAL SUCCESS + RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - PERIOD +;====================================================================== +; +AY_PERIOD: + AUDDEBUG("AY3PRD ") + AUDTRACE_HL + AUDDEBUG("\r\n") + + LD A, H ; MAXIMUM TONE PERIOD IS 12-BITS + CP $10 ; ALLOWED RANGE IS 0001-0FFF (4095) + JP NC, AY_QUERY_PERIOD1 ; RETURN NZ IF NUMBER TOO LARGE + + LD (PENDING_PERIOD), HL ; SAVE AND + XOR A ; SIGNAL SUCCESS + RET + +AY_QUERY_PERIOD1: + LD L, $FF + LD H, L ; REQUESTED PERIOD IS LARGER + LD (PENDING_PERIOD), HL ; THAN THE DEVICE CAN SUPPORT + OR L ; SO SIGNAL FAILURE + RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - NOTE +;====================================================================== +; +AY_NOTE: + AUDDEBUG("AY3NOT ") + AUDTRACE_L + AUDDEBUG("\r\n") + + ADD HL, HL ; SHIFT RIGHT (MULT 2) -INDEX INTO AY3NOTETBL TABLE OF WORDS + ; TEST IF HL IS LARGER THAN AY3NOTETBL SIZE + OR A ; CLEAR CARRY FLAG + LD DE, SIZ_AY3NOTETBL + SBC HL, DE + JR NC, AY_NOTE1 ; INCOMING HL DOES NOT MAP INTO AY3NOTETBL + + ADD HL, DE ; RESTORE HL + LD E, L ; HL = AY3NOTETBL + HL + LD D, H + LD HL, AY3NOTETBL + ADD HL, DE + + LD A, (HL) ; RETRIEVE PERIOD COUNT FROM AY3NOTETBL + INC HL + LD H, (HL) + LD L, A + + JR AY_PERIOD ; APPLY NOTE PERIOD + +AY_NOTE1: + OR $FF ; NOT IMPLEMENTED YET + RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - PLAY +;====================================================================== +; +AY_PLAY: + AUDDEBUG("AY3PLY ") + AUDTRACE_D + AUDDEBUG("\r\n") +; + LD A, (PENDING_PERIOD + 1) ; CHECK THE HIGH BYTE OF THE PERIOD + CP $FF + JR Z, AY_PLAY1 ; PERIOD IS TOO LARGE, UNABLE TO PLAY + CALL AY_APPLY_VOL + CALL AY_APPLY_PRD +; + XOR A ; SIGNAL SUCCESS + RET +; +AY_PLAY1: ; TURN CHANNEL VOL TO OFF AND STOP PLAYING + LD A, (PENDING_VOLUME) + PUSH AF + XOR A + LD (PENDING_VOLUME), A + CALL AY_APPLY_VOL + POP AF + LD (PENDING_VOLUME), A +; + OR $FF ; SIGNAL FAILURE + RET +; +;====================================================================== +; SOUND DRIVER FUNCTION - QUERY AND SUBFUNCTIONS +;====================================================================== +; +AY_QUERY: + LD A, E + CP BF_SNDQ_CHCNT ; SUB FUNCTION 01 + JR Z, AY_QUERY_CHCNT +; + CP BF_SNDQ_VOLUME ; SUB FUNCTION 02 + JR Z, AY_QUERY_VOLUME +; + CP BF_SNDQ_PERIOD ; SUB FUNCTION 03 + JR Z, AY_QUERY_PERIOD +; + CP BF_SNDQ_DEV ; SUB FUNCTION 04 + JR Z, AY_QUERY_DEV +; + OR $FF ; SIGNAL FAILURE + RET +; +AY_QUERY_CHCNT: + LD B, AY_TONECNT ; RETURN NUMBER OF + LD C, AY_NOISECNT ; TONE AND NOISE + XOR A ; CHANNELS IN BC + RET +; +AY_QUERY_PERIOD: + LD HL, (PENDING_PERIOD) ; RETURN 16-BIT PERIOD + XOR A ; IN HL REGISTER + RET +; +AY_QUERY_VOLUME: + LD A, (PENDING_VOLUME) ; RETURN 8-BIT VOLUME + LD L, A ; IN L REGISTER + XOR A + LD H, A + RET +; +AY_QUERY_DEV: + LD B, BF_SND_AY38910 ; RETURN DEVICE IDENTIFIER + LD DE, (AY_RSEL*256)+AY_RDAT ; AND ADDRESS AND DATA PORT + XOR A + RET +; +;====================================================================== +; APPLY VOLUME TO CHANNEL IN D REGISTER +;====================================================================== +; +AY_APPLY_VOL: + PUSH DE + PUSH BC + PUSH AF +; + LD A,D ; LIMIT CHANNEL 0-2 + AND $3 ; AND INDEX TO THE + ADD A,AY_R8AVOL ; CHANNEL VOLUME + LD D,A ; REGISTER +; + AUDTRACE(TRACE_REG_WR) + AUDTRACE_A + AUDTRACE(TRACE_NEWLINE) +; + LD A, (PENDING_VOLUME) ; MAP THE VOLUME + RRCA ; FROM 00-FF + RRCA ; TO 00-0F + RRCA + RRCA + AND $0F + LD E,A +; + CALL AY_WRTPSG ; SET VOL (E) IN CHANNEL REG (D) +; + POP AF + POP BC + POP DE + RET +; +;====================================================================== +; APPLY PERIOD TO CHANNEL IN D REGISTER +;====================================================================== +; +AY_APPLY_PRD: + PUSH DE + PUSH BC + PUSH AF +; + LD A,D ; LIMIT CHANNEL 0-2 + AND $3 ; AND INDEX TO THE + ADD A,A ; CHANNEL REGISTER + LD D,A ; FOR THE TONE PERIOD +; + AUDTRACE(TRACE_REG_WR) + AUDTRACE_A + AUDTRACE(TRACE_NEWLINE) +; + LD HL,(PENDING_PERIOD) ; WRITE THE LOWER + LD E,L ; 8-BITS OF THE TONE PERIOD + CALL AY_WRTPSG + INC D + LD E,H ; WRITE THE UPPER + CALL AY_WRTPSG ; 8-BITS OF THE TONE PERIOD +; + POP AF + POP BC + POP DE + RET +; +;====================================================================== +; +; WRITE DATA IN E REGISTER TO DEVICE REGISTER D +; INTERRUPTS DISABLE DURING WRITE. WRITE IN SLOW MODE IF Z180 CPU. +; +;====================================================================== +; +AY_WRTPSG: + HB_DI +#IF (SBCV2004) + LD A,8 ; SBC-V2-004 CHANGE + OUT (112),A ; TO HALF CLOCK SPEED +#ENDIF +#IF (CPUFAM == CPU_Z180) + IN0 A,(Z180_DCNTL) ; GET WAIT STATES + PUSH AF ; SAVE VALUE + OR %00110000 ; FORCE SLOW OPERATION (I/O W/S=3) + OUT0 (Z180_DCNTL),A ; AND UPDATE DCNTL +#ENDIF + LD A,D ; SELECT THE REGISTER WE + OUT (AY_RSEL),A ; WANT TO WRITE TO + LD A,E ; WRITE THE VALUE TO + OUT (AY_RDAT),A ; THE SELECTED REGISTER +#IF (CPUFAM == CPU_Z180) + POP AF ; GET SAVED DCNTL VALUE + OUT0 (Z180_DCNTL),A ; AND RESTORE IT +#ENDIF +#IF (SBCV2004) + LD A,0 ; SBC-V2-004 CHANGE TO + OUT (112),A ; NORMAL CLOCK SPEED +#ENDIF + HB_EI + RET +; +;====================================================================== +; +PENDING_PERIOD .DW 0 ; PENDING PERIOD (12 BITS) +PENDING_VOLUME .DB 0 ; PENDING VOL (8 BITS) + +#IF AUDIOTRACE +TRACE_INIT .DB "\r\nAY_INIT CALLED\r\n$" +TRACE_VOLUME_OFF .DB "\r\nAY_VOLUME_OFF\r\n$" +TRACE_VOLUME_SET .DB "\r\nAY_VOLUME_SET CH: $" +TRACE_PLAY .DB "\r\nPLAY\r\n$" +TRACE_VOLUME .DB ", VOL: $" +TRACE_REG_WR .DB "\r\nOUT AY-3-8910 $" +TRACE_PERIOD_SET .DB "\r\nAY_PERIOD_SET CH: $" +TRACE_PERIOD .DB ", PERIOD: $" +TRACE_NEWLINE .DB "\r\n$" +#ENDIF +; +; THE FREQUENCY BY QUARTER TONE STARTING AT A1# +; +;====================================================================== +; FREQUENCY TONE TABLE +;====================================================================== +; +; PERIOD OCTAVE NOTE MIDI# +; +AY3NOTETBL: +; .DW 6842 ;0 12 +; .DW 6458 ;0 13 +; .DW 6096 ;0 14 +; .DW 5751 ;0 15 +; .DW 5430 ;0 16 +; .DW 5124 ;0 17 +; .DW 4838 ;0 18 +; .DW 4566 ;0 19 +; .DW 4309 ;0 20 + .DW 4068 ;0 A0 21 + .DW 3839 ;0 22 + .DW 3624 ;0 23 + .DW 3421 ;1 24 + .DW 3228 ;1 25 + .DW 3047 ;1 26 + .DW 2876 ;1 27 + .DW 2715 ;1 28 + .DW 2563 ;1 29 + .DW 2419 ;1 30 + .DW 2283 ;1 31 + .DW 2155 ;1 32 + .DW 2034 ;1 33 + .DW 1920 ;1 34 + .DW 1812 ;1 35 + .DW 1710 ;2 36 + .DW 1614 ;2 37 + .DW 1524 ;2 38 + .DW 1438 ;2 39 + .DW 1357 ;2 40 + .DW 1281 ;2 41 + .DW 1209 ;2 42 + .DW 1141 ;2 43 + .DW 1077 ;2 44 + .DW 1017 ;2 45 + .DW 960 ;2 46 + .DW 906 ;2 47 + .DW 855 ;3 48 + .DW 807 ;3 49 + .DW 762 ;3 50 + .DW 719 ;3 51 + .DW 679 ;3 52 + .DW 641 ;3 53 + .DW 605 ;3 54 + .DW 571 ;3 55 + .DW 539 ;3 56 + .DW 508 ;3 57 + .DW 480 ;3 58 + .DW 453 ;3 59 + .DW 428 ;4 60 + .DW 404 ;4 61 + .DW 381 ;4 62 + .DW 360 ;4 63 + .DW 339 ;4 64 + .DW 320 ;4 65 + .DW 302 ;4 66 + .DW 285 ;4 67 + .DW 269 ;4 68 + .DW 254 ;4 69 + .DW 240 ;4 70 + .DW 226 ;4 71 + .DW 214 ;5 72 + .DW 202 ;5 73 + .DW 190 ;5 74 + .DW 180 ;5 75 + .DW 170 ;5 76 + .DW 160 ;5 77 + .DW 151 ;5 78 + .DW 143 ;5 79 + .DW 135 ;5 80 + .DW 127 ;5 81 + .DW 120 ;5 82 + .DW 113 ;5 83 + .DW 107 ;6 84 + .DW 101 ;6 85 + .DW 95 ;6 86 + .DW 90 ;6 87 + .DW 85 ;6 88 + .DW 80 ;6 89 + .DW 76 ;6 90 + .DW 71 ;6 91 + .DW 67 ;6 92 + .DW 64 ;6 93 + .DW 60 ;6 94 + .DW 57 ;6 95 + .DW 53 ;7 96 + .DW 50 ;7 97 + .DW 48 ;7 98 + .DW 45 ;7 99 + .DW 42 ;7 100 + .DW 40 ;7 101 + .DW 38 ;7 102 + .DW 36 ;7 103 + .DW 34 ;7 104 + .DW 32 ;7 105 + .DW 30 ;7 106 + .DW 28 ;7 107 + .DW 27 ;8 108 + .DW 25 ;8 109 + .DW 24 ;8 110 + .DW 22 ;8 111 + .DW 21 ;8 112 + .DW 20 ;8 113 + .DW 19 ;8 114 + .DW 18 ;8 115 + .DW 17 ;8 116 + .DW 16 ;8 117 + .DW 15 ;8 118 + .DW 14 ;8 119 + .DW 13 ;9 120 + .DW 13 ;9 121 + .DW 12 ;9 122 + .DW 11 ;9 123 + .DW 11 ;9 124 + .DW 10 ;9 125 + .DW 9 ;9 126 + .DW 9 ;9 127 + .DW 8 ;9 128 + +SIZ_AY3NOTETBL .EQU $ - AY3NOTETBL + .ECHO "AY-3-8910 approx " + .ECHO SIZ_AY3NOTETBL / 2 / 12 + .ECHO " Octaves. Last note index supported: " + + .ECHO SIZ_AY3NOTETBL / 2 + .ECHO "\n" diff --git a/Source/HBIOS/cfg_dyno.asm b/Source/HBIOS/cfg_dyno.asm index 6f85b242..23f330c7 100644 --- a/Source/HBIOS/cfg_dyno.asm +++ b/Source/HBIOS/cfg_dyno.asm @@ -158,4 +158,5 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AY38910ENABLE .EQU FALSE ; AY-3-8910 SOUND DRIVER AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_ezz80.asm b/Source/HBIOS/cfg_ezz80.asm index a6646994..189fa5f6 100644 --- a/Source/HBIOS/cfg_ezz80.asm +++ b/Source/HBIOS/cfg_ezz80.asm @@ -183,4 +183,5 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AY38910ENABLE .EQU FALSE ; AY-3-8910 SOUND DRIVER AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_master.asm b/Source/HBIOS/cfg_master.asm index 7c3f00ab..c8255606 100644 --- a/Source/HBIOS/cfg_master.asm +++ b/Source/HBIOS/cfg_master.asm @@ -238,4 +238,5 @@ UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) UFBASE .EQU $0C ; UF: REGISTERS BASE ADR SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AY38910ENABLE .EQU FALSE ; AY-3-8910 SOUND DRIVER AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_mk4.asm b/Source/HBIOS/cfg_mk4.asm index e869de18..da75f165 100644 --- a/Source/HBIOS/cfg_mk4.asm +++ b/Source/HBIOS/cfg_mk4.asm @@ -192,4 +192,5 @@ UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) UFBASE .EQU $0C ; UF: REGISTERS BASE ADR SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AY38910ENABLE .EQU FALSE ; AY-3-8910 SOUND DRIVER AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_n8.asm b/Source/HBIOS/cfg_n8.asm index 9e016cf8..d32b7edf 100644 --- a/Source/HBIOS/cfg_n8.asm +++ b/Source/HBIOS/cfg_n8.asm @@ -192,4 +192,5 @@ UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) FIFO_BASE .EQU $0C ; UF: REGISTERS BASE ADR SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AY38910ENABLE .EQU FALSE ; AY-3-8910 SOUND DRIVER AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_rcz180.asm b/Source/HBIOS/cfg_rcz180.asm index 2f04e152..bd6e086c 100644 --- a/Source/HBIOS/cfg_rcz180.asm +++ b/Source/HBIOS/cfg_rcz180.asm @@ -192,4 +192,5 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AY38910ENABLE .EQU FALSE ; AY-3-8910 SOUND DRIVER AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_rcz80.asm b/Source/HBIOS/cfg_rcz80.asm index 61de3c2e..b2b072d0 100644 --- a/Source/HBIOS/cfg_rcz80.asm +++ b/Source/HBIOS/cfg_rcz80.asm @@ -198,4 +198,5 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AY38910ENABLE .EQU FALSE ; AY-3-8910 SOUND DRIVER AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_sbc.asm b/Source/HBIOS/cfg_sbc.asm index 329944b4..f5da3829 100644 --- a/Source/HBIOS/cfg_sbc.asm +++ b/Source/HBIOS/cfg_sbc.asm @@ -194,4 +194,5 @@ UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) UFBASE .EQU $0C ; UF: REGISTERS BASE ADR SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AY38910ENABLE .EQU FALSE ; AY-3-8910 SOUND DRIVER AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_scz180.asm b/Source/HBIOS/cfg_scz180.asm index 955790e7..9183f448 100644 --- a/Source/HBIOS/cfg_scz180.asm +++ b/Source/HBIOS/cfg_scz180.asm @@ -187,4 +187,5 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AY38910ENABLE .EQU FALSE ; AY-3-8910 SOUND DRIVER AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_zeta.asm b/Source/HBIOS/cfg_zeta.asm index 979d4975..a8b9eea6 100644 --- a/Source/HBIOS/cfg_zeta.asm +++ b/Source/HBIOS/cfg_zeta.asm @@ -138,4 +138,5 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AY38910ENABLE .EQU FALSE ; AY-3-8910 SOUND DRIVER AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/cfg_zeta2.asm b/Source/HBIOS/cfg_zeta2.asm index 31b97c7f..d76fcef6 100644 --- a/Source/HBIOS/cfg_zeta2.asm +++ b/Source/HBIOS/cfg_zeta2.asm @@ -148,4 +148,5 @@ PPI_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP UFENABLE .EQU FALSE ; UF: ENABLE ECB USB FIFO DRIVER (UF.ASM) SN76489ENABLE .EQU FALSE ; SN76489 SOUND DRIVER +AY38910ENABLE .EQU FALSE ; AY-3-8910 SOUND DRIVER AUDIOTRACE .EQU FALSE ; ENABLE TRACING TO CONSOLE OF SOUND DRIVER diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 708b57ef..3e058bd1 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -1677,6 +1677,9 @@ HB_INITTBL: #IF (SN76489ENABLE) .DW SN76489_INIT #ENDIF +#IF (AY38910ENABLE) + .DW AY38910_INIT +#ENDIF #IF (ASCIENABLE) .DW ASCI_INIT #ENDIF @@ -3352,6 +3355,14 @@ SIZ_SN76489 .EQU $ - ORG_SN76489 .ECHO SIZ_SN76489 .ECHO " bytes.\n" #ENDIF +#IF (AY38910ENABLE) +ORG_AY38910 .EQU $ + #INCLUDE "ay38910.asm" +SIZ_AY38910 .EQU $ - ORG_AY38910 + .ECHO "AY38910 occupies " + .ECHO SIZ_AY38910 + .ECHO " bytes.\n" +#ENDIF ; #DEFINE USEDELAY #INCLUDE "util.asm" diff --git a/Source/HBIOS/hbios.inc b/Source/HBIOS/hbios.inc index a0f22099..a07e8a27 100644 --- a/Source/HBIOS/hbios.inc +++ b/Source/HBIOS/hbios.inc @@ -72,7 +72,7 @@ BF_SNDQ_DEV .EQU BF_SNDQ_STATUS + 4 ; RETURN DEVICE TYPE CODE AND IO PORTS - TY BF_SNDDEV .EQU 0 ; TYPES OF SOUND DRIVERS BF_SND_SN76489 .EQU BF_SNDDEV + 1 -BF_SND_SNAY38910 .EQU BF_SNDDEV + 2 +BF_SND_AY38910 .EQU BF_SNDDEV + 2 ; BF_SYS .EQU $F0 diff --git a/Source/HBIOS/sn76489.asm b/Source/HBIOS/sn76489.asm index 4ce9546b..5d849893 100644 --- a/Source/HBIOS/sn76489.asm +++ b/Source/HBIOS/sn76489.asm @@ -347,7 +347,7 @@ SN7_FNTBL: PENDING_PERIOD .DW 0 ; PENDING PERIOD (10 BITS) PENDING_VOLUME - .DB 0 ; PENDING VOL (8 BITS -> DOWNOVERTED TO 4 BITS AND INVERTED) + .DB 0 ; PENDING VOL (8 BITS -> DOWNCONVERTED TO 4 BITS AND INVERTED) STR_MESSAGELT .DB "\r\nSN76489: LEFT IO=0x$" STR_MESSAGERT .DB ", RIGHT IO=0x$" @@ -364,7 +364,7 @@ TRACE_PERIOD .DB ", PERIOD: $" TRACE_NEWLINE .DB "\r\n$" #ENDIF -; THE FREQUENCY BY QUATER TONE STARTING AT A1# +; THE FREQUENCY BY QUARTER TONE STARTING AT A1# SN7NOTETBL: .DW A1S .DW SN7RATIO / 5912