metamorpho (18.08.2020)
С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
При взятии монеты эффект создаётся вот как - в программе обработки прерываний срабатывает следующее:
mvi a,251
out 02
С палитрой это не связано напрямую.
Чёрный до белого и назад кажется будет слишком контрастно (на мой взгляд).
Насчёт набора микровзрывов хорошая идея, попробую !!
Игра готова по всем пунктам, кроме музыки.
Осталось вставить музыку и может некоторые звуки изменить.
После различных оптимизаций кода и информации удалось неплохо сократить файл - на данный момент игра занимает 30756 байт
Можно ещё кое-что ужать но похоже этого хватит.
metamorpho, а картинки из игры, ака скриншоты
в первый пост
Наткнулся в закромах на файл "Миссия невыполнима.mid", правда в ней только часть темы.
Написал простенький музыкальный редактор. К нему написал свой плеер. Возникла проблема не пойму почему так работает.
Плеер у меня обрабатывает три канала отдельно. Каждый канал отдельно работает правильно, но если их сразу три запускать то один играет, а два других "хрипят".
В чём может быть проблема ? Может есть какая-то особенность программирования каналов ВИ53 ?
Вот код:
Скрытый текст
;
;-----------------------------------------------
; Super player 08.2020
;-----------------------------------------------
;
;==== Мой формат плеера:
;===================================
pit_init1 .equ 36h
pit_init2 .equ 76h
pit_init3 .equ 0b6h
timeron .equ 1h
;
;------------------------------------
.ORG 0100H
; =======================
M0000H: DI
XRA A
OUT 10H ;
;
MVI A,0C3H
STA 0000H ;
STA 0038H ;
LXI H,M0000H
SHLD 0001H
LXI H,vsync
SHLD 0039H
;
LXI SP,100H
end_program:
mvi a, pit_init1 ; отключить канал 1
out $08
mvi a, pit_init2 ; отключить канал 2
out $08
mvi a, pit_init3 ; отключить канал 3
out $08
;
lxi h, repeat_point1 ;
shld data_pointer1 ; инициализация канала 1
lxi h, repeat_point2 ;
shld data_pointer2 ; инициализация канала 2
lxi h, repeat_point3 ;
shld data_pointer3 ; инициализация канала 3
mvi a, 1 ;
sta wait_counter1 ;
sta wait_counter2
sta wait_counter3
ei
command_line:
jmp command_line
;
;============================================ Плеер в программе обработки прерываний
;
vsync:
push h
push d
push b
push psw
;======================= обработка канала 1
kanal1:
lxi h,wait_counter1 ; отрабатываем установленную длительность
dcr m
jnz kanal2 ; переход если длительность не равна нулю
; ===== иначе если равна нулю то загружаем следующие данные
read_command1:
lhld data_pointer1 ; читаем данные
mov a,m
inx h
shld data_pointer1
cpi 255 ; проверяем это не конец мелодии ?
jnz oktava_can1 ; если нет то идём на обработку данных
; если конец мелодии канала то глушим канал
mvi a, 36h ; отключить канал 1
out $08
lxi h, repeat_point1 ; перезапуск мелодии
shld data_pointer1
jmp kanal2 ; переход на канал 2
;==================================================== проверка октавы
oktava_can1:
; ==============отсеиваем только то что от 108-114
cpi 114
jnc dlina_can1 ; если больше 114 то уходим
cpi 108
jc dlina_can1 ; если меньше 108 то уходим
call oktavian ; возвращает в HL адрес октавы
shld oktava_counter1 ; установка октавы для канала
lhld data_pointer1 ; читаем данные
mov a,m
inx h
shld data_pointer1
;============================================== проверка это длительность ?
dlina_can1:
; ==============отсеиваем только то что от 101-107
cpi 107
jnc off_1 ; если больше 114 то уходим
cpi 101
jc off_1 ; если меньше 108 то уходим
call dlinachiz ; возвращает в A длительность канала
sta swait_counter1 ; установка длительности для канала
lhld data_pointer1 ; читаем данные
mov a,m
inx h
shld data_pointer1
;============================================== проверка это пауза ?
off_1:
cpi 100
jnz set_1
mvi a,36h ; выключить канал 1
out 08
lda swait_counter1 ; взять длительность канала
sta wait_counter1 ; установка текущей длительности для канала
jmp kanal2 ; переход на канал 2
;============================================== значит это НОТА 1-12
set_1:
lhld oktava_counter1 ; берём адрес октавы для ноты
lxi d, 0002h; вычисляем адрес ноты
rizunok1:
dcr a
jz wuwitron1 ; нашли адресс ноты
dad d
jmp rizunok1
wuwitron1:
mvi a,36h ; задать режим для канала 1 (включить канал)
out 08
mov a, m
out 0bH
inx h
mov a, m
out 0bH
lda swait_counter1 ; взять длительность канала
sta wait_counter1 ; установка текущей длительности для канала
;==============================================================
;======================= обработка канала 2
;==============================================================
kanal2:
lxi h,wait_counter2 ; отрабатываем установленную длительность
dcr m
jnz kanal3 ; переход если длительность не равна нулю
; ===== иначе если равна нулю то загружаем следующие данные
read_command2:
lhld data_pointer2 ; читаем данные
mov a,m
inx h
shld data_pointer2
cpi 255 ; проверяем это не конец мелодии ?
jnz oktava_can2 ; если нет то идём на обработку данных
; если конец мелодии канала то глушим канал
mvi a, 76h ; отключить канал 2
out $08
lxi h, repeat_point2 ; перезапуск мелодии
shld data_pointer2
jmp kanal3 ; переход на канал 2
;==================================================== проверка октавы
oktava_can2:
; ==============отсеиваем только то что от 108-114
cpi 114
jnc dlina_can2 ; если больше 114 то уходим
cpi 108
jc dlina_can2 ; если меньше 108 то уходим
call oktavian ; возвращает в HL адрес октавы
shld oktava_counter2 ; установка октавы для канала
lhld data_pointer2 ; читаем данные
mov a,m
inx h
shld data_pointer2
;============================================== проверка это длительность ?
dlina_can2:
; ==============отсеиваем только то что от 101-107
cpi 107
jnc off_2 ; если больше 114 то уходим
cpi 101
jc off_2 ; если меньше 108 то уходим
call dlinachiz ; возвращает в A длительность канала
sta swait_counter2 ; установка длительности для канала
lhld data_pointer2 ; читаем данные
mov a,m
inx h
shld data_pointer2
;============================================== проверка это пауза ?
off_2:
cpi 100
jnz set_2
mvi a,76h ; выключить канал 2
out 08
lda swait_counter2 ; взять длительность канала
sta wait_counter2 ; установка текущей длительности для канала
jmp kanal3 ; переход на канал 2
;============================================== значит это НОТА 1-12
set_2:
lhld oktava_counter2 ; берём адрес октавы для ноты
lxi d, 0002h; вычисляем адрес ноты
rizunok2:
dcr a
jz wuwitron2 ; нашли адресс ноты
dad d
jmp rizunok2
wuwitron2:
mvi a,76h ; задать режим для канала 2 (включить канал)
out 08
mov a, m
out 0aH
inx h
mov a, m
out 0aH
lda swait_counter2 ; взять длительность канала
sta wait_counter2 ; установка текущей длительности для канала
;==============================================================
;======================= обработка канала 3
;==============================================================
kanal3:
lxi h,wait_counter3 ; отрабатываем установленную длительность
dcr m
jnz end_int ; выход из прерываний если длительность не равна нулю
; ===== иначе если равна нулю то загружаем следующие данные
read_command3:
lhld data_pointer3 ; читаем данные
mov a,m
inx h
shld data_pointer3
cpi 255 ; проверяем это не конец мелодии ?
jnz oktava_can3 ; если нет то идём на обработку данных
; если конец мелодии канала то глушим канал
mvi a, 0b6h ; отключить канал 3
out $08
lxi h, repeat_point3 ; перезапуск мелодии
shld data_pointer3
jmp end_int ; выход из прерываний
;==================================================== проверка октавы
oktava_can3:
; ==============отсеиваем только то что от 108-114
cpi 114
jnc dlina_can3 ; если больше 114 то уходим
cpi 108
jc dlina_can3 ; если меньше 108 то уходим
call oktavian ; возвращает в HL адрес октавы
shld oktava_counter3 ; установка октавы для канала
lhld data_pointer3 ; читаем данные
mov a,m
inx h
shld data_pointer3
;============================================== проверка это длительность ?
dlina_can3:
; ==============отсеиваем только то что от 101-107
cpi 107
jnc off_3 ; если больше 114 то уходим
cpi 101
jc off_3 ; если меньше 108 то уходим
call dlinachiz ; возвращает в A длительность канала
sta swait_counter3 ; установка длительности для канала
lhld data_pointer3 ; читаем данные
mov a,m
inx h
shld data_pointer3
;============================================== проверка это пауза ?
off_3:
cpi 100
jnz set_3
mvi a,0b6h ; выключить канал 3
out 08
lda swait_counter3 ; взять длительность канала
sta wait_counter3 ; установка текущей длительности для канала
jmp end_int ; выход из прерываний
;============================================== значит это НОТА 1-12
set_3:
lhld oktava_counter3 ; берём адрес октавы для ноты
lxi d, 0002h; вычисляем адрес ноты
rizunok3:
dcr a
jz wuwitron3 ; нашли адресс ноты
dad d
jmp rizunok3
wuwitron3:
mvi a,0b6h ; задать режим для канала 3 (включить канал)
out 08
mov a, m
out 09H
inx h
mov a, m
out 09H
lda swait_counter3 ; взять длительность канала
sta wait_counter3 ; установка текущей длительности для канала
;=================================
end_int:
pop psw
pop b
pop d
pop h
;
ei
ret
;
;
;============================================================
;---------------------------
; контр-октава (12 нот)
note_table1:
dw 45872,43290,40872,38560,36408,34364,32432,30612,28902,27273,25729,24311 ; до/до#/ре/ре#/ми/фа/фа#/соль/соль#/ля/ля#/си
; большая-октава
note_table2:
dw 22936,21645,20436,19280,18204,17182,16216,15306,14451,13636,12876,12146 ; до до# ре ре# ми фа фа# соль соль# ля ля# си
; малая-октава
note_table3:
dw 11468,10823,10218,9646,9102,8591,8108,7653,7229,6818,6438,6075 ; до до# ре ре# ми фа фа# соль соль# ля ля# си
; 1-я октава
note_table4:
dw 5734,5415,5107,4823,4551,4296,4054,3827,3614,3409,3219,3036 ; до до# ре ре# ми фа фа# соль соль# ля ля# си
; 2-я октава
note_table5:
dw 2867,2708,2554,2412,2275,2147,2027,1913,1805,1705,1609,1519 ; до до# ре ре# ми фа фа# соль соль# ля ля# си
; 3-я октава
note_table6:
dw 1433,1353,1277,1205,1137,1074,1014,957,904,852,804,759 ; до до# ре ре# ми фа фа# соль соль# ля ля# си
; 4-я октава
note_table7:
dw 717,677,639,602,569,537,507,472,452,426,402,380 ; до до# ре ре# ми фа фа# соль соль# ля ля# си
;================sound_data: .db
repeat_point1: db 111,104,1,2,3,4,5,6,7,8,9,10,11,12,255
repeat_point2: db 112,104,1,2,3,4,5,6,7,8,9,10,11,12,255
repeat_point3: db 113,104,1,2,3,4,5,6,7,8,9,10,11,12,255
;255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
;---------------------------
data_pointer1: .dw 0 ; позиция в нотном массиве для канала 1
data_pointer2: .dw 0 ; позиция в нотном массиве для канала 2
data_pointer3: .dw 0 ; позиция в нотном массиве для канала 3
wait_counter1: .db 0 ; текущее вычисление длительность для канала 1
wait_counter2: .db 0 ; текущее вычисление длительность для канала 2
wait_counter3: .db 0 ; текущее вычисление длительность для канала 3
swait_counter1: .db 0 ; установленная длительность для канала 1
swait_counter2: .db 0 ; установленная длительность для канала 2
swait_counter3: .db 0 ; установленная длительность для канала 3
oktava_counter1: .db 0 ; установленная ОКТАВА для канала 1
oktava_counter2: .db 0 ; установленная ОКТАВА для канала 2
oktava_counter3: .db 0 ; установленная ОКТАВА для канала 3
;=======================================
; подпрограммы определения длительности
dlinachiz:
cpi 101
jnz ghtimin1
mvi a,255 ;------ 1 - full
ret
ghtimin1:
cpi 102
jnz ghtimin2
mvi a,128 ;------ 1/2
ret
ghtimin2:
cpi 103
jnz ghtimin3
mvi a,64 ;------ 1/4
ret
ghtimin3:
cpi 104
jnz ghtimin4
mvi a,32 ;------ 1/8
ret
ghtimin4:
cpi 105
jnz ghtimin5
mvi a,16 ;------ 1/16
ret
ghtimin5:
cpi 106
jnz ghtimin6
mvi a,8 ;------ 1/32
ret
ghtimin6:
cpi 107
rnz
mvi a,4 ;------ 1/64
ret
;=======================================
; подпрограммы определения октавы
oktavian:
cpi 108
jnz timin1
lxi h,note_table1 ; контр-октава
ret
timin1:
cpi 109
jnz timin2
lxi h,note_table2 ; большая-октава
ret
timin2:
cpi 110
jnz timin3
lxi h,note_table3 ; малая-октава
ret
timin3:
cpi 111
jnz timin4
lxi h,note_table4 ; 1-я октава
ret
timin4:
cpi 112
jnz timin5
lxi h,note_table5 ; 2-я октава
ret
timin5:
cpi 113
jnz timin6
lxi h,note_table6 ; 3-я октава
ret
timin6:
cpi 114
rnz
lxi h,note_table7 ; 4-я октава
ret
;==============================
.end
[свернуть]
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)