DECLARE SUB LoadOPL2Frequency (FMKey AS ANY, OPL2Grid%()) DECLARE SUB LoadOPL2GridIndex (FMKey AS ANY, OPL2Grid%()) DECLARE SUB LoadOPL2WaveEffect (FMKey AS ANY, Effect AS ANY, OPL2Grid%()) DECLARE SUB LoadOPL2WaveEnvelope (FMKey AS ANY, Envelope AS ANY, OPL2Grid%()) DECLARE SUB MonoLoadOPL2 (FMKey AS ANY, MonoGrid%()) DECLARE SUB SetOPL2InstrumentVolume (FMKey AS ANY, OPL2Grid%()) DEFINT A-Z TYPE OPL2 MonoStatusPort AS INTEGER MonoDataPort AS INTEGER LeftStatusPort AS INTEGER LeftDataPort AS INTEGER RightStatusPort AS INTEGER RightDataPort AS INTEGER Status AS INTEGER TimerStatusBit1 AS INTEGER TimerFlag1 AS INTEGER TimerStatusBit2 AS INTEGER TimerFlag2 AS INTEGER InterruptBit AS INTEGER InterruptFlag AS INTEGER TimerResolution1 AS INTEGER TimerResolution2 AS INTEGER ActiveRegister AS INTEGER RegisterControl AS INTEGER ActiveChannel AS INTEGER ActiveOperator AS INTEGER IncomingMonoData AS INTEGER IncomingLeftData AS INTEGER IncomingRightData AS INTEGER IncomingData AS INTEGER OPL2PresentFlag AS INTEGER StatusWriteDelay AS INTEGER DataWriteDelay AS INTEGER DelayCountdown AS INTEGER MonoGridOffset AS INTEGER MonoGridLimit AS INTEGER StereoGridOffset AS INTEGER StereoGridLimit AS INTEGER WaveControl AS INTEGER Wave AS INTEGER TimerDataControl1 AS INTEGER TimerPreset1 AS INTEGER TimerDataControl2 AS INTEGER TimerPreset2 AS INTEGER TimerControl AS INTEGER TimerState AS INTEGER IRQResetBit AS INTEGER IRQResetFlag AS INTEGER TimerMaskBit1 AS INTEGER TimerMaskFlag1 AS INTEGER TimerMaskBit2 AS INTEGER TimerMaskFlag2 AS INTEGER TimerActiveBit1 AS INTEGER TimerActiveFlag1 AS INTEGER TimerActiveBit2 AS INTEGER TimerActiveFlag2 AS INTEGER SpeechSynthControl AS INTEGER SpeechSynthBit AS INTEGER SpeechSynthFlag AS INTEGER SpeechSynth AS INTEGER KeyboardSplitControl AS INTEGER KeyboardSplitBit AS INTEGER KeyboardSplitFlag AS INTEGER KeyboardSplit AS INTEGER FMControl AS INTEGER FMLimit AS INTEGER AmplitudeBit AS INTEGER AmplitudeFlag AS INTEGER Amplitude AS INTEGER VibratoBit AS INTEGER VibratoFlag AS INTEGER Vibrato AS INTEGER EGBit AS INTEGER EGFlag AS INTEGER EG AS INTEGER KeyboardScaleBit AS INTEGER KeyboardScaleFlag AS INTEGER KeyboardScale AS INTEGER FMMultipleBit AS INTEGER FMMultiple AS INTEGER VolumeControl AS INTEGER VolumeLimit AS INTEGER KeyScaleLevelBit AS INTEGER KeyScaleLevel AS INTEGER VolumeBit AS INTEGER Volume AS INTEGER AttackControl AS INTEGER AttackLimit AS INTEGER AttackBit AS INTEGER Attack AS INTEGER DecayBit AS INTEGER Decay AS INTEGER SustainControl AS INTEGER SustainLimit AS INTEGER SustainBit AS INTEGER Sustain AS INTEGER ReleaseBit AS INTEGER Release AS INTEGER FrequencyControl AS INTEGER FrequencyLimit AS INTEGER Frequency AS INTEGER NoteCSharp AS INTEGER NoteD AS INTEGER NoteDSharp AS INTEGER NoteE AS INTEGER NoteF AS INTEGER NoteFSharp AS INTEGER NoteG AS INTEGER NoteGSharp AS INTEGER NoteA AS INTEGER NoteASharp AS INTEGER NoteB AS INTEGER NoteC AS INTEGER OctaveControl AS INTEGER OctaveLimit AS INTEGER OctaveBit AS INTEGER Octave AS INTEGER ChannelActiveBit AS INTEGER ChannelActiveFlag AS INTEGER FrequencyHighBit AS INTEGER AMDepthControl AS INTEGER AMDepthBit AS INTEGER AMDepthFlag AS INTEGER VibratoDepthControl AS INTEGER VibratoDepthBit AS INTEGER VibratoDepthFlag AS INTEGER RhythmControl AS INTEGER RhythmBit AS INTEGER RhythmFlag AS INTEGER BassDrumBit AS INTEGER BassDrumFlag AS INTEGER SnareDrumBit AS INTEGER SnareDrumFlag AS INTEGER TomTomBit AS INTEGER TomTomFlag AS INTEGER TopCymbalBit AS INTEGER TopCymbalFlag AS INTEGER HiHatBit AS INTEGER HiHatFlag AS INTEGER FeedbackControl AS INTEGER FeedbackLimit AS INTEGER FeedbackBit AS INTEGER Feedback AS INTEGER SynthAlgorithmBit AS INTEGER SynthAlgorithmFlag AS INTEGER WaveSelectControl AS INTEGER WaveSelectLimit AS INTEGER WaveSelect AS INTEGER SineBit AS INTEGER HalfSineBit AS INTEGER AbsoluteSineBit AS INTEGER PulseSineBit AS INTEGER ControlLimit AS INTEGER MonoControlLimit AS INTEGER StereoControlLimit AS INTEGER END TYPE DIM OPL2Key AS OPL2 OPL2Key.MonoStatusPort = &H388 OPL2Key.MonoDataPort = &H389 OPL2Key.LeftStatusPort = &H220 OPL2Key.LeftDataPort = &H222 OPL2Key.RightStatusPort = &H221 OPL2Key.RightDataPort = &H223 OPL2Key.TimerStatusBit1 = 64 OPL2Key.TimerStatusBit2 = 32 OPL2Key.InterruptBit = 128 OPL2Key.StatusWriteDelay = 6 OPL2Key.DataWriteDelay = 35 OPL2Key.WaveControl = &H1 OPL2Key.TimerDataControl1 = &H2 OPL2Key.TimerDataControl2 = &H3 OPL2Key.TimerControl = &H4 OPL2Key.IRQResetBit = 128 OPL2Key.TimerMaskBit1 = 64 OPL2Key.TimerMaskBit2 = 32 OPL2Key.TimerActiveBit1 = 1 OPL2Key.TimerActiveBit2 = 2 OPL2Key.SpeechSynthControl = &H8 OPL2Key.SpeechSynthBit = 128 OPL2Key.KeyboardSplitControl = &H8 OPL2Key.KeyboardSplitBit = 64 OPL2Key.FMControl = &H20 OPL2Key.FMLimit = &H35 OPL2Key.AmplitudeBit = 128 OPL2Key.VibratoBit = 64 OPL2Key.EGBit = 32 OPL2Key.KeyboardScaleBit = 16 OPL2Key.FMMultipleBit = 1 OPL2Key.VolumeControl = &H40 OPL2Key.VolumeLimit = &H55 OPL2Key.KeyScaleLevelBit = 64 OPL2Key.VolumeBit = 1 OPL2Key.AttackControl = &H60 OPL2Key.AttackLimit = &H75 OPL2Key.AttackBit = 16 OPL2Key.SustainControl = &H80 OPL2Key.SustainLimit = &H95 OPL2Key.SustainBit = 1 OPL2Key.FrequencyControl = &HA0 OPL2Key.FrequencyLimit = &HA8 OPL2Key.NoteCSharp = &H16B OPL2Key.NoteD = &H181 OPL2Key.NoteDSharp = &H198 OPL2Key.NoteE = &H1B0 OPL2Key.NoteF = &H1CA OPL2Key.NoteFSharp = &H1E5 OPL2Key.NoteG = &H202 OPL2Key.NoteGSharp = &H220 OPL2Key.NoteA = &H241 OPL2Key.NoteASharp = &H263 OPL2Key.NoteB = &H287 OPL2Key.NoteC = &H2AE OPL2Key.OctaveControl = &HB0 OPL2Key.OctaveLimit = &HB8 OPL2Key.ChannelActiveBit = 32 OPL2Key.OctaveBit = 4 OPL2Key.FrequencyHighBit = 1 OPL2Key.AMDepthControl = &HBD OPL2Key.AMDepthBit = 128 OPL2Key.VibratoDepthControl = &HBD OPL2Key.VibratoDepthBit = 64 OPL2Key.RhythmControl = &HBD OPL2Key.RhythmBit = 32 OPL2Key.BassDrumBit = 16 OPL2Key.SnareDrumBit = 8 OPL2Key.TomTomBit = 4 OPL2Key.TopCymbalBit = 2 OPL2Key.HiHatBit = 1 OPL2Key.FeedbackControl = &HC0 OPL2Key.FeedbackLimit = &HC8 OPL2Key.FeedbackBit = 2 OPL2Key.SynthAlgorithmBit = 1 OPL2Key.WaveSelectControl = &HE0 OPL2Key.WaveSelectLimit = &HF5 OPL2Key.ControlLimit = &HF5 DIM MonoControlGrid%(OPL2Key.MonoControlLimit) DIM StereoControlGrid%(OPL2Key.StereoControlLimit) TYPE OPL2Patch Op1AmplitudeFlag AS INTEGER Op2AmplitudeFlag AS INTEGER Op1VibratoFlag AS INTEGER Op2VibratoFlag AS INTEGER Op1EGFlag AS INTEGER Op2EGFlag AS INTEGER Op1KeyboardScaleFlag AS INTEGER Op2KeyboardScaleFlag AS INTEGER Op1FMMultiple AS INTEGER Op2FMMultiple AS INTEGER Op1WaveSelect AS INTEGER Op2WaveSelect AS INTEGER Op1Attack AS INTEGER Op2Attack AS INTEGER Op1Decay AS INTEGER Op2Decay AS INTEGER Op1Sustain AS INTEGER Op2Sustain AS INTEGER Op1Release AS INTEGER Op2Release AS INTEGER END TYPE TYPE OPL2Operator Index AS INTEGER AmplitudeFlag AS INTEGER VibratoFlag AS INTEGER EGFlag AS INTEGER KeyboardScaleFlag AS INTEGER FMMultiple AS INTEGER WaveSelect AS INTEGER Attack AS INTEGER Decay AS INTEGER Sustain AS INTEGER Release AS INTEGER END TYPE TYPE OPL2Effect AmplitudeFlag AS INTEGER VibratoFlag AS INTEGER EGFlag AS INTEGER KeyboardScaleFlag AS INTEGER FMMultiple AS INTEGER WaveSelect AS INTEGER END TYPE TYPE OPL2Envelope Attack AS INTEGER Decay AS INTEGER Sustain AS INTEGER Release AS INTEGER END TYPE TYPE Music Tempo AS INTEGER Note32Duration AS INTEGER VolumeStaff AS INTEGER VolumeStaffLimit AS INTEGER VolumeBarIndex AS INTEGER VolumeBarLimit AS INTEGER IncomingFrequency AS INTEGER Frequency AS INTEGER FrequencyStaffLimit AS INTEGER FrequencyBarIndex AS INTEGER FrequencyBarLimit AS INTEGER FrequencyHalf1 AS INTEGER FrequencyHalf2 AS INTEGER FrequencyAuxillaryFlag AS INTEGER IncomingNote AS INTEGER Octave AS INTEGER Note AS INTEGER SongLimit AS INTEGER StaffLimit AS INTEGER BarIndex AS INTEGER BarLimit AS INTEGER NoteLimit AS INTEGER END TYPE DEFSNG A-Z SUB DetectOPL2 (FMKey AS OPL2) OUT FMKey.TimerControl, &H60 OUT FMKey.TimerControl, &H80 OPL2TestControl1% = INP(FMKey.MonoStatusPort) OUT FMKey.TimerDataControl1, &HFF OUT FMKey.TimerControl, &H21 FOR FMCounter = 1 TO FMKey.DataWriteDelay FMKey.DelayCountdown = INP(FMKey.MonoStatusPort) NEXT OPL2TestControl2% = INP(FMKey.MonoStatusPort) OUT FMKey.TimerControl, &H60 OUT FMKey.TimerControl, &H80 OPL2TestControl1% = OPL2TestControl1% AND &HE0 OPL2TestControl2% = OPL2TestControl2% AND &HE0 IF OPL2TestControl1% = 0 THEN IF OPL2TestControl2% = &HC0 THEN FMKey.OPL2PresentFlag = 1 END IF END IF END SUB SUB LoadOPL2Frequency (FMKey AS OPL2, OPL2Grid%()) FMKey.RegisterControl = FMKey.FrequencyControl + FMKey.ActiveChannel OPL2Grid%(FMKey.RegisterControl) = FMKey.Frequency AND 256 FMKey.RegisterControl = FMKey.OctaveControl FMKey.IncomingData = FMKey.ChannelActiveBit * FMKey.ChannelActiveFlag FMKey.IncomingData = FMKey.IncomingData + (FMKey.OctaveBit * FMKey.Octave) FMKey.IncomingData = FMKey.FrequencyHighBit * INT(FMKey.Frequency / 256) FMKey.ActiveOperator = 1 LoadOPL2GridIndex FMKey, OPL2Grid%() END SUB DEFINT A-Z SUB LoadOPL2GridIndex (FMKey AS OPL2, OPL2Grid%()) GridIndex% = 3 * INT(FMKey.ActiveChannel / 3) GridIndex% = GridIndex% + (FMKey.ActiveOperator - 1) * 3 GridIndex% = GridIndex% + FMKey.RegisterControl + FMKey.ActiveChannel OPL2Grid%(GridIndex%) = FMKey.IncomingData END SUB SUB LoadOPL2MonoRegister (FMKey AS OPL2) OUT FMKey.MonoStatusPort, FMKey.ActiveRegister FOR FMCounter = 1 TO FMKey.StatusWriteDelay FMKey.DelayCountdown = INP(FMKey.MonoStatusPort) NEXT OUT FMKey.MonoDataPort, FMKey.IncomingMonoData FOR FMCounter = 1 TO FMKey.DataWriteDelay FMKey.DelayCountdown = INP(FMKey.MonoStatusPort) NEXT END SUB DEFSNG A-Z SUB LoadOPL2Operator (Operator AS OPL2Operator, FMKey AS OPL2, OPL2Grid%()) FMKey.ActiveOperator = Operator.Index FMKey.RegisterControl = FMKey.FMControl FMKey.Amplitude = FMKey.AmplitudeBit * Operator.AmplitudeFlag FMKey.AmplitudeFlag = Operator.AmplitudeFlag FMKey.IncomingData = FMKey.Amplitude FMKey.Vibrato = FMKey.VibratoBit * Operator.VibratoFlag FMKey.VibratoFlag = Operator.VibratoFlag FMKey.IncomingData = FMKey.IncomingData + FMKey.Vibrato FMKey.EG = FMKey.EGBit * Operator.EGFlag FMKey.EGFlag = Operator.EGFlag FMKey.IncomingData = FMKey.IncomingData + FMKey.EGBit FMKey.KeyboardScale = FMKey.KeyboardScaleBit * Operator.KeyboardScaleFlag FMKey.KeyboardScaleFlag = Operator.KeyboardScaleFlag FMKey.IncomingData = FMKey.IncomingData + FMKey.KeyboardScale FMKey.FMMultiple = Operator.FMMultiple FMKey.IncomingData = FMKey.IncomingData + FMKey.FMMultiple LoadOPL2GridIndex FMKey, OPL2Grid%() FMKey.RegisterControl = FMKey.WaveSelectControl FMKey.WaveSelect = Operator.WaveSelect FMKey.IncomingData = FMKey.WaveSelect LoadOPL2GridIndex FMKey, OPL2Grid%() FMKey.RegisterControl = FMKey.AttackControl FMKey.Attack = Operator.Attack FMKey.Decay = Operator.Decay FMKey.IncomingData = FMKey.AttackBit * FMKey.Attack FMKey.IncomingData = FMKey.IncomingData + FMKey.Decay LoadOPL2GridIndex FMKey, OPL2Grid%() FMKey.RegisterControl = FMKey.SustainControl FMKey.Sustain = Operator.Sustain FMKey.Release = Operator.Release FMKey.IncomingData = FMKey.SustainBit * FMKey.Sustain FMKey.IncomingData = FMKey.IncomingData + FMKey.Release LoadOPL2GridIndex FMKey, OPL2Grid%() END SUB DEFINT A-Z SUB LoadOPL2StereoRegister (FMKey AS OPL2) OUT FMKey.LeftStatusPort, FMKey.ActiveRegister FOR FMCounter = 1 TO FMKey.StatusWriteDelay FMKey.DelayCountdown = INP(FMKey.LeftStatusPort) NEXT OUT FMKey.LeftDataPort, FMKey.IncomingLeftData FOR FMCounter = 1 TO FMKey.DataWriteDelay FMKey.DelayCountdown = INP(FMKey.LeftStatusPort) NEXT OUT FMKey.RightStatusPort, FMKey.ActiveRegister FOR FMCounter = 1 TO FMKey.StatusWriteDelay FMKey.DelayCountdown = INP(FMKey.RightStatusPort) NEXT OUT FMKey.RightDataPort, FMKey.IncomingRightData FOR FMCounter = 1 TO FMKey.DataWriteDelay FMKey.DelayCountdown = INP(FMKey.RightStatusPort) NEXT END SUB DEFSNG A-Z SUB LoadOPL2WaveEffect (FMKey AS OPL2, Effect AS OPL2Effect, OPL2Grid%()) FMKey.RegisterControl = FMKey.FMControl FMKey.Amplitude = FMKey.AmplitudeBit * Effect.AmplitudeFlag FMKey.AmplitudeFlag = Effect.AmplitudeFlag FMKey.IncomingData = FMKey.Amplitude FMKey.Vibrato = FMKey.VibratoBit * Effect.VibratoFlag FMKey.VibratoFlag = Effect.VibratoFlag FMKey.IncomingData = FMKey.IncomingData + FMKey.Vibrato FMKey.EG = FMKey.EGBit * Effect.EGFlag FMKey.EGFlag = Effect.EGFlag FMKey.IncomingData = FMKey.IncomingData + FMKey.EGBit FMKey.KeyboardScale = FMKey.KeyboardScaleBit * Effect.KeyboardScaleFlag FMKey.KeyboardScaleFlag = Effect.KeyboardScaleFlag FMKey.IncomingData = FMKey.IncomingData + FMKey.KeyboardScale FMKey.FMMultiple = Effect.FMMultiple FMKey.IncomingData = FMKey.IncomingData + FMKey.FMMultiple LoadOPL2GridIndex FMKey, OPL2Grid%() FMKey.RegisterControl = FMKey.WaveSelectControl FMKey.WaveSelect = Effect.WaveSelect FMKey.IncomingData = FMKey.WaveSelect LoadOPL2GridIndex FMKey, OPL2Grid%() END SUB SUB LoadOPL2WaveEnvelope (FMKey AS OPL2, Envelope AS OPL2Envelope, OPL2Grid%()) FMKey.RegisterControl = FMKey.AttackControl FMKey.Attack = Envelope.Attack FMKey.Decay = Envelope.Decay FMKey.IncomingData = FMKey.AttackBit * FMKey.Attack FMKey.IncomingData = FMKey.IncomingData + FMKey.Decay LoadOPL2GridIndex FMKey, OPL2Grid%() FMKey.RegisterControl = FMKey.SustainControl FMKey.Sustain = Envelope.Sustain FMKey.Release = Envelope.Release FMKey.IncomingData = FMKey.SustainBit * FMKey.Sustain FMKey.IncomingData = FMKey.IncomingData + FMKey.Release LoadOPL2GridIndex FMKey, OPL2Grid%() END SUB DEFINT A-Z SUB MonoLoadOPL2 (FMKey AS OPL2, MonoGrid%()) FOR GridIndex% = FMKey.MonoGridOffset TO FMKey.MonoGridLimit FMKey.ActiveRegister = GridIndex% OUT FMKey.MonoStatusPort, FMKey.ActiveRegister FOR FMCounter = 1 TO FMKey.StatusWriteDelay FMKey.DelayCountdown = INP(FMKey.MonoStatusPort) NEXT FMKey.IncomingMonoData = MonoGrid%(FMKey.ActiveRegister) OUT FMKey.MonoDataPort, FMKey.IncomingMonoData FOR FMCounter = 1 TO FMKey.DataWriteDelay FMKey.DelayCountdown = INP(FMKey.MonoStatusPort) NEXT NEXT END SUB SUB OpenOPL2Operator (Op AS OPL2Operator, Effect AS OPL2Effect, Envelope AS OPL2Envelope) Op.AmplitudeFlag = Effect.AmplitudeFlag Op.VibratoFlag = Effect.VibratoFlag Op.EGFlag = Effect.EGFlag Op.KeyboardScaleFlag = Effect.KeyboardScaleFlag Op.FMMultiple = Effect.FMMultiple Op.WaveSelect = Effect.WaveSelect Op.Attack = Envelope.Attack Op.Decay = Envelope.Decay Op.Sustain = Envelope.Sustain Op.Release = Envelope.Release END SUB DEFSNG A-Z SUB OpenOPL2Patch (Patch AS OPL2Patch, Op1 AS OPL2Operator, Op2 AS OPL2Operator) Patch.Op1AmplitudeFlag = Op1.AmplitudeFlag Patch.Op2AmplitudeFlag = Op2.AmplitudeFlag Patch.Op1VibratoFlag = Op1.VibratoFlag Patch.Op2VibratoFlag = Op2.VibratoFlag Patch.Op1EGFlag = Op1.EGFlag Patch.Op2EGFlag = Op2.EGFlag Patch.Op1KeyboardScaleFlag = Op1.KeyboardScaleFlag Patch.Op2KeyboardScaleFlag = Op2.KeyboardScaleFlag Patch.Op1FMMultiple = Op1.FMMultiple Patch.Op2FMMultiple = Op2.FMMultiple Patch.Op1WaveSelect = Op1.WaveSelect Patch.Op2WaveSelect = Op2.WaveSelect Patch.Op1Attack = Op1.Attack Patch.Op2Attack = Op2.Attack Patch.Op1Decay = Op1.Decay Patch.Op2Decay = Op2.Decay Patch.Op1Sustain = Op1.Sustain Patch.Op2Sustain = Op2.Sustain Patch.Op1Release = Op1.Release Patch.Op2Release = Op2.Release END SUB DEFINT A-Z SUB PlayOPLMusicBar (Music AS Music, FMKey AS OPL2, OPL2Grid%(), Score$, Frequency$, Volume$) IF FMKey.InterruptFlag = 1 THEN IF FMKey.TimerFlag2 = 1 THEN IF LEN(Volume$) > 0 THEN Music.VolumeBarLimit = Music.VolumeStaff + Music.VolumeBarIndex FOR VolumeIndex% = 1 TO Music.VolumeStaffLimit FMKey.Volume = ASC(MID$(Volume$, VolumeIndex%, 1)) FMKey.ActiveChannel = VolumeIndex% SetOPL2InstrumentVolume FMKey, OPL2Grid%() NEXT END IF IF LEN(Frequency$) > 0 THEN FOR FrequencyIndex% = 1 TO Music.FrequencyStaffLimit FrequencyHalfIndex% = Music.FrequencyBarIndex + FrequencyIndex% Frequency1$ = MID$(Frequency$, FrequencyHalfIndex%, 1) Music.IncomingFrequency = ASC(Frequency1$) Music.FrequencyHalf1 = 128 - Music.IncomingFrequency FrequencyHalfIndex% = Music.FrequencyBarLimit + FrequencyIndex% Frequency2$ = MID$(Frequency$, FrequencyHalfIndex%, 1) Music.FrequencyHalf2 = ASC(Frequency2$) FMKey.Frequency = (Music.FrequencyHalf1 * 32) + Music.FrequencyHalf2 IF FMKey.TimerFlag1 = 1 THEN ScoreSubject$ = MID$(Score$, 1, Music.BarIndex + FrequencyIndex% - 1) ScorePredicate$ = MID$(Score$, Music.BarIndex + FrequencyIndex% + 1) Score$ = ScoreSubject$ Score$ = Score$ + Frequency1$ Score$ = Score$ + ScorePredicate$ ScoreSubject$ = MID$(Score$, 1, Music.BarIndex + FrequencyBarIndex% - 1) ScorePredicate$ = MID$(Score$, Music.BarIndex + FrequencyBarIndex% + 1) IF Music.FrequencyAuxillaryFlag = 1 THEN Score$ = ScoreSubject$ Score$ = Score$ + Frequency2$ Score$ = Score$ + ScorePredicate$ ELSEIF Music.FrequencyAuxillaryFlag = 0 THEN Score$ = ScoreSubject$ FOR FrequencyStaffIndex% = 1 TO (FrequencyIndex% - 1) Score$ = Score$ + CHR$(0) NEXT Score$ = Score$ + Frequency2$ FOR FrequencyStaffIndex% = 1 TO (Music.StaffLimit - FrequencyIndex%) Score$ = Score$ + CHR$(0) NEXT Score$ = Score$ + ScorePredicate$ END IF Music.SongLimit = Music.SongLimit + Music.StaffLimit Music.FrequencyAuxillaryFlag = 1 END IF FMKey.ActiveChannel = FrequencyIndex% LoadOPL2Frequency FMKey, OPL2Grid%() NEXT Music.FrequencyAuxillaryFlag = 0 END IF END IF IF FMKey.TimerFlag1 = 1 THEN Music.BarLimit = Music.StaffLimit + Music.BarIndex IF Music.SongLimit > Music.BarLimit THEN Music.NoteLimit = Music.SongLimit - Music.BarLimit Bar$ = MID$(Score$, Music.BarIndex, Music.StaffLimit) FOR NoteIndex% = 1 TO Music.NoteLimit Music.IncomingNote = ASC(MID$(Bar$, NoteIndex%, 1)) IF Music.IncomingNote > 96 THEN Music.FrequencyHalf1 = 128 - Music.IncomingNote FrequencyHalfIndex% = Music.BarLimit + NoteIndex% Frequency$ = MID$(Score$, FrequencyHalfIndex%, 1) Music.FrequencyHalf2 = ASC(Frequency$) FMKey.Frequency = (Music.FrequencyHalf1 * 32) + Music.FrequencyHalf2 END IF Music.Octave = INT(Music.IncomingNote / 12) IF Music.Octave > 8 THEN Music.Octave = 0 END IF Music.Note = Music.IncomingNote - (Music.Octave * 12) IF Music.Note < 7 THEN IF Music.Note < 3 THEN IF Music.Note = 1 THEN FMKey.Frequency = FMKey.NoteCSharp ELSEIF Music.Note = 2 THEN FMKey.Frequency = FMKey.NoteD ELSE FMKey.Frequency = FMKey.NoteDSharp END IF ELSE IF Music.Note = 3 THEN FMKey.Frequency = FMKey.NoteE ELSEIF Music.Note = 4 THEN FMKey.Frequency = FMKey.NoteF ELSE FMKey.Frequency = FMKey.NoteFSharp END IF END IF ELSEIF Music.Note <= 12 THEN IF Music.Note < 9 THEN IF Music.Note = 7 THEN FMKey.Frequency = FMKey.NoteG ELSEIF Music.Note = 8 THEN FMKey.Frequency = FMKey.NoteGSharp ELSE FMKey.Frequency = FMKey.NoteA END IF ELSE IF Music.Note = 10 THEN FMKey.Frequency = FMKey.NoteASharp ELSEIF Music.Note = 11 THEN FMKey.Frequency = FMKey.NoteB ELSE FMKey.Frequency = FMKey.NoteC END IF END IF END IF FMKey.Octave = Music.Octave FMKey.ActiveChannel = NoteIndex% LoadOPL2Frequency FMKey, OPL2Grid%() NEXT Music.BarIndex = Music.BarLimit Music.BarIndex = Music.BarIndex + Music.StaffLimit Music.BarIndex = Music.BarIndex + Music.FrequencyStaffLimit END IF END IF FMKey.MonoGridOffset = FMKey.FrequencyControl FMKey.MonoGridLimit = FMKey.FrequencyLimit MonoLoadOPL2 FMKey, OPL2Grid%() END IF END SUB DEFSNG A-Z SUB RetreiveOPL2Status (FMKey AS OPL2) FMKey.Status = INP(FMKey.MonoStatusPort) FMKey.TimerFlag1 = FMKey.TimerStatusBit1 AND FMKey.Status FMKey.TimerFlag2 = FMKey.TimerStatusBit2 AND FMKey.Status FMKey.InterruptFlag = FMKey.InterruptBit AND FMKey.Status END SUB DEFINT A-Z SUB SetOPL2InstrumentVolume (FMKey AS OPL2, OPL2Grid%()) FMKey.IncomingData = FMKey.KeyScaleLevel * FMKey.KeyScaleLevelBit FMKey.IncomingData = FMKey.IncomingData + (FMKey.VolumeBit * FMKey.Volume) FMKey.RegisterControl = FMKey.VolumeControl IF FMKey.SynthAlgorithmFlag = 1 THEN FMKey.ActiveOperator = 1 LoadOPL2GridIndex FMKey, OPL2Grid%() ELSE FMKey.ActiveOperator = 1 LoadOPL2GridIndex FMKey, OPL2Grid%() FMKey.ActiveOperator = 2 LoadOPL2GridIndex FMKey, OPL2Grid%() END IF END SUB SUB SetOPL2Tempo (Music AS Music, FMKey AS OPL2) Music.Note32Duration = (60 / Music.Tempo) * .125 FMKey.TimerPreset2 = Music.Note32Duration / FMKey.TimerResolution2 END SUB SUB StereoLoadOPL2 (FMKey AS OPL2, StereoGrid%()) FOR GridIndex% = FMKey.StereoGridOffset TO INT(FMKey.StereoGridLimit) FMKey.ActiveRegister = GridIndex% OUT FMKey.LeftStatusPort, FMKey.ActiveRegister FOR FMCounter = 1 TO FMKey.StatusWriteDelay FMKey.DelayCountdown = INP(FMKey.LeftStatusPort) NEXT FMKey.IncomingLeftData = StereoGrid%(GridIndex%) OUT FMKey.LeftDataPort, FMKey.IncomingLeftData FOR FMCounter = 1 TO FMKey.DataWriteDelay FMKey.DelayCountdown = INP(FMKey.LeftStatusPort) NEXT GridIndex% = GridIndex% + 1 FMKey.IncomingRightData = StereoGrid%(GridIndex%) OUT FMKey.RightStatusPort, FMKey.ActiveRegister FOR FMCounter = 1 TO FMKey.StatusWriteDelay FMKey.DelayCountdown = INP(FMKey.RightStatusPort) NEXT OUT FMKey.RightDataPort, FMKey.IncomingRightData FOR FMCounter = 1 TO FMKey.DataWriteDelay FMKey.DelayCountdown = INP(FMKey.RightStatusPort) NEXT NEXT END SUB