Universal PT2 and PT3 Turbo Sound player for ZX Spectrum Release 0
(c)2004-2007 S.V.Bulba <vorobey@mail.khstu.ru>
http://bulba.untergrund.net/ (http://bulba.at.kz/)
Release date: 29 of April 2007

Common remarks
--------------

The project is based on PTxPlay Release 0. So, you can play single PT2 or PT3
modules via standard musical coprocessor of ZX Spectrum (AY) or two modules
via extradevice Turbo Sound (TS).

Features
--------

- All versions PT2-modules including PT v2.4PhF.
- PT v2.4PhF modules can be loaded not only at its compilation address.
- Tone and volume tables are generated depending PT3-module version.
- PT3-modules of v3.6 and higher played with other portamento algorithm.
- PT3-modules of v3.7 and higher can contain speccommands 1.xx and 2.xx.
- New header Vortex Tracker II modules played as PT 3.6 modules.
- Any two PT2 modules can be played simultaneously via TS.
- Same via TS can be played any two PT3 modules .
- PT 3.7+ modules, saved in TS mode, also can be played through TS.
- Player signals about looping any of played modules.
- Looping can be disabled.
- Channels allocation for stereo can be changed during playing.
- Can be called from ZX Spectrum basic.
- At any moment can be read current position number.
- Assembling at any Z80 address.
- The most variables moved outside of code block to any desired address.

Compilation
-----------

Conditional assembly allows include next optional features:

1) positions counter for each of played module at (VARS1+0) and (VARS2+0);
2) ability to change channels allocation during playing;
3) checking loop point;
4) disabling official identificator;
5) correct return to ZX basic.

Project was compiled in assembler for Win32:

SjASM Z80 Assembler v0.39f
Copyright 2005 Sjoerd Mastijn

Minimal build take 2312 bytes for codes and 703 bytes for variables.

Files
-----

PTxPlay.asm - source Z80 assembler code.
PTxPlay.txt - same text is prepared for ZX Asm 3.10.
PTxPlay.h - same text is prepared for Alasm (all comments are removed).
PTxPlay - assembled binary code block in minimal configuration for ZX Spectrum
with identificator to load at #C000 address, zeroes at end can be truncated.

Entry points
------------

Before playing at (START+10) set bit 1 for PT2 and reset for PT3 and call START
(loading) address, and also bit 4-5: %00 - single module for AY, %01 - 2 modules
for TS, %10 - single PT3 or autodetect PT3 TS-format by AlCo (PT 3.7+).

To detect module type you can use UniSearch by Spectre.

Player is not reallocable, so you need to assemble with other ORG value, if you
want to load code at other than #C000 address, also you can place VARS area to
any other address too. After calling START AY (TS) stops any sounding. At
START+10 is located SETUP byte, where bit 0 is used to control looping of
melody. At any time you can set bit 0 to disable loop. Bit 7 can be checked at
any moment, it is set after reaching end of module (finishing playing of last
position). For check looping 2nd module use bit 6. Bits 2 and 3 are used for
setting channels allocation. Only first three combinations of these bits are
allowed: 0 - ABC, 1 - ACB, 2 - BAC. ABC is used to output channels "as is". ACB
swaps B and C, and BAC swaps A and B. So, any stereo combinations can be
heard: ABC-stereo for the most xUSSR ZX-clones, ACB - East Europe ones, and
BAC - ZS Scorpion 256K.

In current compilation module must be loaded after variables (by default). Of
course, you can change it in source or in assembled code. Also you can specify
module addresses in HL and DE as follows:

	LD HL,PT3Module1
	LD DE,PT3Module2
	LD A,16 ;2xPT3
	LD (START+10),A
	CALL START+3

By calling START you are proceeding INIT procedure, which analyzes module type
bit and prepares corresponding player branches, checks 1st PT3 module version
and prepares corresponding note and volume tables (it is need for correct
playing of modules of different PT3 subversions). Also you can call START after
stopping playing to mute AY sound. In last case you can call START+8 to simple
mute AY sound, to continue playing simply continue calling START+5 as usually.

To play, call START+5 address each 1/50 of second (interrupt). Playing selects
right portamento algorithm for old (v3.5-) and new (v3.6+ or VT II) modules.
During running PLAY subprogram no any interrupts are expected, it is your task
to right call PLAY. For example, next example is totally right:

	CALL #C000 ;calling init
	EI ;enable interrupts
_LP	HALT ;wait for next interrupt
	CALL #C005 ;call play
	XOR A ;test keyboard
	IN A,(#FE)
	CPL
	AND 15
	JR Z,_LP
	CALL #C008 ;mute AY sound (you can resume playing from current place)
	RET

At (VARS1+0) and (VARS2+0) current position of each module can be placed (see
conditional assembly keys).
To get common number of position, see module header or use UniSearch by Spectre.

Example of playing without loop:

	LD A,1
	LD (START+10),A
	CALL START
	EI
LOOP	HALT
	CALL START+5
	LD A,(START+10)
	RLA ;only 1st or single module test
	JR NC,LOOP
	RET

Read also all comments in source file.

Thanks to Andrey Bogdanovich aka Spectre for help and UniSearch; Ivan Roshin for
tone and volume tables generators; Alone Coder for TS format description and
help.

Sergey Bulba

19 of September 2004 - 29 of April 2007
