Short beeper routines in assembly

The place for codemasters or beginners to talk about programming any language for the Spectrum.
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Short beeper routines in assembly

Post by R-Tape »

I always end up using the same spot effects, usually nabbed from the DKTronics SoundFX tape. I know we've got BeepFX for the more elaborate ones, but I thought this would be a good place to share shortish beeper routines people can use.

Here's a simple zap.

Code: Select all

	;
zap:
	ld d,16		;speaker = bit 4
	ld e,0		;distance between speaker move counter
	ld b,255	;overall length counter
blp0:	ld a,d
	and 248		;keep border colour the same
	out (254),a	;move the speaker in or out depending on bit 4
	cpl		;toggle, so we alternative between speaker in and out to make sound
	ld d,a		;store it
	ld c,e		;now a pause
blp1:	dec c
	jr nz,blp1
	dec e		;change to inc e to reverse the sound, or remove to make it a note
	djnz blp0	;repeat B=255 times
	ret
	;
	
User avatar
utz
Microbot
Posts: 113
Joined: Wed Nov 15, 2017 9:04 am
Contact:

Re: Short beeper routines in assembly

Post by utz »

Wrote a complete beeper music player/sequencer in 64 byte earlier this year: url=https://github.com/utz82/ZX-Spectrum-1- ... /nanobeep2
In it's most basic setup, it has just two square wave channels, and 8-bit frequency resolution (approx. 2.5 octaves note range). The code is modular, so you can activate extra features like increased note range and PWM sweeps, at the cost of increasing the player size.

The player is open source and free for use by anyone, but there's no editor for the music available yet. There's a short demo tune included in the download package, if anybody is curious about how it sounds.
Ralf
Rick Dangerous
Posts: 2279
Joined: Mon Nov 13, 2017 11:59 am
Location: Poland

Re: Short beeper routines in assembly

Post by Ralf »

Utz, if I may ask I recall there was some forum about making music and effects on zx beeper - https://web.archive.org/web/20150423235 ... i-demo.pl/

Was it your forum? Do you know anything why it disappeared?
User avatar
utz
Microbot
Posts: 113
Joined: Wed Nov 15, 2017 9:04 am
Contact:

Re: Short beeper routines in assembly

Post by utz »

Some drama happened and the former admin shut down the place. :roll:
We've got a new place at http://www.randomflux.info/1bit/ nowadays.
User avatar
Morkin
Bugaboo
Posts: 3251
Joined: Mon Nov 13, 2017 8:50 am
Location: Bristol, UK

Re: Short beeper routines in assembly

Post by Morkin »

utz wrote: Wed Nov 15, 2017 9:19 pm Some drama happened and the former admin shut down the place. :roll:
We've got a new place at http://www.randomflux.info/1bit/ nowadays.
Ah cool, I wondered what happened to that site. I was just starting to learn the basics from scratch (the beeper, frequencies etc.) and then the site seemed to disappear - will have to get back to it..!

Here's a sound effect almost identical to the 'pick up object' sound I used in Catacombs of Balachor. It uses the ROM beeper, which I used at the time because I had no idea how to use OUT properly to make sound effects..!

Code: Select all

sound_setup:
	ld de, 5
	ld b,3
	ld hl, 938 	; pitch
sound_loop:
	dec h
	push bc
	push de
	push hl
	call 949 	; call ROM beeper routine
	pop hl
	pop de
	pop bc
	djnz sound_loop
	ret
I liked the way you can just keep mucking about with the registers (DE, HL, BC), and the INCs and DECs to get very different effects.
My Speccy site: thirdharmoniser.com
User avatar
utz
Microbot
Posts: 113
Joined: Wed Nov 15, 2017 9:04 am
Contact:

Re: Short beeper routines in assembly

Post by utz »

Morkin wrote: Wed Nov 15, 2017 10:40 pm I liked the way you can just keep mucking about with the registers (DE, HL, BC), and the INCs and DECs to get very different effects.
Yeah, that's actually one of the things that I really like about the beeper. You can just throw almost random code at it and it will often do something interesting.

