;; Midi2ay playback code for Amstrad CPC
;;
;; Uses firmware functions to allow music to play
;; while BASIC is active.
;;
;; CALL &8000 to setup interrupt and to play music
;; CALL &8003 to stop music
;; 
;;
;; Code assembles using wincpc's assembler.
;;
;; To use this:
;; 1. Use Midi2ay to convert a .mid file and output as asm.
;; 2. Delete the data after notas in this file.
;; 3. Copy and paste the notas from the new asm file to the end of this code
;; 4. Assemble and enjoy.
;;
;; NOTE: The tone data stored here is for the Spectrum which
;; has an AY sound chip running at 1.77Mhz.
;;
;; The CPC has an AY sound chip running at 1.0Mhz, so the tones will not 
;; be correct.

;;--------------------------------------------------------------------------------------------

kl_new_frame_fly equ &bcd7
mc_sound_register equ &bd34
kl_del_frame_fly equ &bcdd
;;--------------------------------------------------------------------------------------------

org	8000h


;;--------------------------------------------------------------------------------------------

jp play_music		;; +0
jp stop_music		;; +3

;;--------------------------------------------------------------------------------------------

play_music:
xor a
ld (counter),a
ld (count_active),a

;; setup an interrupt to be executed every frame flyback 
;; (50hz)
ld hl,ff_event_block
ld b,&81
ld c,0
ld de,ff_event_routine
call kl_new_frame_fly
ret

;;--------------------------------------------------------------------------------------------

stop_music:
ld hl,ff_event_block
call kl_del_frame_fly
ret

;;--------------------------------------------------------------------------------------------

ff_event_block:
defs 10

;;--------------------------------------------------------------------------------------------

ff_event_routine:
;; counter is active?

ld a,(count_active)
or a
;; no, do next packet
jr z,packet_begin

;; yes it's active
;; count down
ld a,(counter)
dec a
ld (counter),a

;; if counter is not zero, we quit and continue
or a
ret nz

;; counter is not active any more
xor a
ld (count_active),a

;; we now continue from counter and read remaining data in packet
ld hl,(pos)
jr cont_from_counter

;;--------------------------------------------------------------------------------------------

;; read a complete packet 
packet_begin:
ld	hl,(pos)

;; continue with part of a packet
packet_cont:

;; counter?
ld	a,(hl)
or	a
jr	nz,counter_set

;; continue after doing a counter
cont_from_counter:
inc	hl
ld	a,(hl)
cp	0ffh		;; end
jr	z,music_end
cp	0feh		;; skip?
jr	z,skip
	
;; write to ay
ld a,(hl)
inc hl
ld c,(hl)
inc hl
call mc_sound_register
		
jr	packet_cont

;;--------------------------------------------------------------------------------------------
;; start the counter

counter_set:
ld	(pos),hl
ld (counter),a
ld (count_active),a

ret

;;--------------------------------------------------------------------------------------------
;; skip data

skip:	
inc	hl
inc	hl
ld	(pos),hl
ret

;;--------------------------------------------------------------------------------------------
;; music end

music_end:
;; loop
ld hl,notas
ld (pos),hl
jr packet_cont

;;--------------------------------------------------------------------------------------------

count_active: defb 0
counter: defb 0
pos:	dw	notas

;;--------------------------------------------------------------------------------------------


;; data

