From afbc00d78c33b88db4fffc4d60de4538218e0376 Mon Sep 17 00:00:00 2001 From: b1ackmai1er Date: Sun, 3 May 2020 20:28:44 +0800 Subject: [PATCH] ay38910 updates cleanups, optimizations, protect registers --- Source/HBIOS/ay38910.asm | 200 ++++++++++++++++++--------------------- 1 file changed, 93 insertions(+), 107 deletions(-) diff --git a/Source/HBIOS/ay38910.asm b/Source/HBIOS/ay38910.asm index 4b6c863f..6e109b4e 100644 --- a/Source/HBIOS/ay38910.asm +++ b/Source/HBIOS/ay38910.asm @@ -58,7 +58,7 @@ 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 +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 @@ -107,7 +107,7 @@ AY38910_INIT: LD E,$00 CALL AY_WRTPSG ; R03 = $00 = XXXX0000 ; - CALL LDELAY ; HALF SECOND + CALL LDELAY ; HALF SECOND DELAY ; LD E,$00 ; SET VOLUME OFF CALL AY_SETV ; ON ALL CHANNELS @@ -146,6 +146,8 @@ AY_SV: CALL AY_WRTPSG ; CYCLING THROUGH ALL CHANNELS AY_RESET: AUDTRACE(AYT_INIT) ; + PUSH DE + PUSH HL CALL AY_INIT ; SET DEFAULT CHIP CONFIGURATION ; AUDTRACE(AYT_VOLOFF) @@ -158,6 +160,8 @@ AY_RESET: LD L,A LD (AY_PENDING_PERIOD),HL ; SET TONE PERIOD TO ZERO ; + POP HL + POP DE RET ; ;====================================================================== @@ -182,22 +186,19 @@ AY_PERIOD: AUDTRACE(AYT_PERIOD) AUDTRACE_HL AUDTRACE_CR - +; 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 (AY_PENDING_PERIOD), HL ; SAVE AND - XOR A ; SIGNAL SUCCESS - RET - -AY_QUERY_PERIOD1: - LD L, $FF - LD H, L ; REQUESTED PERIOD IS LARGER - LD (AY_PENDING_PERIOD), HL ; THAN THE DEVICE CAN SUPPORT - OR L ; SO SIGNAL FAILURE + 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 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 + RET ; AND RETURN FAILURE +; ;====================================================================== ; SOUND DRIVER FUNCTION - NOTE ;====================================================================== @@ -206,33 +207,44 @@ AY_NOTE: AUDTRACE(AYT_NOTE) AUDTRACE_L AUDTRACE_CR - +; + PUSH HL + PUSH DE + LD H,0 ADD HL, HL ; SHIFT RIGHT (MULT 2) -INDEX INTO AY3NOTETBL TABLE OF WORDS - ; TEST IF HL IS LARGER THAN AY3NOTETBL SIZE +; ; 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 + EX DE,HL + LD HL, AY3NOTETBL ; HL = AY3NOTETBL + HL 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 - +; + CALL AY_PERIOD ; APPLY NOTE PERIOD + POP DE + POP HL + RET +; AY_NOTE1: + POP DE + POP HL OR $FF ; NOT IMPLEMENTED YET RET ; ;====================================================================== ; SOUND DRIVER FUNCTION - PLAY +; B = FUNCTION +; C = AUDIO DEVICE +; D = CHANNEL +; A = EXIT STATUS ;====================================================================== ; AY_PLAY: @@ -241,23 +253,63 @@ AY_PLAY: AUDTRACE_CR ; LD A, (AY_PENDING_PERIOD + 1) ; CHECK THE HIGH BYTE OF THE PERIOD - CP $FF + INC A JR Z, AY_PLAY1 ; PERIOD IS TOO LARGE, UNABLE TO PLAY - CALL AY_APPLY_VOL - CALL AY_APPLY_PRD +; + PUSH HL + PUSH DE + 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(AYT_REGWR) + AUDTRACE_A + AUDTRACE_CR +; + LD HL,AY_PENDING_PERIOD ; WRITE THE LOWER + ld E,(HL) ; 8-BITS OF THE TONE PERIOD + CALL AY_WRTPSG + INC D ; NEXT REGISTER + INC HL ; NEXT BYTE + LD E,(HL) ; WRITE THE UPPER + CALL AY_WRTPSG ; 8-BITS OF THE TONE PERIOD +; + POP DE ; RECALL CHANNEL + PUSH DE ; SAVE CHANNEL +; + LD A,D ; LIMIT CHANNEL 0-2 + AND $3 ; AND INDEX TO THE + ADD A,AY_R8AVOL ; CHANNEL VOLUME + LD D,A ; REGISTER +; + AUDTRACE(AYT_REGWR) + AUDTRACE_A + AUDTRACE_CR +; + INC HL ; NEXT BYTE + LD E,(HL) + SRL E ; MAP THE VOLUME + SRL E ; FROM 00-FF + SRL E ; TO 00-0F + SRL E + CALL AY_WRTPSG ; SET VOL (E) IN CHANNEL REG (D) +; + POP DE ; RECALL CHANNEL + POP HL ; XOR A ; SIGNAL SUCCESS RET ; -AY_PLAY1: ; TURN CHANNEL VOL TO OFF AND STOP PLAYING - LD A, (AY_PENDING_VOLUME) - PUSH AF - XOR A - LD (AY_PENDING_VOLUME), A - CALL AY_APPLY_VOL - POP AF - LD (AY_PENDING_VOLUME), A -; +AY_PLAY1: + PUSH DE ; TURN VOLUME OFF TO STOP PLAYING + LD A,D ; LIMIT CHANNEL 0-2 + AND $3 ; AND INDEX TO THE + ADD A,AY_R8AVOL ; CHANNEL VOLUME + LD D,A ; REGISTER + LD E,0 + CALL AY_WRTPSG ; SET VOL (E) IN CHANNEL REG (D) + POP DE OR $FF ; SIGNAL FAILURE RET ; @@ -307,70 +359,6 @@ AY_QUERY_DEV: 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(AYT_REGWR) - AUDTRACE_A - AUDTRACE_CR -; - LD A, (AY_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(AYT_REGWR) - AUDTRACE_A - AUDTRACE_CR - -; - LD HL,(AY_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. @@ -406,9 +394,9 @@ AY_WRTPSG: ; ;====================================================================== ; -AY_PENDING_PERIOD .DW 0 ; PENDING PERIOD (12 BITS) -AY_PENDING_VOLUME .DB 0 ; PENDING VOL (8 BITS) - +AY_PENDING_PERIOD .DW 0 ; PENDING PERIOD (12 BITS) ; ORDER +AY_PENDING_VOLUME .DB 0 ; PENDING VOL (8 BITS) ; SIGNIFICANT +; #IF AUDIOTRACE AYT_INIT .DB "\r\nAY_INIT\r\n$" AYT_VOLOFF .DB "\r\nAY_VOLUME OFF\r\n$" @@ -419,10 +407,8 @@ AYT_PLAY .DB "\r\nAY_PLAY CH: $" AYT_REGWR .DB "\r\nOUT AY-3-8910 $" #ENDIF ; -; THE FREQUENCY BY QUARTER TONE STARTING AT A1# -; ;====================================================================== -; FREQUENCY TONE TABLE +; FREQUENCY TONE TABLE (SEMITONE CURRENTLY) ;====================================================================== ; ; PERIOD OCTAVE NOTE MIDI#