Anyway, here's a simple laser effect in 13 bytes. By initializing D with different values, you can control the length. 0x28 is approximately one full zap.

Code: Select all

	di
	ld d,#28		;length/iterations
loop
	add hl,de
	dec de
	ld a,h
	out (#fe),a
	ld a,e
	or d
	jr nz,loop
	
	ei
	ret

Another nice thing to have is (pseudo-)white noise in all forms. My preferred method nowadays, provided that I have the cycles and registers available, is this poor man's XORshift PRNG:

Code: Select all

	di
;HL must be !0 aka set HL to 0 for silence
loop
	add hl,hl
	sbc a,a
	xor l
	ld l,a
	
	cp #10       ;cp n -  n = volume
	sbc a,a
	
	out (#fe),a
	jr loop
In this form, it will produce a pretty good rendition of "white noise" on the beeper. If you want to control the "pitch" of the noise, you can wrap the above in a prescaler, like so:

Code: Select all

	ld d,%01010101    ;prescaler mask
loop
	rlc d
	jr nc,skip
	add hl,hl
	...
skip	
	cp #10       ;cp n -  n = volume
	sbc a,a
	
	out (#fe),a
	jr loop
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: Short beeper routines in assembly

Post by R-Tape »

Has anyone got, or is anyone willing to do a beep routine that sounds vaguely like a paper page turning? No samples, just few hundred byte routine max.

Also preferably a routine using OUT rather than CALL 949.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: Short beeper routines in assembly

Post by Ast A. Moore »

A page turning sound? Are you insane? Do you want us all get killed?
Image
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
HexTank
Drutt
Posts: 28
Joined: Sun Nov 12, 2017 9:11 pm

Re: Short beeper routines in assembly

Post by HexTank »

Well, it would inolve noise, so try a few RNGs with some adsr for amplitude.
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: Short beeper routines in assembly

Post by R-Tape »

Too teary?

Code: Select all

org 32768
	ld hl,0
	ld c,255
lp1:	inc hl
	ld a,(hl)
	and 248
	or 7
	out (254),a
	ld b,c
lp0:	djnz lp0
	dec c
	jr nz,lp1
	ret
	;
	
Yep too teary.
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: Short beeper routines in assembly

Post by R-Tape »

I don't suppose anyone can improve on my naff page turning sound?

It's for use on the tape magazine, would be credited natch.
Hikaru
Microbot
Posts: 100
Joined: Mon Nov 13, 2017 1:42 pm
Location: Russia
Contact:

Re: Short beeper routines in assembly

Post by Hikaru »

Well, I gave it a go previously, but decided not to post it in the end as I didn't really like the result. Seems like it was auto-saved as a draft, sooo here

Code: Select all

SFX
	ld hl,0
	ld de,#0710
	ld bc,2
	ld lx,#18
	call .loop
	ld c,24
	ld lx,#06
.loop
	ld a,(hl)
	inc hl
	cp c
	sbc a
	and e
	or d
	out (#FE),a
	djnz .loop
	dec lx
	jr nz,.loop
	ret
Inactive account
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: Short beeper routines in assembly

Post by R-Tape »

Much better than mine, thanks.

Are you still okay to be credited as 'owner' of the noise if I go with this? I'm using IX as a string pointer, so while it would be easy enough to PUSH it I'm trying to minimise having to do so.

Also, do you think changing ld d,6 to 24 makes it better or too close to masticating crisps?

Why did you use ixl? Timing reasons, or just because you used every other register?

Code: Select all

org 32768
SFX
	ld hl,0
	ld bc,2
	ld d,24
	call .loop
	ld c,24
	ld d,64
.loop
	ld a,(hl)
	inc hl
	cp c
	sbc a,a
	and 24
	or 7
	out (254),a
	djnz .loop
	dec d
	jr nz,.loop
	ret
Hikaru
Microbot
Posts: 100
Joined: Mon Nov 13, 2017 1:42 pm
Location: Russia
Contact:

Re: Short beeper routines in assembly

Post by Hikaru »

I don't think something like this needs a credit at all, so any option is fine of course. For the record, at the core of it is a fairly old trick used in the Tritone engine (and IIRC one more from the 80's), i.e. CP N: SBC A: AND #10. In other words, any values less than N give #10, while values equal to or more than N give 0. Tritone uses it as a kind of hybrid 'timbre/volume control' for square waves, so I thought I might be able to get something similar with the noise, but apparently the result is far less pronounced.

LX, no point really, it's more due to my subconscious habit to speed up innermost loops (use up all registers first, ask questions later). Well, this time it affects the noise pitch. Try both versions, maybe tweak the constants a bit to see which is better. There's no right or wrong about it other than if it sounds good to you.
Inactive account
User avatar
Joefish
Rick Dangerous
Posts: 2041
Joined: Tue Nov 14, 2017 10:26 am

Re: Short beeper routines in assembly

Post by Joefish »

If it's any help, the way I generate the combined noise and tone that gives the saws in Buzzsaw+ their 'whine' was to create a high/low square wave, then have a random number generator that whenever it produces a number over a certain threshold, I temporarily invert a bit of the square wave for a small number of cycles.

Now to control the rough 'pitch' of the whine, that's the original square wave. To make it more or less noisy, I move the threshold above which the random number inverts the output, or have it so it can only insert '1s' into the square wave, rather than invert it (so it only affects the low half of the wave). And to adjust the pitch of the noise, I make the random inversion stick around for more or less cycles of my sound function.

But these are prepared in advance and replayed from a buffer, which repeats once it's set up. To make the 'noise' sound more random, the buffer is longer than it needs to be and each time it replays the start position is randomised.
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: Short beeper routines in assembly

Post by R-Tape »

Joefish wrote: Tue Dec 05, 2017 3:13 pm If it's any help
Aye it is, in the long term. I don't have enough time to refine a sound routine right now but it's something I started to make progress with then forgot during a 6 month coding lacuna. I tend to avoid doing music/sound as I don't feel I have an affinity for audio anyway, but it's probably similar to when people say 'I can't draw' and I never believe them.

There are some amazing sound support packages out there but spot effects and music are IMO the most neglected area in ZX Software these days (and I'm at least as guilty as anyone).
User avatar
g0blinish
Manic Miner
Posts: 281
Joined: Sun Jun 17, 2018 2:54 pm

Re: Short beeper routines in assembly

Post by g0blinish »

Some disassembly from BLAM:

Code: Select all

sub_9E21:				; CODE XREF: sub_8EA7:loc_8F13p
		ld	hl, 1F40h
		ld	c, 0D0h	; 'Р'

loc_9E26:				; CODE XREF: sub_9E21+Fj
		ld	a, (hl)
		and	18h
		out	(0FEh),	a
		ld	b, c

loc_9E2C:				; CODE XREF: sub_9E21:loc_9E2Cj
		djnz	$
		inc	hl
		inc	c
		jr	nz, loc_9E26
		ret
; End of function sub_9E21


; =============== S U B	R O U T	I N E =======================================


sub_9E33:				; CODE XREF: sub_C746+72p
		ld	b, 64h ; 'd'

loc_9E35:				; CODE XREF: sub_9E33+11j
		xor	a
		out	(0FEh),	a
		push	bc

loc_9E39:				; CODE XREF: sub_9E33:loc_9E39j
		djnz	$
		pop	bc
		ld	a, 0F8h	; 'ш'
		out	(0FEh),	a
		push	bc

loc_9E41:				; CODE XREF: sub_9E33:loc_9E41j
		djnz	$
		pop	bc
		djnz	loc_9E35
		ret
; End of function sub_9E33


; =============== S U B	R O U T	I N E =======================================


sub_9E47:				; CODE XREF: sub_CA18+3p
		ld	b, 64h ; 'd'

loc_9E49:				; CODE XREF: sub_9E47+18j
		xor	a
		out	(0FEh),	a
		push	bc
		ld	a, r
		ld	b, a

loc_9E50:				; CODE XREF: sub_9E47+Bj
		nop
		nop
		djnz	loc_9E50
		pop	bc
		ld	a, 0F8h	; 'ш'
		out	(0FEh),	a
		push	bc

loc_9E5A:				; CODE XREF: sub_9E47+15j
		nop
		nop
		djnz	loc_9E5A
		pop	bc
		djnz	loc_9E49
		ret

User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: Short beeper routines in assembly

Post by R-Tape »

Here's a simulation of the Chuckie Egg 'farty collect' sound. After looking at the code and the weird interrupt, I thought I'd never unravel it, but as long as you know which bit is making the noise, you can use the debugger to count the # of tstates in between and approximate. Close enough?

Code: Select all

org 32768
cbmain:
	ld b,60	;it last slightly more than a second, and each loop on average is a bit more than a full frame
cbbeep:	push bc
	call chuckiebeep
	call chuckiedelay
	ld hl,ccounter
	inc (hl)
	pop bc
	djnz cbbeep
	ret
	;
chuckiedelay:
	ld a,(ccounter)
	and 7
	add a,a
	ld c,a
	ld b,0
	ld hl,cdelays
	add hl,bc
	ld c,(hl)
	inc hl
	ld b,(hl)
cdlp:	dec bc
	ld a,b
	or c
	jr nz,cdlp
	ret
	;
chuckiebeep:	
	ld a,(ccounter)
	and 7
	ld c,a
	ld b,0
	ld hl,chuckbeeps
	add hl,bc
	ld h,(hl)	;H is 37,33,29,25,21,17,13,9 cycled
	ld l,2		;L is always 2
cblp2:	ld a,16		;arrive H tone, L always 2, this is exactly the same as the Chuckie Egg sound engine
	out (254),a
	ld b,h
cblp0:	djnz cblp0
	xor a
	out (254),a
	ld b,h
cblp1:	djnz cblp1
	dec l
	jr nz,cblp2
	ret
	;
ccounter:		db	0
chuckbeeps:		db	37,33,29,25,21,17,13,9			;the chuckie egg code does this as SUBs
cdelays:		dw	1580,1988,1035,1433,476,860,2260,243	;approximate BC loopcounter for no of tstates that pass between beeps
	;
User avatar
Morkin
Bugaboo
Posts: 3251
Joined: Mon Nov 13, 2017 8:50 am
Location: Bristol, UK

Re: Short beeper routines in assembly

Post by Morkin »

Yep, just compared it to the original, to my knackered ears it's a smidgen slower and lower pitched than the game, but otherwise spot on.
My Speccy site: thirdharmoniser.com
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: Short beeper routines in assembly

Post by R-Tape »

Morkin wrote: Wed Oct 02, 2019 11:13 pm Yep, just compared it to the original, to my knackered ears it's a smidgen slower and lower pitched than the game, but otherwise spot on.
Cheers. I can't spot a difference, but I don't have a good ear for these things.

Can anyone accurately compare using technology? And understand how the delays should change to match?
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: Short beeper routines in assembly

Post by R-Tape »

I just ripped this tune from a game. I won't spoil the surprise by saying which.

The code isn't exactly the same, just a similar player and the music data was easily halved in size. It could probably be reduced ever further as there aren't that many combinations.

Code: Select all

org 32768
musicbeep:
	halt
	halt
	halt
	halt
	ld hl,(musiccount)
	ld h,0
	add hl,hl
	ld de,musictab
	add hl,de
	ld e,(hl)
	inc hl
	ld c,(hl)
	ld b,0
	ld d,b
	ld a,e
	cp 255
	call z,resettune
	or a
	call nz,musiclp
	ld hl,musiccount
	inc (hl)
	jr musicbeep
	;
resettune:
	xor a
	ld (musiccount),a
	ld de,(musictab)
	ld c,d
	ld b,0
	ld d,b
	ld a,e
	ret
	;
musiccount:	db	0
	;
musiclp:	ld a,0
	out (254),a
	call delay
	ld a,16
	out (254),a
	call delay
	dec de
	ld a,d
	or e
	jr nz,musiclp
	ret
	;
delay:	push bc
delp:	dec bc
	ld a,b
	or c
	jr nz,delp
	pop bc
	ret
	;
musictab:
DEFB 38,43
DEFB 34,48
DEFB 38,43
DEFB 0,0
DEFB 22,73
DEFB 0,0
DEFB 22,73
DEFB 0,0
DEFB 34,48
DEFB 30,53
DEFB 28,58
DEFB 46,35
DEFB 46,35
DEFB 43,38
DEFB 46,35
DEFB 0,0
DEFB 53,30
DEFB 46,35
DEFB 53,30
DEFB 0,0
DEFB 25,65
DEFB 0,0
DEFB 25,65
DEFB 0,0
DEFB 25,65
DEFB 22,73
DEFB 21,78
DEFB 34,48
DEFB 34,48
DEFB 32,50
DEFB 34,48
DEFB 0,0
DEFB 38,43
DEFB 43,38
DEFB 46,35
DEFB 43,38
DEFB 38,43
DEFB 34,48
DEFB 38,43
DEFB 34,48
DEFB 30,53
DEFB 28,58
DEFB 30,53
DEFB 28,58
DEFB 25,65
DEFB 22,73
DEFB 22,73
DEFB 20,80
DEFB 18,90
DEFB 16,103
DEFB 0,0
DEFB 18,90
DEFB 22,73
DEFB 21,78
DEFB 25,65
DEFB 22,73
DEFB 28,58
DEFB 25,65
DEFB 30,53
DEFB 28,58
DEFB 0,0
DEFB 22,73
DEFB 0,0
DEFB 22,73
DEFB 0,0
DEFB 0,0
DEFB 34,48
DEFB 30,53
DEFB 28,58
DEFB 46,35
DEFB 46,35
DEFB 34,48
DEFB 28,58
DEFB 46,35
DEFB 46,35
DEFB 34,48
DEFB 38,43
DEFB 0,0
DEFB 29,55
DEFB 0,0
DEFB 29,55
DEFB 0,0
DEFB 38,43
DEFB 34,48
DEFB 29,55
DEFB 53,30
DEFB 53,30
DEFB 38,43
DEFB 29,55
DEFB 53,30
DEFB 53,30
DEFB 38,43
DEFB 43,38
DEFB 0,0
DEFB 34,48
DEFB 0,0
DEFB 34,48
DEFB 0,0
DEFB 38,43
DEFB 43,38
DEFB 46,35
DEFB 43,38
DEFB 38,43
DEFB 34,48
DEFB 38,43
DEFB 34,48
DEFB 30,53
DEFB 28,58
DEFB 30,53
DEFB 28,58
DEFB 25,65
DEFB 22,73
DEFB 22,73
DEFB 20,80
DEFB 18,90
DEFB 16,103
DEFB 0,0
DEFB 18,90
DEFB 22,73
DEFB 21,78
DEFB 25,65
DEFB 22,73
DEFB 28,58
DEFB 25,65
DEFB 30,53
DEFB 28,58
DEFB 0,0
DEFB 22,73
DEFB 0,0
DEFB 22,73
DEFB 0,0
DEFB 0,0
DEFB 255,255
endmusic:

User avatar
Spud
Manic Miner
Posts: 372
Joined: Sun Nov 12, 2017 8:50 pm
Contact:

Re: Short beeper routines in assembly

Post by Spud »

You clever CLOGS
User avatar
Morkin
Bugaboo
Posts: 3251
Joined: Mon Nov 13, 2017 8:50 am
Location: Bristol, UK

Re: Short beeper routines in assembly

Post by Morkin »

The
Spoiler
Booty
music has irritated me for over 30 years as there are some annoying extra pauses between the notes that I don't think should be there. Whenever I've played the game it's made me more twitchy than piratey.

I reckon the gaps should be something a bit more like:

Code: Select all

DEFB 38,43
DEFB 34,48
DEFB 38,43
DEFB 0,0
DEFB 22,73
DEFB 0,0
DEFB 22,73
DEFB 0,0
DEFB 34,48
DEFB 30,53
DEFB 28,58
DEFB 46,35
DEFB 46,35
DEFB 43,38
DEFB 46,35
DEFB 0,0
DEFB 53,30
DEFB 46,35
DEFB 53,30
DEFB 0,0
DEFB 25,65
DEFB 0,0
DEFB 25,65
DEFB 0,0
DEFB 25,65
DEFB 22,73
DEFB 21,78
DEFB 34,48
DEFB 34,48
DEFB 32,50
DEFB 34,48
DEFB 0,0
DEFB 38,43
DEFB 43,38
DEFB 46,35
DEFB 43,38
DEFB 38,43
DEFB 34,48
DEFB 38,43
DEFB 34,48
DEFB 30,53
DEFB 28,58
DEFB 30,53
DEFB 28,58
DEFB 25,65
DEFB 22,73
DEFB 22,73
DEFB 20,80
DEFB 18,90
DEFB 16,103
DEFB 18,90
DEFB 22,73
DEFB 21,78
DEFB 25,65
DEFB 22,73
DEFB 28,58
DEFB 25,65
DEFB 30,53
DEFB 28,58
DEFB 0,0
DEFB 22,73
DEFB 0,0
DEFB 22,73
DEFB 0,0
DEFB 34,48
DEFB 30,53
DEFB 28,58
DEFB 46,35
DEFB 46,35
DEFB 34,48
DEFB 28,58
DEFB 46,35
DEFB 46,35
DEFB 34,48
DEFB 38,43
DEFB 0,0
DEFB 29,55
DEFB 0,0
DEFB 29,55
DEFB 0,0
DEFB 38,43
DEFB 34,48
DEFB 29,55
DEFB 53,30
DEFB 53,30
DEFB 38,43
DEFB 29,55
DEFB 53,30
DEFB 53,30
DEFB 38,43
DEFB 43,38
DEFB 0,0
DEFB 34,48
DEFB 0,0
DEFB 34,48
DEFB 0,0
DEFB 38,43
DEFB 43,38
DEFB 46,35
DEFB 43,38
DEFB 38,43
DEFB 34,48
DEFB 38,43
DEFB 34,48
DEFB 30,53
DEFB 28,58
DEFB 30,53
DEFB 28,58
DEFB 25,65
DEFB 22,73
DEFB 22,73
DEFB 20,80
DEFB 18,90
DEFB 16,103
DEFB 18,90
DEFB 22,73
DEFB 21,78
DEFB 25,65
DEFB 22,73
DEFB 28,58
DEFB 25,65
DEFB 30,53
DEFB 28,58
DEFB 0,0
DEFB 22,73
DEFB 0,0
DEFB 22,73
DEFB 0,0
DEFB 255,255
My Speccy site: thirdharmoniser.com
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: Short beeper routines in assembly

Post by R-Tape »

Morkin wrote: Fri Oct 11, 2019 12:52 pm I reckon the gaps should be something a bit more like:
I think it sounds better. I can't really pick out why and which bits though. But no matter how good it gets—such a short loop of that track will drive anyone crackers.
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: Short beeper routines in assembly

Post by R-Tape »

I don't suppose anyone has a disasm of any of the digitised speech, or the beeper music in Ghostbusters?

My attempts so far sound like heavy furniture being dragged...
Post Reply