notas:
	db	000h, 007h, 038h, 000h, 008h, 000h, 000h, 009h, 000h
	db	000h, 010h, 000h, 000h, 000h, 0fch, 000h, 001h, 000h
	db	000h, 008h, 00fh, 019h, 000h, 07eh, 000h, 002h, 0fch
	db	000h, 003h, 000h, 00dh, 000h, 0a8h, 000h, 002h, 07eh
	db	000h, 004h, 0fch, 000h, 005h, 000h, 019h, 000h, 0fch
	db	000h, 002h, 0a8h, 000h, 004h, 07eh, 019h, 000h, 08dh
	db	000h, 002h, 0fch, 000h, 004h, 0a8h, 019h, 000h, 0fch
	db	000h, 002h, 08dh, 000h, 004h, 0fch, 00dh, 000h, 0bdh
	db	000h, 002h, 0fch, 000h, 004h, 08dh, 019h, 002h, 0bdh
	db	000h, 004h, 0fch, 019h, 000h, 08dh, 000h, 002h, 0a8h
	db	000h, 009h, 00fh, 000h, 004h, 0bdh, 019h, 000h, 0fch
	db	000h, 002h, 08dh, 000h, 009h, 000h, 000h, 004h, 0a8h
	db	00dh, 002h, 0fch, 000h, 004h, 08dh, 00dh, 000h, 07eh
	db	000h, 002h, 0a8h, 000h, 009h, 00fh, 000h, 004h, 0fch
	db	00dh, 008h, 000h, 000h, 009h, 000h, 00dh, 008h, 00fh
	db	000h, 009h, 00fh, 000h, 004h, 07eh, 019h, 000h, 0fch
	db	000h, 002h, 07eh, 000h, 009h, 000h, 000h, 004h, 0a8h
	db	00dh, 000h, 08dh, 000h, 002h, 0a8h, 000h, 009h, 00fh
	db	000h, 004h, 0fch, 00dh, 008h, 000h, 000h, 009h, 000h
	db	00dh, 008h, 00fh, 000h, 002h, 0bdh, 000h, 009h, 00fh
	db	000h, 004h, 08dh, 00dh, 008h, 000h, 000h, 009h, 000h
	db	00dh, 000h, 096h, 000h, 008h, 00fh, 000h, 009h, 00fh
	db	00dh, 008h, 000h, 000h, 009h, 000h, 00dh, 000h, 0fch
	db	000h, 008h, 00fh, 000h, 002h, 096h, 000h, 004h, 0bdh
	db	00dh, 000h, 0a8h, 000h, 001h, 001h, 000h, 002h, 0fch
	db	000h, 004h, 096h, 003h, 002h, 0a8h, 000h, 003h, 001h
	db	000h, 004h, 0fch, 003h, 004h, 0a8h, 000h, 005h, 001h
	db	013h, 000h, 0f8h, 00dh, 000h, 0fch, 000h, 001h, 000h
	db	000h, 002h, 050h, 000h, 009h, 00fh, 000h, 004h, 0f8h
	db	00dh, 008h, 000h, 000h, 009h, 000h, 00dh, 008h, 00fh
	db	000h, 009h, 00fh, 000h, 004h, 0fch, 000h, 005h, 000h
	db	00dh, 008h, 000h, 000h, 009h, 000h, 026h, 000h, 0a8h
	db	000h, 008h, 00fh, 000h, 002h, 0d4h, 000h, 003h, 000h
	db	000h, 009h, 00fh, 000h, 004h, 01bh, 000h, 005h, 001h
	db	000h, 00ah, 00fh, 019h, 004h, 0fch, 000h, 005h, 000h
	db	00dh, 004h, 01bh, 000h, 005h, 001h, 00dh, 004h, 0fch
	db	000h, 005h, 000h, 00dh, 004h, 01bh, 000h, 005h, 001h
	db	026h, 000h, 096h, 000h, 002h, 0bdh, 000h, 004h, 0a8h
	db	00dh, 000h, 0f8h, 000h, 001h, 001h, 000h, 002h, 096h
	db	000h, 009h, 000h, 000h, 004h, 0bdh, 000h, 005h, 000h
	db	000h, 00ah, 000h, 00dh, 000h, 096h, 000h, 001h, 000h
	db	000h, 002h, 0bdh, 000h, 009h, 00fh, 000h, 004h, 0fch
	db	000h, 00ah, 00fh, 00dh, 004h, 096h, 000h, 00ah, 000h
	db	00dh, 004h, 0fch, 000h, 00ah, 00fh, 00dh, 004h, 096h
	db	000h, 00ah, 000h, 019h, 000h, 0a8h, 000h, 002h, 0d4h
	db	002h, 004h, 0a8h, 00bh, 000h, 0fch, 000h, 002h, 0a8h
	db	000h, 009h, 000h, 000h, 004h, 0d4h, 003h, 002h, 0fch
	db	000h, 004h, 0a8h, 003h, 004h, 0fch, 006h, 002h, 0f8h
	db	000h, 003h, 001h, 000h, 009h, 00fh, 00dh, 002h, 0fch
	db	000h, 003h, 000h, 000h, 004h, 050h, 000h, 005h, 001h
	db	000h, 00ah, 00fh, 00dh, 009h, 000h, 000h, 004h, 0fch
	db	000h, 005h, 000h, 000h, 00ah, 000h, 00dh, 009h, 00fh
	db	000h, 004h, 050h, 000h, 005h, 001h, 000h, 00ah, 00fh
	db	00dh, 009h, 000h, 000h, 004h, 0fch, 000h, 005h, 000h
	db	000h, 00ah, 000h, 00dh, 002h, 0f8h, 000h, 003h, 001h
	db	000h, 009h, 00fh, 00dh, 002h, 0a8h, 019h, 008h, 000h
	db	000h, 009h, 000h, 000h, 0ffh, 000h

;; end