Browse Source

ay38910 updates

cleanups, optimizations, protect registers
pull/120/head
b1ackmai1er 6 years ago
parent
commit
afbc00d78c
  1. 200
      Source/HBIOS/ay38910.asm

200
Source/HBIOS/ay38910.asm

@ -58,7 +58,7 @@ AY_IDAT .EQU 0 ; NO INSTANCE DATA ASSOCIATED WITH THIS DEVICE
; ;
; DEVICE CAPABILITIES AND CONFIGURATION ; 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_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
@ -107,7 +107,7 @@ AY38910_INIT:
LD E,$00 LD E,$00
CALL AY_WRTPSG ; R03 = $00 = XXXX0000 CALL AY_WRTPSG ; R03 = $00 = XXXX0000
; ;
CALL LDELAY ; HALF SECOND
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
@ -146,6 +146,8 @@ AY_SV: CALL AY_WRTPSG ; CYCLING THROUGH ALL CHANNELS
AY_RESET: AY_RESET:
AUDTRACE(AYT_INIT) AUDTRACE(AYT_INIT)
; ;
PUSH DE
PUSH HL
CALL AY_INIT ; SET DEFAULT CHIP CONFIGURATION CALL AY_INIT ; SET DEFAULT CHIP CONFIGURATION
; ;
AUDTRACE(AYT_VOLOFF) AUDTRACE(AYT_VOLOFF)
@ -158,6 +160,8 @@ AY_RESET:
LD L,A LD L,A
LD (AY_PENDING_PERIOD),HL ; SET TONE PERIOD TO ZERO LD (AY_PENDING_PERIOD),HL ; SET TONE PERIOD TO ZERO
; ;
POP HL
POP DE
RET RET
; ;
;====================================================================== ;======================================================================
@ -182,22 +186,19 @@ AY_PERIOD:
AUDTRACE(AYT_PERIOD) AUDTRACE(AYT_PERIOD)
AUDTRACE_HL AUDTRACE_HL
AUDTRACE_CR AUDTRACE_CR
;
LD A, H ; MAXIMUM TONE PERIOD IS 12-BITS 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 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 ; SOUND DRIVER FUNCTION - NOTE
;====================================================================== ;======================================================================
@ -206,33 +207,44 @@ AY_NOTE:
AUDTRACE(AYT_NOTE) AUDTRACE(AYT_NOTE)
AUDTRACE_L AUDTRACE_L
AUDTRACE_CR AUDTRACE_CR
;
PUSH HL
PUSH DE
LD H,0
ADD HL, HL ; SHIFT RIGHT (MULT 2) -INDEX INTO AY3NOTETBL TABLE OF WORDS 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 OR A ; CLEAR CARRY FLAG
LD DE, SIZ_AY3NOTETBL LD DE, SIZ_AY3NOTETBL
SBC HL, DE SBC HL, DE
JR NC, AY_NOTE1 ; INCOMING HL DOES NOT MAP INTO AY3NOTETBL JR NC, AY_NOTE1 ; INCOMING HL DOES NOT MAP INTO AY3NOTETBL
;
ADD HL, DE ; RESTORE HL 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 ADD HL, DE
;
LD A, (HL) ; RETRIEVE PERIOD COUNT FROM AY3NOTETBL LD A, (HL) ; RETRIEVE PERIOD COUNT FROM AY3NOTETBL
INC HL INC HL
LD H, (HL) LD H, (HL)
LD L, A LD L, A
JR AY_PERIOD ; APPLY NOTE PERIOD
;
CALL AY_PERIOD ; APPLY NOTE PERIOD
POP DE
POP HL
RET
;
AY_NOTE1: AY_NOTE1:
POP DE
POP HL
OR $FF ; NOT IMPLEMENTED YET OR $FF ; NOT IMPLEMENTED YET
RET RET
; ;
;====================================================================== ;======================================================================
; SOUND DRIVER FUNCTION - PLAY ; SOUND DRIVER FUNCTION - PLAY
; B = FUNCTION
; C = AUDIO DEVICE
; D = CHANNEL
; A = EXIT STATUS
;====================================================================== ;======================================================================
; ;
AY_PLAY: AY_PLAY:
@ -241,23 +253,63 @@ AY_PLAY:
AUDTRACE_CR AUDTRACE_CR
; ;
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
CP $FF
INC A
JR Z, AY_PLAY1 ; PERIOD IS TOO LARGE, UNABLE TO PLAY 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 XOR A ; SIGNAL SUCCESS
RET 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 OR $FF ; SIGNAL FAILURE
RET RET
; ;
@ -307,70 +359,6 @@ AY_QUERY_DEV:
RET 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 ; WRITE DATA IN E REGISTER TO DEVICE REGISTER D
; INTERRUPTS DISABLE DURING WRITE. WRITE IN SLOW MODE IF Z180 CPU. ; 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 #IF AUDIOTRACE
AYT_INIT .DB "\r\nAY_INIT\r\n$" AYT_INIT .DB "\r\nAY_INIT\r\n$"
AYT_VOLOFF .DB "\r\nAY_VOLUME OFF\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 $" AYT_REGWR .DB "\r\nOUT AY-3-8910 $"
#ENDIF #ENDIF
; ;
; THE FREQUENCY BY QUARTER TONE STARTING AT A1#
;
;====================================================================== ;======================================================================
; FREQUENCY TONE TABLE
; FREQUENCY TONE TABLE (SEMITONE CURRENTLY)
;====================================================================== ;======================================================================
; ;
; PERIOD OCTAVE NOTE MIDI# ; PERIOD OCTAVE NOTE MIDI#

Loading…
Cancel
Save