I've been learning Z80 Assembly language, and I'm a bit stumped with this. The values in the DEFB represent musical pitches. The program creates a sequential loop, using the A register, starting at 0, and it should read the nth element of the DEFB, transfer the value into the HL register, and then BEEP the note. I cannot work out how to remove my hard-coding and get this to work:
ORG 30000
_MAIN
LD A, 0 ;Set A to zero
LOOP_POINT:
LD B, A ;Load the current value of A into B to loop on
CP 31 ;Check if the B value is 31
JP Z, FINISHED ;If yes, 32 notes have been played, so jump to FINISHED
PUSH AF ;Put current A value on the stack, because the "CALL 949" is going to overwrite it
;LD HL, (SOUND_BUFFER + A) - THIS DOES NOT WORK, I AM FORCED TO HARD CODE TO 855 FOR THIS EXAMPLE (BELOW)
LD HL, 855 ;Load the pitch into HL
LD DE, 24 ;Load the duration into DE
CALL 949 ;Will play the pitch in HL for the duration in DE
POP AF ;Restore the A value back from the stack
INC A ;Add 1
CALL LOOP_POINT
FINISHED:
RET
SOUND_BUFFER ;32 elements (each is a 1/4 note, so, 4*8 bars = 32 in total)
DEFB "855,0,0,0,855,855,855,759,759,673,673,673,673,673,673,673,0,0,0,0,855,855,855,759,759,673,673,759,759,855,0,855"
Can anyone help me with the syntax or pointme in the right direction please?
You either have to calculate the pointer from index in A or just keep the pointer and update it as you go through the array. Below is my variant (based on your original code) - not checked, no guarantees. Note also that I've changed your DEFB to DEFW - I'm not familiar with your version of assembler, so this might be wrong, but since the pitch is represented by 16-bit values I would expect DEFW (or DW) to be used.
EDIT: And, with the way things are coded, you need to compare A with 32, not 31. Otherwise the last note is not played.
Hope this helps.