Auld Lang Syne — Dave change notes
uglisynthstart_ug:
di
call screensetup
ld hl,auldtitle ;подготовка заголовка
call printstring ;и его печать
ld a,16+5 ;cyan (установка цветов бордюра красный/cyan)
ld (colour1smc+1),a
ld a,2 ;red
ld (colour2smc+1),a
ld hl,auld0
call playsong
ld a,16+1 ;blue (установка цветов бордюра синий/жёлтый)
ld (colour1smc+1),a
ld a,6 ;yellow
ld (colour2smc+1),a
ld hl,auldtext1 ;подготовка первой части слов — should alud
call printstring ;и её печать
ld hl,auld1 ;подготовка фрагмента мелодии
call playsong ;и его воспроизведение
ld hl,auldtext2 ;подготовка следующей части слов — and never
call printstring ;и её печать
ld hl,auld2
call playsong
ld hl,auldtext3 ;should auld
call printstring
ld hl,auld3
call playsong
ld hl,auldtext4 ;for ths sake
call printstring
ld hl,auld4
call playsong
ld hl,auldtext5
call printstring
ld hl,trill1
call playsong
ld hl,auld5
call playsong
ld hl,auldtext6
call printstring
ld hl,trill1
call playsong
ld hl,auld6
call playsong
ld hl,auldtext7
call printstring
ld hl,trill1
call playsong
ld hl,auld7
call playsong
ld hl,auldtext8
call printstring
ld hl,auld8
call playsong
ld a,7 ; 7 — код белого цвета.
call 8859 ; установка цвета бордюра.
call wastetime ;небольшая пауза
ld hl,auldtext9
call printstring
call wastetime ;небольшая пауза
call wastetime ;небольшая пауза
call wastetime ;небольшая пауза
ld hl,auldtext10
call printstring
ei
ret
playsong: ;вызывается, когда HL указывает на musidata
ld (songpointer),hl ;инициализируем songpointer фрагментом мелодии
testloop:
ld hl,(songpointer)
ld (smc_data+1),hl
inc hl
inc hl
ld (songpointer),hl
smc_data:
ld hl,(auld1)
ld a,l ;проверяем, равен ли L (младший байт) нулю (маркер конца мелодии), если да — возврат
or a
ret z
;Проверка на «паузу» (rest) (равно ли значение H=0)
ld a,h
or a
jr z,rest_routine
call playnote
;jr rest_routine ;ЭТО ВСТАВЛЯЕТ ПАУЗЫ КАЖДЫЙ РАЗ, ДЛЯ ТЕСТИРОВАНИЯ
jr testloop ; Переход к следующему элементу мелодии
;
rest_routine:
ld bc,20000 ;вставляет слышимую паузу ЭТО ДОЛЖНО ЗАВИСЕТЬ ОТ длины L, ****но пока еще нет***
insert_pause:
nop
dec bc
ld a,b
or c
jr nz,insert_pause
jr testloop ; Переход к следующему элементу мелодии
playnote:
;загрузка данных (hl) l=длина, h=высота тона
tempo_smc:
ld a,4 ;напр. 4 — сколько раз по циклу (своего рода множитель темпа)
ld (smc_length+1),a ;установка длины цикла при сбросе
ld (noteroll),a ;noteroll ;и изначально
ld (notelength),hl
ld e,1 ;убедиться, что нет ошибочной «предыдущей ноты», совпадающей с текущей
jumpbackpoint: ;возврат сюда для настройки d с высотой ноты
ld hl,noteroll ;noteroll — это счетчик от X до 0, определяющий сколько раз
dec (hl) ;проходит цикл (т.е. длина в регистре l)
jr nz,skipcounterdown ;
smc_length:
ld (hl),0 ;сброс noteroll в исходное значение (равно темпу) (настроено ранее)
ld hl,notelength ;notelength — это длина (но см. также noteroll)
dec (hl) ;уменьшать, пока не станет 0
ret z ;
skipcounterdown:
ld hl,notepitch ;в d заносится требуемая высота
ld d,(hl)
generateanote: ;генерация ноты
;высота тона хранится в регистре d
;но сначала проверка: это «новая» нота?
ld a,d
cp e ;в e хранится предыдущая нота
jr z,sameoldnote ;если та же самая, менять счетчики и т.д. не нужно
newnotebeingplayed:
xor a ;сброс флага carry
ld a,d
ld e,a ;сохранить эту ноту для сравнения в следующий раз
ld (smc_ug2+1),a
rra ;a=d/2
ld c,a ;c используется для временного хранения счетчика
sameoldnote: ;вход сюда, если это та же нота, что и раньше
ld a,c ;восстановить счетчик
inc a ;инкремент счетчика
ld b,a ;загрузить в b для цикла djnz
killsometime:
nop ;4 такта, один байт
cp (hl) ;7 тактов, один байт, без цели — просто убить время — прим.: здесь можно убить больше времени, но ноты придется перенастраивать!
djnz killsometime
colour1smc:
ld a,17 ;также определяет цвет бордюра. 16+цвет. 17=синий
out (254),a
ld a,d ;получить высоту
sub c ;вычесть счетчик
inc a ;прибавить 1, чтобы значение никогда не стало нулем
ld b,a ;поместить результат в b
killsometime2:
nop ;4 такта, один байт
cp (hl) ;7 тактов, один байт, без цели — просто убить время
djnz killsometime2
colour2smc:
ld a,6 ;также определяет цвет бордюра. 0+цвет . 6=желтый
out (254),a
;теперь изменим ширину импульса, меняя a/c
ld a,c
smc_ug1: ;это smc, модифицируемый для выбора: увеличивать или уменьшать ширину импульса
add a,255 ;либо прибавить, либо вычесть 1 (вычитание 1 = прибавление 255)
ld c,a ;обновляем c
jp z,changedirection
smc_ug2:
ld a,0 ;это smc, модифицируемый при проигрывании новой ноты
cp c
jp z,changedirection
jp jumpbackpoint
changedirection:
ld a,(smc_ug1+1) ;использует дополнительный код, чтобы превратить 1 в 255 и наоборот
cpl ;
inc a ;
ld (smc_ug1+1),a ;
jp jumpbackpoint
; эти переменные используются для подсчета длительности ноты и длины волны
noteroll: db 0
notelength: db 1
notepitch: db 253 ; длительность и высота ноты
songpointer: dw auld1
;SONGDATA (Auld Lang Syne)
auld0: db c3c*2,c3 ;Shoullllldddd
db c3c*2,c3
db 0
auld1: ;should auld aquaintance be forgot,
; db c3c,c3
db 120,f3
db e3q,e3
db f3c,f3
db a3c,a3
db 135,g3
db f3q,f3
db g3c,g3
db 0
auld2: ;and never brought to mind
db a3q,a3
db g3q,g3
db 120,f3
db f3q,f3
db a3c,a3
db c4c,c4
db d4c,d4
db d4c,d4
db d4c,d4
db 0 ;маркер конца песни
auld3: ;should auld aquaintance be forgot,
db d4c,d4
db 181,c4
auld7: ;то же, что и конец melody3
db a3q,a3
db a3c,a3
db f3c,f3
db 135,g3
db f3q,f3
db g3c,g3
db 0
auld4: ;and the days of auld lang syne
db a3q,a3
db g3q,g3
db 120,f3
db d3q,d3
db d3c,d3
db c3c,c3
db 241,f3
db 0
trill1: ;for auld
db f3c/16,f3
db d4c/16,d4
db f3c/16,f3
db d4c/16,d4
db f3c/16,f3
db d4c/16,d4
db f3c/16,f3
db d4c/16,d4
db f3c/16,f3
db d4c/16,d4
db f3c/16,f3
db d4c/16,d4
db f3c/16,f3
db d4c/16,d4
db f3c/16,f3
db d4c/16,d4
DEFB 11, 122, 7, 188
DEFB 11, 122, 7, 188
DEFB 11, 122, 7, 188
DEFB 11, 122, 7, 188
DEFB 11, 122, 7, 188
DEFB 11, 122, 7, 188
DEFB 11, 122, 7, 188
DEFB 11, 122, 7, 188
db 0
auld5: ;(for auld) lang syne my dear
db a3q,a3
db a3c,a3
db f3c,f3
db 135,g3
db f3q,f3
db g3c,g3
db 0
auld6: ;(for auld) lang syne
db a3q,a3
db a3c,a3
db c4c,c4
db d4c,d4
db d4c,d4
db d4c,d4
db 0
auld8: ;как мелодия 4
db a3q,a3 ;for
db g3q,g3 ;the
db 120,f3 ;sake
db d3q,d3 ;of
db d3c,d3 ;auld
;langtrill
db c3c/24,c3
db e3c/24,e3
db g3c/24,g3
db as3c/24,as3
db c4c/24,c4
db c3c/24,c3
db e3c/24,e3
db g3c/24,g3
db as3c/24,as3
db c4c/24,c4
db c3c/24,c3
db e3c/24,e3
db g3c/24,g3
db as3c/24,as3
db c4c/24,c4
db c3c/24,c3
db e3c/24,e3
db g3c/24,g3
db as3c/24,as3
db c4c/24,c4
db c3c/24,c3
db e3c/24,e3
db g3c/24,g3
db as3c/24,as3
db c4c/24,c4
;synetrill
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db f3c*4/48,f3
db a3c*4/48,a3
db c4c*4/48,c4
db 0
;вероятно, лишний код/мишура
screensetup:
ld a,2 ; верхний экран
call 5633 ; открыть канал из подпрограммы печати ПЗУ
ld a,56 ; чёрный ink (6) на белом paper (0*8) + bright (64*0)
ld (23693),a ; установить цвета экрана.
call 3503 ; очистить экран.
ld a,7 ; 7 — код белого цвета.
call 8859 ; установить цвет бордюра.
; ld hl,memorystring ;текст о памяти
; call printstring
; ld bc,uglisynthstart_ug
; call 11563 ; положить число из bc в стек.
; call 11747 ; отобразить вершину калькуляторного стека.
; ld a,"-"
; rst 16
; ld bc,firstfreebyte_ug
; call 11563 ; положить число из bc в стек.
; call 11747 ; отобразить вершину калькуляторного стека.
ret
;memorystring:
; db 22,21,0,"Memory : ",255
printstring: ;дешевая и сердитая подпрограмма печати строки, hl указывает на строку (завершается 255, а не 0, чтобы упростить управляющие коды)
ld a,(hl)
inc a ;это 255?
ret z ;если да, выйти из цикла
dec a
rst 16 ;если нет, напечатать её
inc hl ;и перейти к следующему символу
jr printstring
auldtitle: db 22,2,0,'Program: AULDLANG'
db 22,5,0,255
auldtext1:
auldtext3: db 'Should ZX Spectrums be forgot,',13,255
auldtext2: db 'And never brought to mind?',13,255
auldtext4: db 'And auld loading time?',13,13,255
auldtext5: db 'For auld loading time, my dear,',13,255
auldtext6: db 'For auld loading time,',13,255
auldtext7: db 'So put the kettle on, my dear,',13,255
auldtext8: db 'For the sake of loading time.',13,255
auldtext9: db 22,17,0,'ZX FACT:',13,13,'The R in ',34,'R Tape loading error,',34,13,'stands for ... ',255
auldtext10: db 18,1,'Robert Burns',255
wastetime: ;грязный цикл для драматической паузы
ld bc,0
timekill1: dec bc
cp (hl) ;это просто убивает время
ld a,b
or c
ret z
jr timekill1
firstfreebyte_ug equ $
;Определение нот
c3 equ 253 ;c# [концертный строй, 440 Гц]
cs3 equ 240 ;d
db3 equ 240 ;d
d3 equ 226 ;d#
ds3 equ 212 ;e
eb3 equ 212 ;e
e3 equ 200 ;f
f3 equ 188 ;f#
fs3 equ 177 ;g
gb3 equ 177 ;g
g3 equ 166 ;g#
gs3 equ 156 ;a
ab3 equ 156 ;a
a3 equ 147 ;a#
as3 equ 137 ;b
bb3 equ 137 ;b
b3 equ 129 ;C
c4 equ 122 ;C#
cs4 equ 114 ;D
db4 equ 114 ;D
d4 equ 108 ;D#
ds4 equ 101 ;E
eb4 equ 101 ;E
e4 equ 95 ;F
f4 equ 88 ;F#
fs4 equ 83 ;G
gb4 equ 83 ;G
g4 equ 77 ;G#
gs4 equ 73 ;A
ab4 equ 73 ;A
a4 equ 68 ;A#
as4 equ 63 ;B
bb4 equ 63 ;B
;определение длительностей нот (четвертные)
c3c equ 60 ;c#
cs3c equ 63 ;d
db3c equ 63 ;d
d3c equ 67 ;d#
ds3c equ 72 ;e
eb3c equ 72 ;e
e3c equ 76 ;f
f3c equ 80 ;f#
fs3c equ 85 ;g
gb3c equ 85 ;g
g3c equ 90 ;g#
gs3c equ 96 ;a
ab3c equ 96 ;a
a3c equ 101 ;a#
as3c equ 108 ;b
bb3c equ 108 ;b
b3c equ 114 ;C
c4c equ 120 ;C#
cs4c equ 128 ;D
db4c equ 128 ;D
d4c equ 135 ;D#
ds4c equ 143 ;E
eb4c equ 143 ;E
e4c equ 151 ;F
f4c equ 162 ;F#
fs4c equ 171 ;G
gb4c equ 171 ;G
g4c equ 183 ;G#
gs4c equ 192 ;A
ab4c equ 192 ;A
a4c equ 204 ;A#
as4c equ 218 ;B
bb4c equ 218 ;B
d3q equ 34
e3q equ 38
f3q equ 40
g3q equ 45
a3q equ 51
end 32768
Поделитесь вашим мнением о статье