mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
3.4 KiB
102 lines
3.4 KiB
#IF AUDIOTRACE
|
|
;
|
|
#DEFINE AUDTRACE(STR) PUSH DE \ LD DE, STR \ CALL WRITESTR \ POP DE
|
|
#DEFINE AUDTRACE_A CALL PRTHEXBYTE
|
|
#DEFINE AUDTRACE_B PUSH AF \ LD A, B \ CALL PRTHEXBYTE \ POP AF
|
|
#DEFINE AUDTRACE_D PUSH AF \ LD A, D \ CALL PRTHEXBYTE \ POP AF
|
|
#DEFINE AUDTRACE_E PUSH AF \ LD A, E \ CALL PRTHEXBYTE \ POP AF
|
|
#DEFINE AUDTRACE_L PUSH AF \ LD A, L \ CALL PRTHEXBYTE \ POP AF
|
|
#DEFINE AUDTRACE_HL CALL PRTHEXWORDHL
|
|
#DEFINE AUDTRACE_BC PUSH HL \ PUSH BC \ POP HL \ CALL PRTHEXWORDHL \ POP HL
|
|
#DEFINE AUDTRACE_DE PUSH HL \ PUSH DE \ POP HL \ CALL PRTHEXWORDHL \ POP HL
|
|
#DEFINE AUDTRACE_IY PUSH HL \ PUSH IY \ POP HL \ CALL PRTHEXWORDHL \ POP HL
|
|
;
|
|
#DEFINE AUDDEBUG(S) push hl \ CALL PRTSTRD \ .TEXT S \ .TEXT "$" \ pop hl ; $$$$$$ PRINT STRING S TO CONSOLE - PRTD("HELLO") - NO TRAILING $ REQUIRED
|
|
;
|
|
#DEFINE AUDTRACE_CR AUDDEBUG("\r\n$")
|
|
;
|
|
#ELSE
|
|
;
|
|
#DEFINE AUDTRACE(S)
|
|
#DEFINE AUDTRACE_A
|
|
#DEFINE AUDTRACE_B
|
|
#DEFINE AUDTRACE_D
|
|
#DEFINE AUDTRACE_E
|
|
#DEFINE AUDTRACE_L
|
|
#DEFINE AUDTRACE_BC
|
|
#DEFINE AUDTRACE_HL
|
|
#DEFINE AUDTRACE_DE
|
|
#DEFINE AUDTRACE_IY
|
|
;
|
|
#DEFINE AUDDEBUG(STR)
|
|
;
|
|
#DEFINE AUDTRACE_CR
|
|
;
|
|
#ENDIF
|
|
;
|
|
#IFNDEF AUDIO_INC
|
|
#DEFINE AUDIO_INC
|
|
;
|
|
; NOTE TABLE VALUES ARE SHIFTED A FEW EXTRA BITS TO MAKE THE
|
|
; DIVISION AS ACCURATE AS POSSIBLE.
|
|
;
|
|
AUD_SCALE .EQU 3
|
|
;
|
|
; ON ENTRY, DE IS ADDRESS OF NOTE TABLE, HL IS NOTE TO PLAY
|
|
; NOTE VALUE 0 MEANS B0b/A0# IN OCTAVE 0 WHICH IS THE FIRST ENTRY
|
|
; OF THE NOTE TABLE. THE NOTE TABLE REPRESENTS THE FREQUENCIES
|
|
; FOR 1 FULL OCTAVE IN QUARTER NOTES. SINCE THERE ARE 12 NOTES
|
|
; IN AN OCTAVE, THE TABLE HAS 48 ENTRIES FOR ALL QUARTER NOTES.
|
|
;
|
|
; ON EXIT, HL CONTAINS THE PERIOD VALUE TO PROGRAM INTO THE PSG
|
|
; DERIVED FROM THE NOTE TABLE SCALED TO THE REQUESTED OCTAVE.
|
|
;
|
|
AUD_NOTE:
|
|
AUDDEBUG("AUDNOTE ")
|
|
AUDTRACE_HL
|
|
AUDTRACE_CR
|
|
AUDTRACE_DE
|
|
AUDTRACE_CR
|
|
;
|
|
; START BY SEPARATING THE NOTE AND OCTAVE PORTION
|
|
; OF THE INCOMING TONE VALUE IN HL
|
|
PUSH DE ; SAVE NOTE TABLE ADR
|
|
LD DE,48 ; 48 QUARTERNOTES PER OCTAVE
|
|
CALL DIV16 ; SEPARATE OCTAVE AND NOTE
|
|
;
|
|
; THE QUOTIENT (BC) IS THE OCTAVE NUMBER REQUESTED
|
|
; THE REMAINDER (HL) IS THE QUARTER NOTE WITHIN THE OCTAVE.
|
|
;
|
|
; NOW USE THE QUARTER NOTE VALUE TO LOOKUP THE CORRESPONDING
|
|
; PSG PERIOD VALUE IN THE NOTE TABLE.
|
|
ADD HL,HL ; SCALE FOR 2 BYTE TABLE ENTRY SIZE
|
|
POP DE ; RECOVER THE TABLE ADR
|
|
ADD HL,DE ; HL := DESIRED TABLE ENTRY ADR
|
|
LD A,(HL) ; GET LOW BYTE OF PERIOD TO A
|
|
INC HL ; POINT TO HIGH BYTE VALUE
|
|
LD H,(HL) ; GET HIGH BYTE OF PERIOD TO H
|
|
LD L,A ; PUT LOW BYTE INTO L
|
|
;
|
|
; NOW WE SCALE THE PERIOD VALUE DOWN BASED ON THE OCTAVE VALUE IN C
|
|
; AND BY THE AUD_SCALE VALUE THAT WAS USED IN THE NOTE TABLE.
|
|
; FOR EACH OCTAVE, THE PERIOD IS HALVED WHICH DOUBLES THE FREQUENCY
|
|
; THAT WILL BE PRODUCED BY THE PSG. SINCE MOVING UP AN OCTAVE
|
|
; SHOULD PRODUCE A FREQUENCY THAT IS TWICE THE LOWER OCTIAVE, THIS
|
|
; WORKS NICELY, ALTHOUGH SOME ERROR MAY BE INTRODUCED.
|
|
;
|
|
LD A,AUD_SCALE ; SHIFT BY AUD_SCALE BITS
|
|
ADD A,C ; ... AND OCTAVE
|
|
LD B,A ; USE AS LOOP COUNTER
|
|
AUD_NOTE1:
|
|
SRL H ; RIGHT SHIFT HL
|
|
RR L ; ... BY ONE BIT
|
|
DJNZ AUD_NOTE1 ; LOOP UNTIL DONE
|
|
;
|
|
; IF THE RESULTANT PERIOD IS ZERO, IT MEANS THAT THE REQUESTED
|
|
; PERIOD IS TOO LOW (FREQUENCY TOO HIGH) FOR THE PSG TO PRODUCE.
|
|
LD A, L ; CHECK FOR ZERO
|
|
OR H ; ... MEANING PSG CAN'T DO IT
|
|
RET NZ ; IF NOT ZERO, RETURN THE CALCULATED PERIOD
|
|
DEC HL ; OTHERWISE RETURN -1 PERIOD (ERROR)
|
|
RET
|
|
#ENDIF
|
|
|