Auld Lang Syne — Dave change notes

Woot! #03

Auld Lang Syne — Dave change notes

uglisynthstart_ug:  
            di      
            call    screensetup

            ld      hl,auldtitle        ;setup the title
            call    printstring         ;and print it

            ld      a,16+5              ;cyan (set up border colours red/cyan)
            ld      (colour1smc+1),a
            ld      a,2                 ;red
            ld      (colour2smc+1),a

            ld      hl,auld0
            call    playsong

            ld      a,16+1              ;blue (set up border colours blue/yellow)
            ld      (colour1smc+1),a
            ld      a,6                 ;yellow
            ld      (colour2smc+1),a           

            ld      hl,auldtext1        ;setup the first bit of words - should alud
            call    printstring         ;and print them

            ld      hl,auld1            ;setup the song fragment
            call    playsong            ;and play it

            ld      hl,auldtext2        ;setup the next bit of words - and never 
            call    printstring         ;and print them

            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 is the code for white.
            call    8859          ; set border colour.

            call    wastetime  ;just a little pause

            ld      hl,auldtext9
            call    printstring

            call    wastetime  ;just a little pause
            call    wastetime  ;just a little pause
            call    wastetime  ;just a little pause

            ld      hl,auldtext10
            call    printstring

            ei
            ret      

playsong:   ;called with HL pointing at the musidata
            ld      (songpointer),hl ;prime the songpointer with the song fragment
testloop:
            ld      hl,(songpointer)
            ld      (smc_data+1),hl
            inc     hl
            inc     hl
            ld      (songpointer),hl
smc_data:
            ld      hl,(auld1)
            ld      a,l           ;check if L (low byte) is zero (end of song marker), if so, return
            or      a
            ret     z

;Check for a 'rest' (is the value of H=0)
            ld      a,h
            or      a
            jr      z,rest_routine

            call    playnote

            ;jr      rest_routine  ;THIS IS INSERTING GAPS EACH TIME, FOR TESTING PURPOSES

            jr      testloop         ; Loop to next element in song
;
rest_routine:
            ld      bc,20000         ;insterts an audible gap THIS NEEDS TO BE BASED UPON length of L, ****but isn't, yet***
insert_pause:
            nop
            dec     bc
            ld      a,b
            or      c
            jr      nz,insert_pause
            jr      testloop       ; Loop to next element in song

playnote:
;load data (hl)  l=length, h=pitch
tempo_smc:
            ld      a,4                             ;eg. 4 - wow many times through the loop (sort of tempo multipler)
            ld      (smc_length+1),a                ;setup the length of loop where it's reset
            ld      (noteroll),a ;noteroll          ;and initially

            ld      (notelength),hl

            ld      e,1                             ;make sure there is no errant "previous note" that matches the one playing

jumpbackpoint:                          ;come back here to setup d with the pitch of the note

            ld      hl,noteroll         ;noteroll is a X-to-0 counter that determines how many times
            dec     (hl)                ;it goes through the cycle (i.e. the lenghth in the l register)
            jr      nz,skipcounterdown  ;
smc_length:
            ld      (hl),0              ;reset noteroll to it's value (equates to tempo) (will have been setup previously)

            ld      hl,notelength       ;notelength is length (see also noteroll, though)
            dec     (hl)                ;decrease it until it's zero
            ret     z                   ;

skipcounterdown:

            ld      hl,notepitch        ;d is given the required pitch
            ld      d,(hl)

generateanote:   ;generate a note
                 ;pitch is held in register d
                 ;but first check is it a "new" note ?
            ld      a,d
            cp      e                   ;e holds previous note
            jr      z,sameoldnote       ;if it is the same, then we don't need to change counters etc
newnotebeingplayed:
            xor     a                   ;clear carry flag)
            ld      a,d
            ld      e,a                 ;store that note for comparisson next time
            ld      (smc_ug2+1),a
            rra                         ;a=d/2
            ld      c,a                 ;c is used to keep counter temporarily

sameoldnote:                            ;enter here if if is the same note as before
            ld      a,c                 ;restore counter

            inc     a                   ;inc counter
            ld      b,a                 ;load it into b, for a djnz loop
killsometime:
            nop                          ;4 tstates, one byte
            cp      (hl)                 ;7 tstates, one byte, no purpose - just killing some time - NB can add more time killing here, but notes will need retuning!

            djnz    killsometime
colour1smc:
            ld      a,17                 ;will determine border colour as well.  16+colour.  17=blue
            out     (254),a

            ld      a,d                  ;get the pitch
            sub     c                    ;take away the counter
            inc     a                    ;add 1 to stop it ever being zero
            ld      b,a                  ;put the result into b

killsometime2:      
            nop                          ;4 tstates,one byte
            cp      (hl)                 ;7 tstates, one byte, no purpose - just killing some time
            djnz    killsometime2
colour2smc:
            ld      a,6                  ;also determine border colour.  0+colour .  6=yellow
            out     (254),a

                                         ;now we'll change the pulse width by changing a/c
            ld      a,c

smc_ug1:                                 ;this is smc modified to change whether pulse width is increasing or decreasing
            add     a,255                ;either add or subtract 1  (subtract 1=adding 255)
            ld      c,a                  ;update c

            jp      z,changedirection
smc_ug2:            
            ld      a,0                  ;this is smc modified when a new note is played
            cp      c
            jp      z,changedirection
            jp      jumpbackpoint

changedirection:    
            ld      a,(smc_ug1+1)         ;uses twos complement to turn 1 into 255 and vice versa
            cpl                           ;
            inc     a                     ;
            ld      (smc_ug1+1),a         ;
            jp      jumpbackpoint

; these variables are set up used to count the note length, and wavelength
noteroll:   db      0
notelength: db      1
notepitch:  db      253 ; note length and pitch
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     ;endofsong marker

auld3:                  ;should auld aquaintance be forgot,

             db  d4c,d4
             db  181,c4
auld7:                  ;same as end of 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:                  ;as melody 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

;probably redundant stuff/fluff

screensetup:
            ld      a,2           ; upper screen
            call    5633          ; open channel from rom print routine
            ld      a,56          ; black ink (6) on white paper (0*8) + bright (64*0)
            ld      (23693),a     ; set our screen colours.
            call    3503          ; clear the screen.
            ld      a,7           ; 7 is the code for white.
            call    8859          ; set border colour.
;            ld      hl,memorystring     ;memory text
;            call    printstring
;            ld      bc,uglisynthstart_ug
;            call    11563               ; stack number in bc.
;            call    11747               ; display top of calc. stack.
;            ld      a,"-"
;            rst     16
;            ld      bc,firstfreebyte_ug
;            call    11563              ; stack number in bc.
;            call    11747              ; display top of calc. stack.
            ret

;memorystring:
;            db      22,21,0,"Memory : ",255

printstring: ;cheap and dirty string printing routine, hl points at string (terminated with a 255, rather than 0, to allow easier ctrl codes)
             ld   a,(hl)
             inc  a    ;is it 255
             ret  z    ;if so, exit loop
             dec  a
             rst  16   ;if not, print it
             inc  hl   ;and loop round
             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:                  ;a dirty loop to dramatically pause
            ld      bc,0
timekill1:  dec     bc
            cp      (hl)    ;this is just killing time
            ld      a,b
            or      c
            ret     z
            jr      timekill1

firstfreebyte_ug equ $
;Define notes'
c3              equ      253    ;c# [concert tunings, 440hz]
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

;define note lengths (of crotchets)
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

Share your thoughts about the article