Auld Lang Syne: правки кода от Дэйва

Woot! #03

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

Поделитесь вашим мнением о статье