forked from MirrorRepos/RomWBW
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.
892 lines
25 KiB
892 lines
25 KiB
;------------------------------------------------------------------------------
|
|
; YM2612 sound driver
|
|
; Written by: Phil Summers (b1ackmailer) difficultylevelhigh@gmail.com
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; References:
|
|
; https://hiddenpalace.org/News/Sega_of_Japan_Sound_Documents_and_Source_Code
|
|
; https://www.smspower.org/maxim/Documents/YM2612
|
|
; https://plutiedev.com/blog/20200103
|
|
; https://www.plutiedev.com/ym2612-registers
|
|
; https://www.plutiedev.com/ym2612-operations
|
|
; https://en.wikipedia.org/wiki/Scientific_pitch_notation
|
|
; https://gendev.spritesmind.net/forum/viewtopic.php?t=2915 (1)
|
|
; http://nemesis.hacking-cult.org/MegaDrive/Documentation/YM2608J.PDF
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Octave range is A#0-B7+3/4 HBIOS note 0..343
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
YMSEL .EQU VGMBASE+00H ; Primary YM2162 11000000 a1=0 a0=0
|
|
YMDAT .EQU VGMBASE+01H ; Primary YM2162 11000001 a1=0 a0=1
|
|
YM2SEL .EQU VGMBASE+02H ; Secondary YM2162 11000010 a1=1 a0=0
|
|
YM2DAT .EQU VGMBASE+03H ; Secondary YM2162 11000011 a1=1 a0=1
|
|
|
|
;------------------------------------------------------------------------------
|
|
; Device capabilities and configuration
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
YM_TONECNT .EQU 6 ; Count number of tone channels
|
|
YM_NOISECNT .EQU 0 ; Count number of noise channels
|
|
;
|
|
YM_PENDING_PERIOD .DW 0 ; PENDING PERIOD (12 BITS)
|
|
YM_PENDING_VOLUME .DB 0 ; PENDING VOL (8 BITS)
|
|
YM_PENDING_DURATION .DW 0 ; PENDING DURATION (16 BITS)
|
|
YM_READY .DB 0 ; BIT 0 -> NZ DRIVER IS READY TO RECEIVE PLAY COMMAND
|
|
; BIT 1 -> NZ EXECUTING WITHIN TIMER HANDLER = DO NOT DIS/ENABLE INT
|
|
YM_RDY_RST .DB 0 ; FLAG INDICATES IF DEVICE IS IN READY (NZ) OR RESET STATE (Z)
|
|
YM_DEBUG .EQU 0 ; CHANGE TO 1 TO ENABLE DEBUGGING
|
|
YM_RSTCFG .EQU 0 ; SET TO 1 FOR FULL REGISTER CLEAR
|
|
YM_FAST3438 .EQU 0 ; FAST CPU'S WITH A YM3438 MAY REQUIRE A DELAY
|
|
;
|
|
DEVECHO "YM: IO="
|
|
DEVECHO YMSEL
|
|
DEVECHO "\n"
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Driver function table and instance data
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
YM_FNTBL: .DW YM_RESET
|
|
.DW ym_volume
|
|
.DW YM_PERIOD
|
|
.DW YM_NOTE
|
|
.DW YM_PLAY
|
|
.DW YM_QUERY
|
|
.DW YM_DURATION
|
|
.DW YM_DEVICE
|
|
.DW YM_BEEP
|
|
;
|
|
#IF (($ - YM_FNTBL) != (SND_FNCNT * 2))
|
|
.ECHO "*** INVALID SND FUNCTION TABLE ***\n"
|
|
!!!!!
|
|
#ENDIF
|
|
;
|
|
YM_IDAT .EQU 0 ; NO INSTANCE DATA FOR THIS DEVICE
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; YM2162 Initialization
|
|
; Announce device on console.
|
|
; Setup function tables. Setup the device.
|
|
; Set volume off.
|
|
; Return initialization status
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
YM2612_INIT: CALL NEWLINE ; ANNOUNCE
|
|
PRTS("YM:$")
|
|
;
|
|
PRTS(" IO=0x$")
|
|
LD A,YMSEL
|
|
CALL PRTHEXBYTE
|
|
;
|
|
LD IY, YM_IDAT ; SETUP FUNCTION TABLE
|
|
LD BC, YM_FNTBL ; POINTER TO INSTANCE DATA
|
|
LD DE, YM_IDAT ; BC := FUNCTION TABLE ADDRESS
|
|
CALL SND_ADDENT ; DE := INSTANCE DATA PTR
|
|
;
|
|
YM_INIT: ld hl,ym_cfg
|
|
; call ym_prog
|
|
; ret
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Program ym2612 with a list of register entries
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
ym_prog: ld c,(hl) ; get port address
|
|
inc hl
|
|
ld d,(hl) ; count of pairs
|
|
inc hl
|
|
;
|
|
#IF (YM_DEBUG)
|
|
push af
|
|
ld a,c ; port
|
|
call PRTHEXBYTE
|
|
pop af
|
|
#ENDIF
|
|
;
|
|
t_loop: ld a,(hl) ; get register to write
|
|
out (c),a ; write reg to RSEL port
|
|
;
|
|
#IF (YM_DEBUG)
|
|
call PRTHEXBYTE ; register
|
|
#ENDIF
|
|
;
|
|
inc hl
|
|
inc c ; point to RDAT port
|
|
ld a,(hl) ; get value to write
|
|
out (c),a ; write value to RDAT port
|
|
;
|
|
#IF (YM_DEBUG)
|
|
call PRTHEXBYTE
|
|
call PC_SPACE
|
|
#ENDIF
|
|
;
|
|
dec c ; point back to RSEL port
|
|
ld b,0 ;
|
|
nready1:
|
|
#IF YM_FAST3438==1) \ cp (ix) \ #ENDIF \ ; ym3438 delay (1)
|
|
in a,(c) ; check device
|
|
rlca ; ready with timeout
|
|
jr nc,ready1 ; bits 7 = busy
|
|
djnz nready1
|
|
;
|
|
; timed out
|
|
;
|
|
ready1: inc hl ;
|
|
dec d ; decrease # left to do
|
|
jr nz,t_loop
|
|
;
|
|
#IF (YM_DEBUG)
|
|
call NEWLINE
|
|
#ENDIF
|
|
;
|
|
ld a,(hl) ; end flag?
|
|
or a
|
|
jr nz,ym_prog ; no? restart
|
|
ret
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Sound driver function - QUERY and subfunctions
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
YM_QUERY: LD A, E
|
|
CP BF_SNDQ_CHCNT ; SUB FUNCTION 01
|
|
JR Z, YM_QUERY_CHCNT
|
|
;
|
|
CP BF_SNDQ_VOLUME ; SUB FUNCTION 02
|
|
JR Z, YM_QUERY_VOLUME
|
|
;
|
|
CP BF_SNDQ_PERIOD ; SUB FUNCTION 03
|
|
JR Z, YM_QUERY_PERIOD
|
|
;
|
|
CP BF_SNDQ_DEV ; SUB FUNCTION 04
|
|
JR Z, YM_QUERY_DEV
|
|
;
|
|
OR $FF ; SIGNAL FAILURE
|
|
RET
|
|
;
|
|
YM_QUERY_CHCNT: LD BC,(YM_TONECNT*256)+YM_NOISECNT
|
|
XOR A ; RETURN NUMBER OF TONE AND NOISE
|
|
RET ; NOISE CHANNELS IN BC
|
|
;
|
|
YM_QUERY_PERIOD:LD HL, (YM_PENDING_PERIOD) ; RETURN 16-BIT PERIOD
|
|
XOR A ; IN HL REGISTER
|
|
RET
|
|
;
|
|
YM_QUERY_VOLUME:LD A, (YM_PENDING_VOLUME) ; RETURN 8-BIT VOLUME
|
|
LD L, A ; IN L REGISTER
|
|
XOR A
|
|
; LD H, A
|
|
RET
|
|
;
|
|
YM_QUERY_DEV: LD B, SNDDEV_YM2612 ; RETURN DEVICE IDENTIFIER
|
|
LD DE, +(YMSEL*256)+YMDAT ; AND ADDRESS AND DATA PORT
|
|
LD HL, +(YM2SEL*256)+YM2DAT
|
|
XOR A
|
|
RET
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Sound driver function - DEVICE
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
YM_DEVICE: LD D,SNDDEV_YM2612 ; D := DEVICE TYPE
|
|
LD E,0 ; E := PHYSICAL UNIT
|
|
LD C,$00 ; C := DEVICE TYPE
|
|
LD H,0 ; H := MODE
|
|
LD L,YMSEL ; L := BASE I/O ADDRESS
|
|
XOR A
|
|
RET
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Sound driver function - BEEP
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
YM_BEEP:
|
|
JP SND_BEEP ; DEFER TO GENERIC CODE IN HBIOS
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Sound driver function - RESET
|
|
; Initialize device. Set volume off. Reset volume and tone variables.
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
YM_RESET: ;CALL AY_CHKREDY ; RETURNS TO OUR CALLER IF NOT READY
|
|
;
|
|
PUSH DE
|
|
PUSH HL
|
|
CALL YM_INIT ; SET DEFAULT CHIP CONFIGURATION
|
|
;
|
|
XOR A ; SIGNAL SUCCESS
|
|
LD (YM_RDY_RST),A ; IN RESET STATE
|
|
LD (YM_PENDING_VOLUME),A ; SET VOLUME TO ZERO
|
|
LD H,A
|
|
LD L,A
|
|
LD (YM_PENDING_PERIOD),HL ; SET TONE PERIOD TO ZERO
|
|
;
|
|
POP HL
|
|
POP DE
|
|
RET
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Sound driver function - VOLUME
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
ym_volume: LD A,L ; SAVE VOLUME
|
|
LD (YM_PENDING_VOLUME),A
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Sound driver function - NOTE
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
YM_NOTE: ;CALL PRTHEXWORDHL
|
|
;CALL PC_COLON
|
|
|
|
LD DE,40 ; Calculate the ym2612 block (octave)
|
|
ADD HL,DE ; This will go into b13-b11
|
|
LD DE,48 ; HL / DE
|
|
CALL DIV16 ; BC = block (octave) HL = quarter semitone note
|
|
;
|
|
ADD HL,HL
|
|
LD DE,ym_notetable ; point HL to frequency entry
|
|
ADD HL,DE ; for the quarter semitone note
|
|
|
|
;CALL PRTHEXWORDHL
|
|
;CALL PC_COLON
|
|
;CALL PRTHEXWORD
|
|
;CALL PC_COLON
|
|
;
|
|
LD A,C ; SHIFT OCTAVE INTO RIGHT POSITION
|
|
ADD A,A ; X2
|
|
ADD A,A ; X4
|
|
ADD A,A ; X8 -NEEDS TO BE OR'ED WITH HIGH BYTE
|
|
;
|
|
LD E,(HL) ; COMBINE FREQUENCY ENTRY
|
|
INC HL ; AND BLOCK (OCTAVE) IN HL
|
|
OR (HL)
|
|
LD H,A
|
|
LD L,E
|
|
|
|
;CALL PRTHEXWORDHL
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Sound driver function - PERIOD
|
|
; The format for setting frequency on the ym2612 is 00xxxyyy-yyyyyyyy
|
|
; Where xxx us the octave and yyy-yyyyyyyy is the frequency
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
YM_PERIOD: LD A, H ; IF ZERO - ERROR
|
|
OR L
|
|
JR Z, YM_PERIOD1
|
|
;
|
|
LD A, H ; MAXIMUM TONE PERIOD IS 11-BITS
|
|
AND 11000000B ; ALLOWED RANGE IS 0001-07FF (2047)
|
|
JR NZ,YM_PERIOD1 ; AND 3 BITS FOR OCTAVE (7)
|
|
LD (YM_PENDING_PERIOD),HL ; RETURN NZ IF NUMBER TOO LARGE
|
|
RET ; SAVE AND RETURN SUCCESSFUL
|
|
;
|
|
YM_PERIOD1: LD A, $FF ; REQUESTED PERIOD IS LARGER
|
|
LD (YM_PENDING_PERIOD),A ; THAN THE DEVICE CAN SUPPORT
|
|
LD (YM_PENDING_PERIOD+1),A ; SO SET PERIOD TO FFFF
|
|
RET ; AND RETURN FAILURE
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Sound driver function - DURATION
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
YM_DURATION: LD (YM_PENDING_DURATION),HL ; SET TONE DURATION
|
|
XOR A
|
|
RET
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Sound driver function - PLAY
|
|
; D = CHANNEL
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
YM_PLAY: ld a,d
|
|
cp YM_TONECNT ; error if bad channel
|
|
ret nc
|
|
|
|
cp 3 ; 000 > 000, 011 > 100
|
|
ld e,part1 ; 001 > 001, 100 > 101
|
|
jr c,ch012 ; 010 > 010, 101 > 110
|
|
sub 3
|
|
ld d,a ; d = 0..2
|
|
add a,4 ; a = 4..6
|
|
jr ch345
|
|
ch012: ld e,part0
|
|
ch345:
|
|
;
|
|
#IF (YM_DEBUG)
|
|
call PC_COLON
|
|
call PRTHEXBYTE ; a = 0..2 4..6
|
|
push af
|
|
ld a,d
|
|
call PRTHEXBYTE ; d = 00..05
|
|
ld a,e
|
|
call PRTHEXBYTE ; e = part0/part1 (c0/c2)
|
|
pop af
|
|
call NEWLINE
|
|
#ENDIF
|
|
;
|
|
ld hl,ym_playcmd01
|
|
ld (hl),e ; set the part
|
|
;
|
|
ld hl,ym_playcmd00 ; setup keyoff channel
|
|
ld (hl),a
|
|
ld hl,ym_playcmd09 ; setup keyon channel
|
|
or %10000000 ; operator 4 only
|
|
ld (hl),a
|
|
|
|
ld a,$a4 ; setup frequency register msb
|
|
add a,d ; $a4-$a6
|
|
ld hl,ym_playcmd02
|
|
ld (hl),a
|
|
|
|
ld a,$a0 ; setup frequency register lsb
|
|
add a,d ; $a0-$a2
|
|
ld hl,ym_playcmd04
|
|
ld (hl),a
|
|
|
|
ld a,$4c ; setup volume register
|
|
add a,d ; $4c-$4e
|
|
ld hl,ym_playcmd06
|
|
ld (hl),a
|
|
|
|
LD A,(YM_RDY_RST) ; IF STILL IN RESET
|
|
OR A ; STATE GO SETUP FOR
|
|
CALL Z,YM_MAKE_RDY ; PLAYING
|
|
;
|
|
ld hl,(YM_PENDING_PERIOD) ; GET THE PREVIOUSLY SETUP
|
|
ld de,ym_playcmd03 ; TONE DATA AND
|
|
ld a,h
|
|
ld (de),a ; PATCH IT INTO THE
|
|
ld de,ym_playcmd05 ; YM2612 PLAY COMMAND
|
|
ld a,l
|
|
ld (de),a
|
|
;
|
|
ld de,ym_playcmd07
|
|
ld A,(YM_PENDING_VOLUME) ; GET VOLUME
|
|
srl a
|
|
cpl
|
|
and %01111111 ; PATCH IT INTO THE
|
|
ld (de),a ; YM2612 PLAY COMMAND
|
|
#IF (YM_DEBUG)
|
|
ld b,16 ; debug
|
|
call NEWLINE ; dump
|
|
ld de,ym_playnote ; the
|
|
ym_dbgcmd: ld a,(de) ; command
|
|
call PRTHEXBYTE ; stream
|
|
call PC_SPACE
|
|
inc de
|
|
djnz ym_dbgcmd
|
|
call NEWLINE
|
|
#ENDIF
|
|
ld hl,ym_playnote ; NOW PLAY IT
|
|
jp ym_prog
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Make ready for hbios play
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
YM_MAKE_RDY: CPL
|
|
LD (YM_RDY_RST),A ; Invert the ready flag
|
|
ld hl,ym_cfg_ready ; Program ym2612 for playing
|
|
jp ym_prog
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Command sequence to play a note
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
ym_playnote: .db part0, 2/2
|
|
.db $28
|
|
ym_playcmd00: .db $00 ; [0] KEY OFF
|
|
;
|
|
ym_playcmd01: .db part0,6/2
|
|
ym_playcmd02: .db $A4
|
|
ym_playcmd03: .db $3F ; [X] Frequency MSB
|
|
ym_playcmd04: .db $A0
|
|
ym_playcmd05: .db $FF ; [X] Frequency LSB
|
|
ym_playcmd06: .db $4C
|
|
ym_playcmd07: .db $00 ; [X] Volume
|
|
;
|
|
.db part0, 2/2
|
|
ym_playcmd08: .db $28
|
|
ym_playcmd09: .db $F0 ; [0] KEY ON
|
|
|
|
.db $00 ; End flag
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Quarter semitone F-Number values for frequency
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
ym_notetable: .dw 644 ; C ; 152
|
|
.dw 653 ; approx
|
|
.dw 663 ; approx
|
|
.dw 672 ; approx
|
|
.dw 681 ; C# ; 156
|
|
.dw 691 ; approx
|
|
.dw 702 ; approx
|
|
.dw 712 ; approx
|
|
.dw 722 ; D ; 160
|
|
.dw 733 ; approx
|
|
.dw 744 ; approx
|
|
.dw 754 ; approx
|
|
.dw 765 ; D# ; 164
|
|
.dw 776 ; approx
|
|
.dw 788 ; approx
|
|
.dw 799 ; approx
|
|
.dw 810 ; E ; 168
|
|
.dw 822 ; approx
|
|
.dw 834 ; approx
|
|
.dw 846 ; approx
|
|
.dw 858 ; F ; 172
|
|
.dw 871 ; approx
|
|
.dw 884 ; approx
|
|
.dw 897 ; approx
|
|
.dw 910 ; F# ; 176
|
|
.dw 924 ; approx
|
|
.dw 937 ; approx
|
|
.dw 951 ; approx
|
|
.dw 964 ; G ; 180
|
|
.dw 978 ; approx
|
|
.dw 993 ; approx
|
|
.dw 1007 ; approx
|
|
.dw 1021 ; G# ; 184
|
|
.dw 1036 ; approx
|
|
.dw 1051 ; approx
|
|
.dw 1066 ; approx
|
|
.dw 1081 ; A ; 188
|
|
.dw 1097 ; approx
|
|
.dw 1114 ; approx
|
|
.dw 1130 ; approx
|
|
.dw 1146 ; A# ; 192
|
|
.dw 1163 ; approx
|
|
.dw 1180 ; approx
|
|
.dw 1197 ; approx
|
|
.dw 1214 ; B ; 196
|
|
.dw 1232 ; approx
|
|
.dw 1250 ; approx
|
|
.dw 1268 ; approx
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Register configuration data for play
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
ym_cfg_ready: .db part0, 2/2
|
|
.db $22, $00 ; Global: LFO disable
|
|
;
|
|
.db part0, 6/2
|
|
.db $B0,$30 ; Channel 1-3
|
|
.db $b1,$30 ; Algorithm 0 S1>S2>S3>S4
|
|
.db $b2,$30 ; Feedback pure sine wave
|
|
;
|
|
.db part1, 6/2
|
|
.db $B0,$30 ; Channel 4-6
|
|
.db $b1,$30 ; Algorithm 0 S1>S2>S3>S4
|
|
.db $b2,$30 ; Feedback pure sine wave
|
|
;
|
|
.db part0, 6/2
|
|
.db $3c, $01 ; Channel 1-3
|
|
.db $3d, $01 ; Operator 4.MUL = 1
|
|
.db $3e, $01
|
|
;
|
|
.db part1, 6/2
|
|
.db $3c, $01 ; Channel 4-6
|
|
.db $3d, $01 ; Operator 4.MUL = 1
|
|
.db $3e, $01
|
|
;
|
|
.db part0, 6/2
|
|
.db $b4,%01000000 ; Channel 1-3
|
|
.db $b5,%01000000 ; Left Channel
|
|
.db $b6,%01000000
|
|
;
|
|
.db part1, 6/2
|
|
.db $b4,%10000000 ; Channel 4-6
|
|
.db $b5,%10000000 ; Right Channel
|
|
.db $b6,%10000000
|
|
;
|
|
.db part0, 6/2
|
|
.db $44, $7F ; Channel 1-3
|
|
.db $45, $7F ; Mute operator 3 <- pure sine wave
|
|
.db $46, $7F
|
|
;
|
|
.db part1, 6/2
|
|
.db $44, $7F ; Channel 4-6
|
|
.db $45, $7F ; Mute operator 3 <- pure sine wave
|
|
.db $46, $7F
|
|
;
|
|
.db part0, 6/2
|
|
.db $4C, $00 ; Channel 1-3
|
|
.db $4d, $00 ; Max volume for operator 4
|
|
.db $4e, $00
|
|
;
|
|
.db part1, 6/2
|
|
.db $4C, $00 ; Channel 4-6
|
|
.db $4d, $00 ; Max volume for operator 4
|
|
.db $4e, $00
|
|
;
|
|
.db part0, 6/2
|
|
.db $5C, $1F ; Channel 1-3
|
|
.db $5d, $1F ; Operator 4.AR = shortest
|
|
.db $5e, $1F
|
|
;
|
|
.db part1, 6/2
|
|
.db $5C, $1F ; Channel 4-6
|
|
.db $5d, $1F ; Operator 4.AR = shortest
|
|
.db $5e, $1F
|
|
;
|
|
.db part0, 6/2
|
|
.db $6C, $06 ; Channel 1-3
|
|
.db $6d, $06 ; Operator 4.D1R= 6
|
|
.db $6e, $06
|
|
;
|
|
.db part1, 6/2
|
|
.db $6C, $06 ; Channel 4-6
|
|
.db $6d, $06 ; Operator 4.D1R= 6
|
|
.db $6e, $06
|
|
;
|
|
.db part0, 6/2
|
|
.db $7C, $1F ; Channel 1-3
|
|
.db $7d, $1F ; Operator 4.D2R= 31
|
|
.db $7e, $1F
|
|
;
|
|
.db part1, 6/2
|
|
.db $7C, $1F ; Channel 4-6
|
|
.db $7d, $1F ; Operator 4.D2R= 31
|
|
.db $7e, $1F
|
|
;
|
|
.db part0, 6/2
|
|
.db $8C, $FF ; Channel 1-3
|
|
.db $8d, $FF ; Operator 4.SL = 15 / Operator4. RR=15
|
|
.db $8e, $FF
|
|
;
|
|
.db part1, 6/2
|
|
.db $8C, $FF ; Channel 4-6
|
|
.db $8d, $FF ; Operator 4.SL = 15 / Operator4. RR=15
|
|
.db $8e, $FF
|
|
;
|
|
.db $00 ; End flag
|
|
;
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Register configuration data for soft reset state
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
part0: .equ YMSEL
|
|
part1: .equ YM2SEL
|
|
;
|
|
#IF (YM_RSTCFG==0)
|
|
ym_cfg: .db part0, 24/2
|
|
.db $22,$00 ; [0] lfo off
|
|
.db $27,$00 ; [0] Disable independant Channel 3
|
|
.db $28,$00 ; [0] note off ch 1
|
|
.db $28,$01 ; [0] note off ch 2
|
|
.db $28,$02 ; [0] note off ch 3
|
|
.db $28,$04 ; [0] note off ch 4
|
|
.db $28,$05 ; [0] note off ch 5
|
|
.db $28,$06 ; [0] note off ch 6
|
|
.db $2b,$00 ; [0] dac off
|
|
.db $b4,$00 ; [0] sound off ch 1-3
|
|
.db $b5,$00
|
|
.db $b6,$00
|
|
;
|
|
.db part1, 6/2
|
|
.db $b4,$00 ; [1] sound off ch 4-6
|
|
.db $b5,$00 ; [1]
|
|
.db $b6,$00 ; [1]
|
|
;
|
|
.db part0, 24/2
|
|
.db $40,$7f ; [0] ch 1-3 total level minimum
|
|
.db $41,$7f ; [0]
|
|
.db $42,$7f ; [0]
|
|
.db $44,$7f ; [0]
|
|
.db $45,$7f ; [0]
|
|
.db $46,$7f ; [0]
|
|
.db $48,$7f ; [0]
|
|
.db $49,$7f ; [0]
|
|
.db $4a,$7f ; [0]
|
|
.db $4c,$7f ; [0]
|
|
.db $4d,$7f ; [0]
|
|
.db $4e,$7f ; [0]
|
|
;
|
|
.db part1, 24/2
|
|
.db $40,$7f ; [1] ch 4-6 total level minimum
|
|
.db $41,$7f ; [1]
|
|
.db $42,$7f ; [1]
|
|
.db $44,$7f ; [1]
|
|
.db $45,$7f ; [1]
|
|
.db $46,$7f ; [1]
|
|
.db $48,$7f ; [1]
|
|
.db $49,$7f ; [1]
|
|
.db $4a,$7f ; [1]
|
|
.db $4c,$7f ; [1]
|
|
.db $4d,$7f ; [1]
|
|
.db $4e,$7f ; [1]
|
|
;
|
|
.db $00 ; End flag
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
; Register configuration data for hard reset state
|
|
;------------------------------------------------------------------------------
|
|
;
|
|
#ELSE
|
|
ym_cfg: .db part0, 24/2
|
|
.db $22,$00 ; [0] lfo off
|
|
.db $27,$00 ; [0] Disable independant Channel 3
|
|
.db $28,$00 ; [0] note off ch 1
|
|
.db $28,$01 ; [0] note off ch 2
|
|
.db $28,$02 ; [0] note off ch 3
|
|
.db $28,$04 ; [0] note off ch 4
|
|
.db $28,$05 ; [0] note off ch 5
|
|
.db $28,$06 ; [0] note off ch 6
|
|
.db $2b,$00 ; [0] dac off
|
|
.db $b4,$00 ; [0] sound off ch 1-3
|
|
.db $b5,$00 ; [0]
|
|
.db $b6,$00 ; [0]
|
|
|
|
.db part1, 6/2
|
|
.db $b4,$00 ; [1] sound off ch 4-6
|
|
.db $b5,$00 ; [1]
|
|
.db $b6,$00 ; [1]
|
|
|
|
.db part0, 24/2
|
|
.db $40,$7f ; [0] ch 1-3 total level minimum
|
|
.db $41,$7f ; [0]
|
|
.db $42,$7f ; [0]
|
|
.db $44,$7f ; [0]
|
|
.db $45,$7f ; [0]
|
|
.db $46,$7f ; [0]
|
|
.db $48,$7f ; [0]
|
|
.db $49,$7f ; [0]
|
|
.db $4a,$7f ; [0]
|
|
.db $4c,$7f ; [0]
|
|
.db $4d,$7f ; [0]
|
|
.db $4e,$7f ; [0]
|
|
|
|
.db part1, 24/2
|
|
.db $40,$7f ; [1] ch 4-6 total level minimum
|
|
.db $41,$7f ; [1]
|
|
.db $42,$7f ; [1]
|
|
.db $44,$7f ; [1]
|
|
.db $45,$7f ; [1]
|
|
.db $46,$7f ; [1]
|
|
.db $48,$7f ; [1]
|
|
.db $49,$7f ; [1]
|
|
.db $4a,$7f ; [1]
|
|
.db $4c,$7f ; [1]
|
|
.db $4d,$7f ; [1]
|
|
.db $4e,$7f ; [1]
|
|
|
|
.db part0, 32/2
|
|
.db $2a,$00 ; [0] ; dac value
|
|
.db $24,$00 ; [0] ; timer A frequency
|
|
.db $25,$00 ; [0] ; timer A frequency
|
|
.db $26,$00 ; [0] ; time B frequency
|
|
.db $30,$00 ; [0] ; ch 1-3 multiply & detune
|
|
.db $31,$00 ; [0]
|
|
.db $32,$00 ; [0]
|
|
.db $34,$00 ; [0]
|
|
.db $35,$00 ; [0]
|
|
.db $36,$00 ; [0]
|
|
.db $38,$00 ; [0]
|
|
.db $39,$00 ; [0]
|
|
.db $3a,$00 ; [0]
|
|
.db $3c,$00 ; [0]
|
|
.db $3d,$00 ; [0]
|
|
.db $3e,$00 ; [0]
|
|
|
|
.db part1, 24/2
|
|
.db $30,$00 ; [1] ch 4-6 multiply & detune
|
|
.db $31,$00 ; [1]
|
|
.db $32,$00 ; [1]
|
|
.db $34,$00 ; [1]
|
|
.db $35,$00 ; [1]
|
|
.db $36,$00 ; [1]
|
|
.db $38,$00 ; [1]
|
|
.db $39,$00 ; [1]
|
|
.db $3a,$00 ; [1]
|
|
.db $3c,$00 ; [1]
|
|
.db $3d,$00 ; [1]
|
|
.db $3e,$00 ; [1]
|
|
|
|
.db part0, 24/2
|
|
.db $50,$00 ; [0] ch 1-3 attack rate and scaling
|
|
.db $51,$00 ; [0]
|
|
.db $52,$00 ; [0]
|
|
.db $54,$00 ; [0]
|
|
.db $55,$00 ; [0]
|
|
.db $56,$00 ; [0]
|
|
.db $58,$00 ; [0]
|
|
.db $59,$00 ; [0]
|
|
.db $5a,$00 ; [0]
|
|
.db $5c,$00 ; [0]
|
|
.db $5d,$00 ; [0]
|
|
.db $5e,$00 ; [0]
|
|
|
|
.db part1, 24/2
|
|
.db $50,$00 ; [1] ch 4-6 attack rate and scaling
|
|
.db $51,$00 ; [1]
|
|
.db $52,$00 ; [1]
|
|
.db $54,$00 ; [1]
|
|
.db $55,$00 ; [1]
|
|
.db $56,$00 ; [1]
|
|
.db $58,$00 ; [1]
|
|
.db $59,$00 ; [1]
|
|
.db $5a,$00 ; [1]
|
|
.db $5c,$00 ; [1]
|
|
.db $5d,$00 ; [1]
|
|
.db $5e,$00 ; [1]
|
|
|
|
.db part0, 24/2
|
|
.db $60,$00 ; [0] ch 1-3 decay rate and am enable
|
|
.db $61,$00 ; [0]
|
|
.db $62,$00 ; [0]
|
|
.db $64,$00 ; [0]
|
|
.db $65,$00 ; [0]
|
|
.db $66,$00 ; [0]
|
|
.db $68,$00 ; [0]
|
|
.db $69,$00 ; [0]
|
|
.db $6a,$00 ; [0]
|
|
.db $6c,$00 ; [0]
|
|
.db $6d,$00 ; [0]
|
|
.db $6e,$00 ; [0]
|
|
|
|
.db part1, 24/2
|
|
.db $60,$00 ; [1] ch 4-6 decay rate and am enable
|
|
.db $61,$00 ; [1]
|
|
.db $62,$00 ; [1]
|
|
.db $64,$00 ; [1]
|
|
.db $65,$00 ; [1]
|
|
.db $66,$00 ; [1]
|
|
.db $68,$00 ; [1]
|
|
.db $69,$00 ; [1]
|
|
.db $6a,$00 ; [1]
|
|
.db $6c,$00 ; [1]
|
|
.db $6d,$00 ; [1]
|
|
.db $6e,$00 ; [1]
|
|
|
|
.db part0, 24/2
|
|
.db $70,$00 ; [0] ch 1-3 sustain rate
|
|
.db $71,$00 ; [0]
|
|
.db $72,$00 ; [0]
|
|
.db $74,$00 ; [0]
|
|
.db $75,$00 ; [0]
|
|
.db $76,$00 ; [0]
|
|
.db $78,$00 ; [0]
|
|
.db $79,$00 ; [0]
|
|
.db $7a,$00 ; [0]
|
|
.db $7c,$00 ; [0]
|
|
.db $7d,$00 ; [0]
|
|
.db $7e,$00 ; [0]
|
|
|
|
.db part1, 24/2
|
|
.db $70,$00 ; [1] ch 4-6 sustain rate
|
|
.db $71,$00 ; [1]
|
|
.db $72,$00 ; [1]
|
|
.db $74,$00 ; [1]
|
|
.db $75,$00 ; [1]
|
|
.db $76,$00 ; [1]
|
|
.db $78,$00 ; [1]
|
|
.db $79,$00 ; [1]
|
|
.db $7a,$00 ; [1]
|
|
.db $7c,$00 ; [1]
|
|
.db $7d,$00 ; [1]
|
|
.db $7e,$00 ; [1]
|
|
|
|
.db part0, 24/2
|
|
.db $80,$00 ; [0] ch 1-3 release rate and sustain level
|
|
.db $81,$00 ; [0]
|
|
.db $82,$00 ; [0]
|
|
.db $84,$00 ; [0]
|
|
.db $85,$00 ; [0]
|
|
.db $86,$00 ; [0]
|
|
.db $88,$00 ; [0]
|
|
.db $89,$00 ; [0]
|
|
.db $8a,$00 ; [0]
|
|
.db $8c,$00 ; [0]
|
|
.db $8d,$00 ; [0]
|
|
.db $8e,$00 ; [0]
|
|
|
|
.db part1, 24/2
|
|
.db $80,$00 ; [1] ch 4-6 release rate and sustain level
|
|
.db $81,$00 ; [1]
|
|
.db $82,$00 ; [1]
|
|
.db $84,$00 ; [1]
|
|
.db $85,$00 ; [1]
|
|
.db $86,$00 ; [1]
|
|
.db $88,$00 ; [1]
|
|
.db $89,$00 ; [1]
|
|
.db $8a,$00 ; [1]
|
|
.db $8c,$00 ; [1]
|
|
.db $8d,$00 ; [1]
|
|
.db $8e,$00 ; [1]
|
|
|
|
.db part0, 24/2
|
|
.db $90,$00 ; [0] ch 1-3 ssg-eg
|
|
.db $91,$00 ; [0]
|
|
.db $92,$00 ; [0]
|
|
.db $94,$00 ; [0]
|
|
.db $95,$00 ; [0]
|
|
.db $96,$00 ; [0]
|
|
.db $98,$00 ; [0]
|
|
.db $99,$00 ; [0]
|
|
.db $9a,$00 ; [0]
|
|
.db $9c,$00 ; [0]
|
|
.db $9d,$00 ; [0]
|
|
.db $9e,$00 ; [0]
|
|
|
|
.db part1, 24/2
|
|
.db $90,$00 ; [1] ch 4-6 ssg-eg
|
|
.db $91,$00 ; [1]
|
|
.db $92,$00 ; [1]
|
|
.db $94,$00 ; [1]
|
|
.db $95,$00 ; [1]
|
|
.db $96,$00 ; [1]
|
|
.db $98,$00 ; [1]
|
|
.db $99,$00 ; [1]
|
|
.db $9a,$00 ; [1]
|
|
.db $9c,$00 ; [1]
|
|
.db $9d,$00 ; [1]
|
|
.db $9e,$00 ; [1]
|
|
|
|
.db part0, 12/2
|
|
.db $a0,$00 ; [0] ch 1-3 frequency
|
|
.db $a1,$00 ; [0]
|
|
.db $a2,$00 ; [0]
|
|
.db $a4,$00 ; [0]
|
|
.db $a5,$00 ; [0]
|
|
.db $a6,$00 ; [0]
|
|
; .db $a8,$00 ; [0] ch 3 special mode
|
|
; .db $a9,$00 ; [0]
|
|
; .db $aa,$00 ; [0]
|
|
; .db $ac,$00 ; [0]
|
|
; .db $ad,$00 ; [0]
|
|
; .db $ae,$00 ; [0]
|
|
|
|
.db part1, 12/2
|
|
.db $a0,$00 ; [1] ch 4-6 frequency
|
|
.db $a1,$00 ; [1]
|
|
.db $a2,$00 ; [1]
|
|
.db $a4,$00 ; [1]
|
|
.db $a5,$00 ; [1]
|
|
.db $a6,$00 ; [1]
|
|
; .db $a8,$00 ; [1] ch 3 special mode
|
|
; .db $a9,$00 ; [1]
|
|
; .db $aa,$00 ; [1]
|
|
; .db $ac,$00 ; [1]
|
|
; .db $ad,$00 ; [1]
|
|
; .db $ae,$00 ; [1]
|
|
|
|
.db part0, 6/2
|
|
.db $b0,$00 ; [0] ch 1-3 algorith + feedback
|
|
.db $b1,$00 ; [0]
|
|
.db $b2,$00 ; [0]
|
|
|
|
.db part1, 6/2
|
|
.db $b0,$00 ; [1] ch 4-6 algorith + feedback
|
|
.db $b1,$00 ; [1]
|
|
.db $b2,$00 ; [1]
|
|
;
|
|
.db $00 ; End flag
|
|
#ENDIF
|
|
|