Rev 49 | Blame | Compare with Previous | Last modification | View Log | Download
;-Minimal ayFX player2 v0.16 20.06.06--------------------------;; ;; Простейший плеер эффектов. Проигрывает эффекты на одном AY, ;; без музыки на фоне. Громкость проигрывания эффектов задаётся ;; при их вызове. Приоритет выбора каналов: если есть свободные ;; каналы, выбирается один из них. Если свободных каналов нет, ;; выбирается наиболее давно звучащий. Процедура проигрывания ;; использует регистры AF,BC,DE,HL,IX. ;;P.S. от Alone Coder'а: задействовал IY и еще 2 байта, чтобы;не играть эффект, когда он тише музыки (убрано для TFM музыки);P.P.S. TurboSound fix 16.02.18; ;; Инициализация: ;; ld hl, адрес банка эффектов ;; call AFXINIT ;; ;; Запуск эффекта: ;; ld a, номер эффекта (0..255) ;; ld c, относительная громкость (-15..15) ;; call AFXPLAY ;; ;; В обработчике прерывания: ;; call AFXFRAME ;; ;;--------------------------------------------------------------;; описатели каналов, по 5+2 байт на канал:; +0 (2) текущий адрес (канал свободен, если старший байт =0x00); +2 (2) время звучания эффекта; +4 (1) громкость эффекта; +6 (2) ПЕРИОД ТОНАЛЬНИКА; ...afxChDesc DS 3*(5+2);--------------------------------------------------------------;; Инициализация плеера эффектов. ;; Выключает все каналы, устанавливает переменные. ;; Вход: HL = адрес банка с эффектами ;;--------------------------------------------------------------;afxINITld a,(hl)ld (afxEffectsAll),aINC HLLD (afxBnkAdr+1),HL ;сохраняем адрес таблицы смещенийLD HL,afxChDesc ;помечаем все каналы как пустыеLD DE,0x00FFLD B,3afxInit0LD (HL),DINC HLLD (HL),DINC HLLD (HL),EINC HLLD (HL),EINC HLLD (HL),DINC HLLD (HL),DINC HLLD (HL),DINC HLDJNZ afxInit0; ifdef TFM; ld a,(TURBOFMON); or a; ret nz ;TFM present; ld a,0xc9 ;ret; ld (waitstatus),a; endifRET ;TFM absent;--------------------------------------------------------------;; Проигрывание текущего кадра. ;; Параметров не имеет. ;;--------------------------------------------------------------;afxFRAMELD BC,0x03FDLD IX,afxChDescafxFrame0PUSH BCLD H,(IX+1) ;сравнение старшего байта;адреса на <11ld a,hor ajp z,afxFrame7 ;канал не играет, пропускаемLD L,(IX+0)LD E,(HL) ;берём значение информационного байтаINC HLLD A,11SUB B ;выбираем регистр громкости:LD D,B ;(11-3=8, 11-2=9, 11-1=10)LD B,0xFF ;начало вывода значения; ifndef TFM ;для TurboSound!!! выключено для TFM;OUT (C),B ;AY 0x1(0) ;т.к.может вырубиться при HY=0xFF ;РАСКОММЕНТИРОВАТЬ для TurboSound!!!LD HY,B ;выкл громкости; endif;; ifdef TFM; call waitstatus; endifOUT (C),A ;выбрали регистр громкости; ifdef TFM; call waitstatus; endif; ifndef TFM ;для TurboSound!!! выключено для TFMIN A,(C)CP 16JR NC,$+4SUB 3;4JR NC,$+3XOR ALD (afxcurvolCHN),A; endifLD A,EAND 0x0FADD A,(IX+4) ;применяем текущую громкость каналаCP 15JP M,$+5LD A,15OR AJP P,$+4XOR A; ifndef TFM ;для TurboSound!!! выключено для TFMCP 13 ;громкую часть эффекта не глушимJR NC,afxcurvONafxcurvolCHN=$+1CP 0JR C,afxcurvOFFafxcurvONLD HY,0xBF ;вклafxcurvOFFLD B,HY; else; LD B,0xBF; endifOUT (C),A ;собственно вывод громкостиBIT 5,E ;будет изменение тона?JR Z,afxFrame1 ;тон не изменяетсяLD A,(HL)LD (IX+5),AINC HLLD A,(HL)LD (IX+6),AINC HLafxFrame1LD A,3 ;выбираем регистры тона:SUB D ;3-3=0, 3-2=1, 3-1=2ADD A,A ;0*2=0, 1*2=2, 2*2=4LD B,0xFF ;выводим значения тона; ifdef TFM; call waitstatus; endifOUT (C),A; ifdef TFM; call waitstatus; endif; ifndef TFM ;для TurboSound!!! выключено для TFMLD B,HY; else; LD B,0xBF; endifLD D,(IX+5) ;младший байт тона может быть 0xfe!!!OUT (C),DLD B,0xFFOUT (C),B ;AY 0x1(0) ;т.к.может вырубиться при HY=0xFFINC A; ifdef TFM; call waitstatus; endifOUT (C),A; ifdef TFM; call waitstatus; endif; ifndef TFM ;для TurboSound!!! выключено для TFMLD B,HY; else; LD B,0xBF; endifLD D,(IX+6)OUT (C),D;afxFrame1BIT 6,E ;будет изменение шума?JR Z,afxFrame3 ;шум не изменяетсяLD A,(HL) ;читаем значение шумаSUB 0x20JR C,afxFrame2 ;меньше 0x20, играем дальшеLD H,A ;иначе конец эффектаLD (IX+2),0xFE ;делаем время наибольшим-1LD (IX+3),0xFFLD E,0x90 ;выключаем тон и шум в микшереJR afxFrame3afxFrame2INC HLLD B,0xFF ;вывод значения шумаLD D,6; ifdef TFM; call waitstatus; endifOUT (C),D; ifdef TFM; call waitstatus; endif; ifndef TFM ;для TurboSound!!! выключено для TFMLD B,HY; else; LD B,0xBF; endifOUT (C),AafxFrame3POP BC ;восстанавливаем значение цикла в BPUSH BCINC B ;4..2 ;количество сдвигов для флагов TNLD A,0b01101111 ;маска для флагов TNafxFrame4RRC E ;сдвигаем флаги и маскуRRCADJNZ afxFrame4LD D,ALD BC,0xFFFD ;читаем регистр микшераLD A,7; ifdef TFM; call waitstatus; endifOUT (C),A; ifdef TFM; call waitstatus; endifIN A,(C)XOR E ;накладываем флаги каналаAND DXOR E; ifndef TFM ;для TurboSound!!! выключено для TFMLD B,HY; else; LD B,0xBF; endifOUT (C),A ;выводим обратно в микшер ;может быть 0xfe!!!LD B,0xFFOUT (C),B ;AY 0x1(0) ;т.к.может вырубиться при HY=0xFFafxFrame5LD C,(IX+2) ;увеличиваем счётчик времениLD B,(IX+3)INC BCafxFrame6LD (IX+2),CLD (IX+3),BLD (IX+0),L ;сохраняем изменившийся адресLD (IX+1),HafxFrame7LD BC,5+2 ;переходим к следующему каналуADD IX,BCPOP BCDEC BJP NZ,afxFrame0RET;--------------------------------------------------------------;; Запуск эффекта на свободном канале. При отсутствии ;; свободных каналов выбирается наиболее давно звучащий. ;; Вход: A = номер эффекта 0..255 ;; С = относительная громкость -15..15 ;;--------------------------------------------------------------;afxPLAYafxPLAY.A.=$+1ld a,0afxPLAY.B.=$+1ld c,0afxEffectsAll=$+1cp 0ret ncpush ixPUSH BC ;сохраняем громкостьLD DE,0 ;в DE наибольшее время при поискеLD H,ELD L,AADD HL,HLafxBnkAdrLD BC,0 ;адрес таблицы смещений эффектовADD HL,BCLD C,(HL)INC HLLD B,(HL)ADD HL,BC ;адрес эффекта получен в hlPUSH HL ;сохраняем адрес эффекта на стекеLD HL,afxChDesc ;поиск пустого каналаLD B,3afxPlay0INC HLINC HLLD A,(HL) ;сравниваем время канала с наибольшимINC HLINC HLCP EJR C,afxPlay1LD C,ALD A,(HL)CP DJR C,afxPlay1LD E,C ;запоминаем наибольшее времяLD D,APUSH HL ;запоминаем адрес канала +3 в IXPOP IXafxPlay1INC HLINC HLINC HLDJNZ afxPlay0POP DE ;забираем адрес эффекта из стекаLD (IX-4),E ;заносим в описатель каналаLD (IX-3),DLD (IX-2),B ;зануляем время звучанияLD (IX-1),BPOP BC ;забираем громкостьLD (IX-0),C ;и заносим её в описатель каналаpop ixret; ifdef TFM;waitstatus;;bc=0xfffd; IN F,(C); JP M,$-2; ret; endif