Espamática
ZX SpectrumRetroZ80 Assembly

ZX Spectrum Assembly, Tic-Tac-Toe – 0x03 Sound

In this chapter of ZX Spectrum Assembly, we will implement different sounds and use them for timing by pausing between events.

Translation by Felipe Monge Corbalán

Table of contents

Sound

We will create the file sound.asm and add the include to main.asm.

In sound.asm we will add the definition of the different sounds and melodies.

ASM
; -------------------------------------------------------------------
; Sounds.
;
; Sounds end in $00, the byte indicating the end.
; -------------------------------------------------------------------
; Countdown
SoundCountDown:
db $03, $8c, $3a, $00

; Error
SoundError:
db $0d, $c6, $1e, $16, $13, $13, $00

; Loss of movement
SoundLostMovement:	
db $0d, $07, $10, $0b, $96, $12, $0a, $4d, $14
db $0b, $96, $12, $1a, $2c, $08, $00

; Next player
SoundNextPlayer:
db $01, $9d, $7b, $00

; Spectrum Movement
SoundSpectrum:
db $06, $6e, $20, $06, $6e, $20, $05, $b7, $24
db $06, $6e, $20, $05, $13, $29, $05, $b7, $24
db $06, $6e, $20, $00

; Tables
SoundTie:
db $0d, $07, $10, $0b, $96, $12, $06, $d4, $1e
db $0b, $96, $12, $07, $a6, $1b, $0b, $96, $12
db $08, $a5, $18, $0b, $96, $12, $09, $b4, $15
db $0b, $96, $12, $0a, $4d, $14, $0b, $96, $12
db $0d, $07, $10, $00

; Point
SoundWinGame:
db $06, $6e, $20, $05, $13, $29, $04, $40, $30
db $06, $6e, $20, $05, $13, $29, $04, $40, $30
db $06, $6e, $20, $05, $13, $29, $04, $c7, $2b
db $05, $13, $29, $05, $b7, $24, $05, $13, $29
db $06, $6e, $20, $05, $13, $29, $04, $40, $30
db $06, $6e, $20, $05, $13, $29, $04, $40, $30
db $06, $6e, $20, $05, $13, $29, $04, $c7, $2b
db $05, $13, $29, $05, $b7, $24, $06, $6e, $20
db $00

All sounds have a zero byte as their last byte, which we will use in the routine that plays them to know when they are finished.

In these definitions, each note is made up of three bytes instead of four, the first two being the note and the third being the low byte of the duration, all of which are sixteenths and/or half notes.

We implement the routine that plays the tones.

ASM
; -------------------------------------------------------------------
; Plays a melody or sound.
;
; Input: BC = Start address of the melody.
;
; To save is done byte by byte, with the duration always being fuzzy
; or half-fuse; only one byte is needed for the duration.
; This routine is adapted for this operation.
; -------------------------------------------------------------------
PlayMusic:
push af
push bc
push de
push hl
push ix                    ; Preserves records

playMusic_loop:
ld   a, (bc)               ; A = high byte note
ld   h, a                  ; H = A
or   a                     ; A = 0?
jr   z, playMusic_end      ; A = 0, end

inc  bc                    ; BC = next value
ld   a, (bc)               ; A = byte under note
ld   l, a                  ; L = A

inc  bc                    ; BC = next value
ld   a, (bc)               ; A = duration note
ld   e, a                  ; E = A
ld   d, $00                ; D = 0 (fuse or half-fuse)
inc  bc                    ; BC = next value

push bc                    ; Preserves BC
call BEEPER                ; Play note
pop  bc                    ; Recover BC

jr   playMusic_loop        ; Loop until it reaches 0 end melody

playMusic_end:
pop  ix
pop  hl
pop  de
pop  bc
pop  af                    ; Retrieves records
ret

PlayMusic receives the address of the sound to be played in BC, loads the note in HL, the duration in DE, plays it and loops until it reaches the zero byte which marks the end of the sound. D is always zero, only one byte is used for the duration.

In main.asm we will add the necessary calls to play the sounds.

We locate the Loop tag and delete from LD B, $19 to DJNZ loop_wait as we will be timing with the sound. Below this, after CALL PrintPoints, we add the next player sound:

ASM
ld   bc, SoundNextPlayer
call PlayMusic

Locate the loop_print tag and just above it the JR Loop line. Above this line we add the error sound:

ASM
ld   bc, SoundError
call PlayMusic

Locate the loop_win tag and just below it the INC (HL) line. Below this line we add the dot winner sound:

ASM
ld   bc, SoundWinGame
call PlayMusic

