aboutsummaryrefslogtreecommitdiff
path: root/sdcc/beeper.z80
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2021-04-17 22:05:24 +0100
committerJuan J. Martinez <jjm@usebox.net>2021-04-17 22:05:24 +0100
commita5745813e442b66ae6eed30bba81d1b3dd5cf634 (patch)
treeb302db1780350dc44543b81d49bfc1b2d4dff6a8 /sdcc/beeper.z80
downloadbeeper-int-zx-a5745813e442b66ae6eed30bba81d1b3dd5cf634.tar.gz
beeper-int-zx-a5745813e442b66ae6eed30bba81d1b3dd5cf634.zip
Initial public release
Diffstat (limited to 'sdcc/beeper.z80')
-rw-r--r--sdcc/beeper.z80158
1 files changed, 158 insertions, 0 deletions
diff --git a/sdcc/beeper.z80 b/sdcc/beeper.z80
new file mode 100644
index 0000000..b5b82e7
--- /dev/null
+++ b/sdcc/beeper.z80
@@ -0,0 +1,158 @@
+; Beeper engine
+; Copyright (C) 2021 by Juan J. Martinez <jjm@usebox.net>
+;
+; Permission is hereby granted, free of charge, to any person obtaining a copy
+; of this software and associated documentation files (the "Software"), to deal
+; in the Software without restriction, including without limitation the rights
+; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+; copies of the Software, and to permit persons to whom the Software is
+; furnished to do so, subject to the following conditions:
+;
+; The above copyright notice and this permission notice shall be included in
+; all copies or substantial portions of the Software.
+;
+; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+; THE SOFTWARE.
+;
+.globl _beeper_init
+.globl _beeper_queue
+.globl _beeper_play
+
+_beeper_init::
+ di
+ ld (sfx_data), hl
+ xor a
+ ld (sfx_type), a
+ ei
+ ret
+
+_beeper_queue::
+ di
+ ld a, l
+ call queue_next
+ ei
+ ret
+
+queue_next:
+ ld (sfx_type), a
+ or a
+ ret z
+
+ dec a
+
+ ld hl, (sfx_data)
+ ld c, l
+ ld b, h
+
+ ld h, #0
+ ld l, a
+ ld d, h
+ ld e, l
+ add hl, hl
+ add hl, hl
+ add hl, de
+ add hl, bc
+
+ ld de, #sfx_type
+ ld bc, #5
+ ldir
+ ret
+
+_beeper_play::
+ ld a, (sfx_type)
+ or a
+ ret z
+
+ dec a
+ jr z, tone
+
+ dec a
+ ; shouldn't happen!
+ ret nz
+
+ ; noise
+ ld a, (sfx_freq)
+ ld d, a
+
+ ld b, #0
+
+noise_loop:
+ call rnd
+ and #0x10
+ ; FIXME: border ?
+ out (0xfe), a
+
+ ld c, d
+noise_freq_loop:
+ dec b
+ jr z, noise_done
+ dec c
+ jr nz, noise_freq_loop
+ jr noise_loop
+
+tone:
+ ld a, (sfx_freq)
+ ld d, a
+
+ xor a
+ ld b, a
+
+tone_loop:
+ ; FIXME: border ?
+ out (0xfe), a
+ xor #0x10
+
+ ld c, d
+freq_loop:
+ dec b
+ jr z, tone_done
+ dec c
+ jr nz, freq_loop
+ jr tone_loop
+
+tone_done:
+noise_done:
+ ld a, (sfx_next)
+ ld hl, #sfx_frames
+ dec (hl)
+ jr z, queue_next
+
+ ; freq change (slide)
+ ld a, (sfx_freq_chg)
+ add d
+ ld (sfx_freq), a
+
+ ret
+
+rnd:
+ ld hl, #0xf3a1
+ ld a, h
+ rra
+ ld a, l
+ rra
+ xor h
+ ld h, a
+ ld a, l
+ rra
+ ld a, h
+ rra
+ xor l
+ ld l, a
+ xor h
+ ld h, a
+ ld (rnd + 1), hl
+ ret
+
+sfx_type: .ds 1
+sfx_frames: .ds 1
+sfx_freq: .ds 1
+sfx_freq_chg: .ds 1
+sfx_next: .ds 1
+
+sfx_data: .ds 2
+