Login

Subversion Repositories NedoOS

Rev

Rev 1107 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

; 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


        ; TODO need test on real computer. On XPECCY emulator beeper is absent !

        module SOUND_PLAYER

        module SET_SOUND
mute:
        ld hl,SOUND_PLAYER.DATA.mute
        jr SOUND_PLAYER.init
coin:
        ld hl,SOUND_PLAYER.DATA.coin
        jr SOUND_PLAYER.init
explosion:
        ld hl,SOUND_PLAYER.DATA.explosion
        jr SOUND_PLAYER.init
impact:
        ld hl,SOUND_PLAYER.DATA.impact
        jr SOUND_PLAYER.init
eat:
        ld hl,SOUND_PLAYER.DATA.eat
        jr SOUND_PLAYER.init
key:
        ld hl,SOUND_PLAYER.DATA.key
        jr SOUND_PLAYER.init
ice:
        ld hl,SOUND_PLAYER.DATA.ice
        jr SOUND_PLAYER.init
done:
        ld hl,SOUND_PLAYER.DATA.done
        jr SOUND_PLAYER.init
dead:
        ld hl,SOUND_PLAYER.DATA.dead
        jr SOUND_PLAYER.init
        endmodule

init:
        di
        ld (sfx_data), hl
        ld a,1
        ld (sfx_type), a
        ld de,sfx_type
        ld bc,5
        ldir
        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

play:
        ld a, (sfx_type)
        or a
        ret z

        dec a
        jr z, tone

        dec a
        ; shouldn't happen!
        ret nz

       if EGA
        ld a,(curgfxmode)
        or 8
        ld e,a;0+0x80+8 ;EGA+keep+noturbo
        OS_SETGFX ;e=0:EGA, e=2:MC, e=3:6912, e=6:text ;+SET FOCUS ;e=-1: disable gfx (out: e=old gfxmode)
       endif
        ; 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:
       if EGA
        ld a,(curgfxmode)
        or 8
        ld e,a;0+0x80+8 ;EGA+keep+noturbo
        OS_SETGFX ;e=0:EGA, e=2:MC, e=3:6912, e=6:text ;+SET FOCUS ;e=-1: disable gfx (out: e=old gfxmode)
       endif
        ld a, (sfx_freq)
        ld d, a

        xor a
        ld b, a

tone_loop:
        ; FIXME: border ?
        and 0x10
        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
       if EGA
        ld a,(curgfxmode)
        ld e,a;0+0x80 ;EGA+keep
        OS_SETGFX ;e=0:EGA, e=2:MC, e=3:6912, e=6:text ;+SET FOCUS ;e=-1: disable gfx (out: e=old gfxmode)
       endif

        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:       db 0
sfx_frames:     db 0
sfx_freq:       db 0
sfx_freq_chg:   db 0
sfx_next:       db 0

sfx_data:       block 2

        module DATA
mute:  
        db 0,0,0,0,0
coin:
        db 1,6,32,-8,2, 1,6,48,-12,0
explosion:
        db 2,32,1,-1,0
impact:
        db 2,2,5,-33,0
eat:
        db 1,8,33,78,0
key:
        db 1,1,4,0,0
ice:
        db 2,6,22,66,0
done:
        db 1,32,99,-3,0
dead:
        db 1,32,1,-64,0
        endmodule

        endmodule