Locate the loop_reset tag and just above it add the table sound:

ASM
ld   bc, SoundTie
call PlayMusic

We compile, load into the emulator and listen to every single sound.

The main.asm file has grown considerably since we started, so it’s time to see what it looks like after commenting.

ASM
org  $5e88                 ; Loading address

Main:
ld   hl, Sprite_P1         ; HL = address Sprite_P1
ld   (UDG), hl             ; UDG = address Sprite_p1
ld   a, $02                ; A = 2
call OPENCHAN              ; Open channel 2

xor  a                     ; A = 0, Z = 0, C = 0
call BORDER                ; Change border
call CLA                   ; Changes display attributes
call CLS                   ; Clear screen

Init:
call PrintBoard            ; Paint board

ld   hl, Name_p1           ; HL = name player 1
ld   de, player1_name      ; DE = player1_name
ld   bc, LENNAME           ; BC = length name
ldir                       ; Pass data
ld   hl, Name_p2           ; HL = name player 2
ld   de, player2_name      ; DE = player 2 name
ld   bc, LENNAME           ; BC = length name
ldir                       ; Pass data
call PrintInfo             ; Paint info

ld   bc, LENDATA           ; BC = length of starting data
call ResetValues           ; Clear data

Loop:
ld   hl, TitleTurn         ; HL = shift address
ld   de, TitleTurn_name    ; DE = address name in turn name in turn
call DoMsg                 ; Compose and paint shift
call PrintPoints           ; PaintPoints
ld   bc, SoundNextPlayer   ; BC = sound direction
call PlayMusic             ; Play sound
loop_key:
call WaitKeyBoard          ; Wait for key press
ld   a, c                  ; A = C
cp   KEY0                  ; Key pressed?
jr   z, loop_key           ; No, loop
call ToMove                ; Check movement
jr   z, loop_print         ; Correct, skip
ld   hl, TitleError        ; HL = address error
call PrintMsg              ; Paint Error
ld   bc, SoundError        ; BC = sound address
call PlayMusic             ; Play sound
jr   Loop                  ; Main loop
loop_print:
call PrintOXO              ; Paint token
loop_checkWinner:
call CheckWinner           ; Any winners?
jr   nz, loop_tie          ; No, check tables
call PrintWinnerLine       ; Paints winning line
ld   hl, TitlePointFor     ; HL = winning address
ld   de, TitlePointName    ; HL = address winning name
call DoMsg                 ; Compose and paint winner
ld   hl, Points_p1         ; HL = address points player 1
ld   a, (PlayerMoves)      ; A = player that moved
or   a                     ; Player 1?
jr   z, loop_win           ; Yes, skip
inc  hl                    ; HL = address points player 2
loop_win:
inc  (hl)                  ; Increases score
ld   bc, SoundWinGame      ; BC = sound address
call PlayMusic             ; Play sound
jr   loop_reset            ; Jump
loop_tie:
ld   hl, MoveCounter       ; HL = move counter address
inc  (hl)                  ; Increments counter
ld   a, $09                ; A = 9
cp   (hl)                  ; Counter = 9?
jr   nz, loop_cont         ; No, skip
ld   hl, Points_tie        ; HL = address points tables
inc  (hl)                  ; Increases score
ld   hl, TitleTie          ; HL = address tables
call PrintMsg              ; Paint tables
ld   bc, SoundTie          ; BC = sound direction
call PlayMusic             ; Play sound
loop_reset:
ld   bc, LENDATA-$04       ; BC = data length clean data
call ResetValues           ; Clear data
call PrintBoard            ; Paint board
loop_cont:
ld   a, (PlayerMoves)      ; A = player who moved
xor  $01                   ; A = next player
ld   (PlayerMoves), a      ; Refresh in memory
jr   Loop                  ; Main loop

include "game.asm"
include "rom.asm"
include "screen.asm"
include "sprite.asm"
include "sound.asm"
include "var.asm"

end  Main

ZX Spectrum Assembly, Tic-Tac-Toe

We have a large part of the game developed and working. We can play our first games with friends and/or family and we have sound.

In the next chapter of ZX Spectrum Assembly, we will implement the different options of the game and the end of the game.

Download the source code from here.

ZX Spectrum Assembly, Tic-Tac-Toe by Juan Antonio Rubio García.
Translation by Felipe Monge Corbalán.
This work is licensed to Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0).
Any comments are always welcome.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies

Descubre más desde Espamática

Suscríbete ahora para seguir leyendo y obtener acceso al archivo completo.

Seguir leyendo