forked from len0rd/rockbox
sync asap codec to ASAP 2.1
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24511 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
b1a6c9096d
commit
35472fe7f1
11 changed files with 3710 additions and 2605 deletions
|
@ -1,37 +1,58 @@
|
||||||
People who have contributed to ASAP
|
Authors
|
||||||
-----------------------------------
|
-------
|
||||||
|
|
||||||
Atari800 Development Team (http://atari800.sourceforge.net)
|
Piotr Fusik {asapwww!<fox@scene.pl>}::
|
||||||
* 6502 and POKEY emulation used in 0.x.y versions of ASAP
|
Creator and main developer.
|
||||||
|
|
||||||
Zdenek Eisenhammer <pg@pinknet.cz>
|
Atari800 Emulator Developers {asapwww!(http://atari800.sourceforge.net)}::
|
||||||
* testing
|
6502 and POKEY emulation used in 0.x.y versions of ASAP.
|
||||||
|
|
||||||
Piotr Fusik <fox@scene.pl>
|
Zdenek Eisenhammer {asapwww!<pg@pinknet.cz>}::
|
||||||
* author and maintainer of ASAP
|
Testing.
|
||||||
|
|
||||||
Maciek Konecki <maciusk1@wp.pl>
|
Henryk Karpowicz {asapwww!<henkar@poczta.tygrys.net>}::
|
||||||
* porting to C#
|
CMC routine modified for the CM3 format.
|
||||||
|
|
||||||
Marcin Lewandowski <jaskier@atari8.info>
|
Maciek Konecki {asapwww!<maciusk1@wp.pl>}::
|
||||||
* 6502 routines for playing CMC, MPT, TMC and TM2
|
Porting to C#.
|
||||||
|
|
||||||
Perry McFarlane <perry_m@fastmail.fm>
|
Marek Konopka {asapwww!<konop11@poczta.onet.pl>}::
|
||||||
* POKEY reverse-engineering
|
6502 routine for playing DLT.
|
||||||
|
|
||||||
Kostas Nakos <knakos@gmail.com>
|
Marcin Lewandowski {asapwww!<jaskier@atari8.info>}::
|
||||||
* compilation for Windows CE
|
6502 routines for playing CMC, MPT, TMC and TM2.
|
||||||
|
|
||||||
Slawomir Sledz <slaves@scene.pl>
|
Adrian Matoga {asapwww!<epi@atari8.info>}::
|
||||||
* testing
|
COVOX information and test files. Testing.
|
||||||
|
|
||||||
Radek Sterba <raster@infos.cz>
|
Perry McFarlane {asapwww!<perry_m@fastmail.fm>}::
|
||||||
* 6502 routine for playing RMT
|
POKEY reverse-engineering.
|
||||||
* testing
|
|
||||||
|
|
||||||
Lukasz Sychowicz <xray@scene.pl>
|
Kostas Nakos {asapwww!<knakos@gmail.com>}::
|
||||||
* Windows icons
|
Windows CE testing.
|
||||||
* testing
|
|
||||||
|
|
||||||
Michal Szpilowski <miker@atari.pl>
|
Mariusz Rozwadowski {asapwww!<ramosc64@o2.pl>}::
|
||||||
* testing
|
Suggested CMS, CM3 and DLT format support.
|
||||||
|
|
||||||
|
Slawomir Sledz {asapwww!<slaves@scene.pl>}::
|
||||||
|
Testing.
|
||||||
|
|
||||||
|
David Spilka::
|
||||||
|
6502 routine for playing CMS.
|
||||||
|
|
||||||
|
Radek Sterba {asapwww!<raster@infos.cz>}::
|
||||||
|
6502 routine for playing RMT.
|
||||||
|
Testing.
|
||||||
|
|
||||||
|
Lukasz Sychowicz {asapwww!<xray@scene.pl>}::
|
||||||
|
Windows icons.
|
||||||
|
Testing.
|
||||||
|
|
||||||
|
Pawel Szewczyk {asapwww!<ripek@op.pl>}::
|
||||||
|
Windows setup graphics.
|
||||||
|
|
||||||
|
Michal Szpilowski {asapwww!<miker@atari.pl>}::
|
||||||
|
Testing.
|
||||||
|
|
||||||
|
Grzegorz Zyla {asapwww!<gsunr@poczta.onet.pl>}::
|
||||||
|
XBMC plugin testing.
|
||||||
|
|
|
@ -1,59 +1,142 @@
|
||||||
ASAP - Another Slight Atari Player
|
ASAP - Another Slight Atari Player
|
||||||
----------------------------------
|
==================================
|
||||||
|
|
||||||
ASAP is a player of Atari 8-bit music for modern computers.
|
// This file is in AsciiDoc format. It is converted to README.html.
|
||||||
It emulates the POKEY sound chip and the 6502 processor.
|
:Compact-Option:
|
||||||
The project was initially based on the routines from the Atari800 emulator,
|
|
||||||
|
ifdef::asapwww[]
|
||||||
|
http://sourceforge.net/projects/asap/files/asap/[Download] |
|
||||||
|
http://asap.git.sourceforge.net/git/gitweb.cgi?p=asap/asap;a=summary[Browse source code (Git)] |
|
||||||
|
http://sourceforge.net/scm/?type=git&group_id=154391[Get latest source code (Git)] |
|
||||||
|
http://sourceforge.net/projects/asap/[SourceForge project page]
|
||||||
|
endif::asapwww[]
|
||||||
|
|
||||||
|
ASAP is a player of http://en.wikipedia.org/wiki/Atari_8-bit_family[8-bit Atari]
|
||||||
|
music for modern computers.
|
||||||
|
It emulates the http://en.wikipedia.org/wiki/POKEY[POKEY sound chip]
|
||||||
|
and the http://en.wikipedia.org/wiki/6502[6502 processor].
|
||||||
|
The project was initially based on the routines from the
|
||||||
|
http://atari800.sourceforge.net/[Atari800 emulator],
|
||||||
but the current version has a completely new original emulation core.
|
but the current version has a completely new original emulation core.
|
||||||
|
|
||||||
The ASAP project includes the following programs:
|
ASAP includes the following programs:
|
||||||
* ASAP2WAV - portable command-line utility that generates WAV files
|
|
||||||
* WASAP - tiny player for Windows
|
|
||||||
* plugin for Apollo
|
|
||||||
* plugin for foobar2000 0.9
|
|
||||||
* plugin for GSPlayer
|
|
||||||
* plugin for MOC
|
|
||||||
* plugin for Winamp
|
|
||||||
* plugin for XMMS
|
|
||||||
* DirectShow source filter (for Windows Media Player)
|
|
||||||
* Java version of ASAP2WAV
|
|
||||||
* Java applet
|
|
||||||
* Java midlet
|
|
||||||
* C# version of ASAP2WAV
|
|
||||||
|
|
||||||
The following input formats are supported:
|
- asapconv - portable command-line converter {asapwin=}
|
||||||
* SAP (Slight Atari Player - standard file format for playing Atari 8-bit
|
- WASAP - tiny player for Windows {asapwin=}
|
||||||
music on modern computers)
|
- plugin for http://koti.welho.com/hylinen/apollo/[Apollo] {asapwin=}
|
||||||
* CMC (Chaos Music Composer)
|
- plugin for http://foobar2000.org/[foobar2000] {asapwin=}
|
||||||
* CMR (CMC Rzog)
|
- plugin for http://hp.vector.co.jp/authors/VA032810/[GSPlayer] {asapwin=}{asapwince=}
|
||||||
* DMC (DoublePlay CMC)
|
- plugin for http://moc.daper.net/[MOC]
|
||||||
* MPT (Music ProTracker)
|
- plugin for http://www.winamp.com/[Winamp] {asapwin=}
|
||||||
* MPD (MPT DoublePlay)
|
- plugin for http://www.microsoft.com/windows/windowsmedia/player/[Windows Media Player] {asapwin=}
|
||||||
* RMT (Raster Music Tracker)
|
- plugin for http://xbmc.org/[XBMC] {asapwin=}
|
||||||
* TMC, TM8 (Theta Music Composer 1.x)
|
- plugin for http://xmms.org/[XMMS]
|
||||||
* TM2 (Theta Music Composer 2.x)
|
- plugin for http://www.un4seen.com/[XMPlay] {asapwin=}
|
||||||
|
- POKEY sound emulation DLL for http://raster.infos.cz/atari/rmt/rmt.htm[Raster Music Tracker] {asapwin=}
|
||||||
|
- Java version of ASAP2WAV - command-line converter to WAV files {asapjava=}
|
||||||
|
- Java applet - for web pages {asapjava=}{asapwww?(see link:applet.html[online demo])}
|
||||||
|
- Java midlet - for mobile devices {asapjava=}
|
||||||
|
- C# version of ASAP2WAV
|
||||||
|
- experimental JScript version of ASAP2WAV running in Windows Script Host {asapjavascript=}
|
||||||
|
- experimental JavaScript version of ASAP2WAV running in Firefox {asapjavascript=}
|
||||||
|
- Flash player - for web pages {asapflash=}{asapwww?(see link:flash.html[online demo])}
|
||||||
|
|
||||||
If you are looking for Atari 8-bit music, there is a single big collection
|
{asapports}The summary of the differences between the above versions is in link:PORTS.xml[this table].
|
||||||
of it called Atari SAP Music Archive (http://asma.atari.org).
|
|
||||||
|
|
||||||
If you are interested in the ASAP project, please subscribe its mailing list:
|
There are other projects which use ASAP:
|
||||||
https://lists.sourceforge.net/lists/listinfo/asap-users
|
|
||||||
As in the Atari800 project, this is a combined list for end users
|
|
||||||
and for developers. Once you subscribe, you can post comments, ideas
|
|
||||||
and questions about ASAP. They will be answered ASAP. ;-)
|
|
||||||
|
|
||||||
If, for some reason, you do not want to subscribe the mailing list,
|
- http://mmsap.sourceforge.net/[mmSAP 2] - standalone player for GNU/Linux with GTK+ user interface
|
||||||
but have a bug report, feature request or a small code patch, you can use
|
- http://www.rockbox.org/[Rockbox] - open source firmware for MP3 players
|
||||||
the sf.net tracker. Use "Bugs", "Feature Requests" or "Patches" link
|
|
||||||
on this page:
|
|
||||||
http://sourceforge.net/projects/asap/
|
|
||||||
|
|
||||||
ASAP is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published
|
|
||||||
by the Free Software Foundation; either version 2 of the License,
|
|
||||||
or (at your option) any later version.
|
|
||||||
|
|
||||||
ASAP is distributed in the hope that it will be useful,
|
Input file formats
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty
|
------------------
|
||||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the included GNU General Public License for more details.
|
ASAP supports the following file formats (determined by the filename extension):
|
||||||
|
|
||||||
|
SAP (Slight Atari Player)::
|
||||||
|
The format designed for playing 8-bit Atari music on modern computers.
|
||||||
|
All other formats can be converted to SAP.
|
||||||
|
http://asma.atari.org/[Atari SAP Music Archive (ASMA)]
|
||||||
|
is a single big collection of SAP files.
|
||||||
|
|
||||||
|
CMC (Chaos Music Composer)::
|
||||||
|
Atari music editor from early 1990s.
|
||||||
|
|
||||||
|
CM3 (CMC "3/4")::
|
||||||
|
CMC with modified pattern length.
|
||||||
|
|
||||||
|
CMR (CMC "Rzog")::
|
||||||
|
CMC with modified bass sounds.
|
||||||
|
|
||||||
|
CMS (Stereo Double CMC)::
|
||||||
|
Stereo CMC.
|
||||||
|
|
||||||
|
DMC (DoublePlay CMC)::
|
||||||
|
CMC with 6502 routine executed at double rate of the original CMC.
|
||||||
|
|
||||||
|
DLT (Delta Music Composer)::
|
||||||
|
Atari music editor from 1990s.
|
||||||
|
|
||||||
|
MPT (Music ProTracker)::
|
||||||
|
Atari music editor from 1990s.
|
||||||
|
|
||||||
|
MPD (MPT DoublePlay)::
|
||||||
|
MPT with 6502 routine executed at double rate of the original MPT.
|
||||||
|
|
||||||
|
RMT (http://raster.infos.cz/atari/rmt/rmt.htm[Raster Music Tracker])::
|
||||||
|
Modern Atari music editor running on Windows.
|
||||||
|
|
||||||
|
TMC, TM8 (http://jaskier.atari8.info/[Theta Music Composer] 1.x)::
|
||||||
|
Atari music editor from late 1990s.
|
||||||
|
The two file extensions are treated identically and played in stereo.
|
||||||
|
TM8 means it's stereo (8-channel) music while TMC can be either mono or stereo.
|
||||||
|
|
||||||
|
TM2 (http://jaskier.atari8.info/[Theta Music Composer] 2.x)::
|
||||||
|
Modern Atari music editor.
|
||||||
|
|
||||||
|
|
||||||
|
ifdef::asapsrc[]
|
||||||
|
include::INSTALL[]
|
||||||
|
endif::asapsrc[]
|
||||||
|
|
||||||
|
ifdef::asapflash[]
|
||||||
|
include::flash/USAGE[]
|
||||||
|
endif::asapflash[]
|
||||||
|
|
||||||
|
ifdef::asapjava[]
|
||||||
|
include::java/USAGE[]
|
||||||
|
endif::asapjava[]
|
||||||
|
|
||||||
|
ifdef::asapjavascript[]
|
||||||
|
include::javascript/USAGE[]
|
||||||
|
endif::asapjavascript[]
|
||||||
|
|
||||||
|
ifdef::asapwin[]
|
||||||
|
include::win32/USAGE[]
|
||||||
|
endif::asapwin[]
|
||||||
|
|
||||||
|
ifdef::asapwince[]
|
||||||
|
include::gsplayer/USAGE[]
|
||||||
|
endif::asapwince[]
|
||||||
|
|
||||||
|
include::NEWS[]
|
||||||
|
|
||||||
|
include::CREDITS[]
|
||||||
|
|
||||||
|
|
||||||
|
Feedback
|
||||||
|
--------
|
||||||
|
|
||||||
|
If you are interested in the ASAP project, please subscribe its
|
||||||
|
https://lists.sourceforge.net/lists/listinfo/asap-users[mailing list].
|
||||||
|
This list is for users and developers.
|
||||||
|
Once you subscribe, you can post comments, ideas and questions about ASAP.
|
||||||
|
They will be answered ASAP. ;-)
|
||||||
|
|
||||||
|
Use http://sourceforge.net/tracker/?group_id=154391[tracker]
|
||||||
|
to submit bug reports, feature requests and small code patches.
|
||||||
|
|
||||||
|
ifdef::asapwww[]
|
||||||
|
image::http://sflogo.sourceforge.net/sflogo.php?group_id=154391&type=13["Get ASAP - Another Slight Atari Player at SourceForge.net. Fast, secure and Free Open Source software downloads",width=120,height=30,link="http://sourceforge.net/projects/asap/"]
|
||||||
|
endif::asapwww[]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
Library: asap-1.2.0
|
Library: asap-2.1.0
|
||||||
Imported: 2008-26-07 by Dominik Wenger
|
Imported: 2010-02-02 by Dominik Wenger
|
||||||
|
|
||||||
This directory contains a local version of asap (http://asap.sourceforge.net/) for decoding Atari 8bit .sap
|
This directory contains a local version of asap (http://asap.sourceforge.net/) for decoding Atari 8bit .sap
|
||||||
audio streams.
|
audio streams.
|
||||||
|
@ -14,12 +14,8 @@ The Licence is the same as the rest of Rockbox.
|
||||||
IMPORT DETAILS
|
IMPORT DETAILS
|
||||||
|
|
||||||
The .[ch] files in apps/codec/asap are copied from ASAP.
|
The .[ch] files in apps/codec/asap are copied from ASAP.
|
||||||
Some #defines were added, so it uses the ci-> Pointer.
|
|
||||||
|
|
||||||
A small modification was needed in asap.h Line 120.
|
players.h (contains binarys of players) was generated and copied
|
||||||
(changed the delta buffer to signed char)
|
|
||||||
|
|
||||||
Also players.h (contains binarys of players) was generated and copied
|
|
||||||
into Rockbox.
|
into Rockbox.
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
218
apps/codecs/libasap/anylang.h
Normal file
218
apps/codecs/libasap/anylang.h
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
/*
|
||||||
|
* anylang.h - C/Java/C#/JavaScript/ActionScript abstraction layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007-2010 Piotr Fusik
|
||||||
|
*
|
||||||
|
* This file is part of ASAP (Another Slight Atari Player),
|
||||||
|
* see http://asap.sourceforge.net
|
||||||
|
*
|
||||||
|
* ASAP is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2 of the License,
|
||||||
|
* or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* ASAP is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with ASAP; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ANYLANG_H_
|
||||||
|
#define _ANYLANG_H_
|
||||||
|
|
||||||
|
#if defined(JAVA) || defined(CSHARP) || defined(JAVASCRIPT) || defined(ACTIONSCRIPT)
|
||||||
|
|
||||||
|
#define FALSE false
|
||||||
|
#define TRUE true
|
||||||
|
#define NULL null
|
||||||
|
#define _ .
|
||||||
|
#define PRIVATE
|
||||||
|
#define CONST
|
||||||
|
#define OUT_STRING STRING
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define C
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define PRIVATE static
|
||||||
|
#define FUNC(type, name, pars) type name pars
|
||||||
|
#define P(type, name) type name
|
||||||
|
#define V(type, name) type name
|
||||||
|
#define CONST const
|
||||||
|
#define _ ->
|
||||||
|
#define PTR *
|
||||||
|
#define ADDRESSOF &
|
||||||
|
#define CAST(type) (type)
|
||||||
|
#define TO_INT(x) (int) (x)
|
||||||
|
#define TO_BYTE(x) (byte) (x)
|
||||||
|
#define BYTEARRAY byte *
|
||||||
|
#define BOOLARRAY abool *
|
||||||
|
#define VOIDPTR void *
|
||||||
|
#define UBYTE(data) (data)
|
||||||
|
#define SBYTE(data) (signed char) (data)
|
||||||
|
#define CONST_ARRAY(type, name) static const type name[] = {
|
||||||
|
#define END_CONST_ARRAY }
|
||||||
|
#define ZERO_ARRAY(array) memset(array, 0, sizeof(array))
|
||||||
|
#define COPY_ARRAY(dest, dest_offset, src, src_offset, len) \
|
||||||
|
memcpy(dest + dest_offset, src + src_offset, len)
|
||||||
|
#define NEW_ARRAY(type, name, size) \
|
||||||
|
type name[size]
|
||||||
|
#define INIT_ARRAY(array) memset(array, 0, sizeof(array))
|
||||||
|
#define STRING const char *
|
||||||
|
#define OUT_STRING char *
|
||||||
|
#define CHARAT(s, i) (s)[i]
|
||||||
|
#define CHARCODEAT(s, i) (s)[i]
|
||||||
|
#define CHARCODE(c) (c)
|
||||||
|
#define EQUAL_STRINGS(s1, s2) (strcmp(s1, s2) == 0)
|
||||||
|
#define EMPTY_STRING(s) (s)[0] = '\0'
|
||||||
|
#define SUBSTR(s, i) (s + i)
|
||||||
|
#define BYTES_TO_STRING(dest, src, src_offset, len) \
|
||||||
|
do { memcpy(dest, src + src_offset, len); (dest)[len] = '\0'; } while (FALSE)
|
||||||
|
#define SUBSTRING(dest, src, src_offset, len) \
|
||||||
|
do { memcpy(dest, src + src_offset, len); (dest)[len] = '\0'; } while (FALSE)
|
||||||
|
|
||||||
|
#define RESOURCE const byte *
|
||||||
|
#define GET_RESOURCE(name, ext) name##_##ext
|
||||||
|
|
||||||
|
#endif /* defined(JAVA) || defined(CSHARP) || defined(JAVASCRIPT) || defined(ACTIONSCRIPT) */
|
||||||
|
|
||||||
|
#ifdef JAVA
|
||||||
|
|
||||||
|
#define abool boolean
|
||||||
|
#define FUNC(type, name, pars) private static type name pars
|
||||||
|
#define P(type, name) type name
|
||||||
|
#define V(type, name) type name
|
||||||
|
#define PTR
|
||||||
|
#define ADDRESSOF
|
||||||
|
#define CAST(type) (type)
|
||||||
|
#define TO_INT(x) (int) (x)
|
||||||
|
#define TO_BYTE(x) (byte) (x)
|
||||||
|
#define BYTEARRAY byte[]
|
||||||
|
#define BOOLARRAY boolean[]
|
||||||
|
#define VOIDPTR byte[]
|
||||||
|
#define UBYTE(data) ((data) & 0xff)
|
||||||
|
#define SBYTE(data) (byte) (data)
|
||||||
|
#define CONST_ARRAY(type, name) private static final type[] name = {
|
||||||
|
#define END_CONST_ARRAY }
|
||||||
|
#define sizeof(array) array.length
|
||||||
|
#define ZERO_ARRAY(array) for (int ii = 0; ii < array.length; ii++) array[ii] = 0
|
||||||
|
#define COPY_ARRAY(dest, dest_offset, src, src_offset, len) \
|
||||||
|
System.arraycopy(src, src_offset, dest, dest_offset, len)
|
||||||
|
#define NEW_ARRAY(type, name, size) \
|
||||||
|
type[] name = new type[size]
|
||||||
|
#define INIT_ARRAY(array)
|
||||||
|
#define STRING String
|
||||||
|
#define CHARAT(s, i) (s).charAt(i)
|
||||||
|
#define CHARCODEAT(s, i) (s).charAt(i)
|
||||||
|
#define CHARCODE(c) (c)
|
||||||
|
#define strlen(s) (s).length()
|
||||||
|
#define EQUAL_STRINGS(s1, s2) (s1).equals(s2)
|
||||||
|
#define EMPTY_STRING(s) (s) = ""
|
||||||
|
#define SUBSTR(s, i) (s).substring(i)
|
||||||
|
#define BYTES_TO_STRING(dest, src, src_offset, len) \
|
||||||
|
(dest) = new String(src, src_offset, len)
|
||||||
|
#define SUBSTRING(dest, src, src_offset, len) \
|
||||||
|
(dest) = (src).substring(src_offset, src_offset + len)
|
||||||
|
|
||||||
|
#define RESOURCE byte[]
|
||||||
|
#define GET_RESOURCE(name, ext) getResourceBytes(#name + "." + #ext)
|
||||||
|
|
||||||
|
#elif defined(CSHARP)
|
||||||
|
|
||||||
|
#define abool bool
|
||||||
|
#define FUNC(type, name, pars) private static type name pars
|
||||||
|
#define P(type, name) type name
|
||||||
|
#define V(type, name) type name
|
||||||
|
#define PTR
|
||||||
|
#define ADDRESSOF
|
||||||
|
#define CAST(type) (type)
|
||||||
|
#define TO_INT(x) (int) (x)
|
||||||
|
#define TO_BYTE(x) (byte) (x)
|
||||||
|
#define BYTEARRAY byte[]
|
||||||
|
#define BOOLARRAY bool[]
|
||||||
|
#define VOIDPTR byte[]
|
||||||
|
#define UBYTE(data) (data)
|
||||||
|
#define SBYTE(data) (sbyte) (data)
|
||||||
|
#define CONST_ARRAY(type, name) private static readonly type[] name = {
|
||||||
|
#define END_CONST_ARRAY }
|
||||||
|
#define sizeof(array) array.Length
|
||||||
|
#define ZERO_ARRAY(array) Array.Clear(array, 0, array.Length)
|
||||||
|
#define COPY_ARRAY(dest, dest_offset, src, src_offset, len) \
|
||||||
|
Array.Copy(src, src_offset, dest, dest_offset, len)
|
||||||
|
#define NEW_ARRAY(type, name, size) \
|
||||||
|
type[] name = new type[size]
|
||||||
|
#define INIT_ARRAY(array)
|
||||||
|
#define STRING string
|
||||||
|
#define CHARAT(s, i) (s)[i]
|
||||||
|
#define CHARCODEAT(s, i) (s)[i]
|
||||||
|
#define CHARCODE(c) (c)
|
||||||
|
#define strlen(s) (s).Length
|
||||||
|
#define EQUAL_STRINGS(s1, s2) ((s1) == (s2))
|
||||||
|
#define EMPTY_STRING(s) (s) = string.Empty
|
||||||
|
#define SUBSTR(s, i) (s).Substring(i)
|
||||||
|
#define BYTES_TO_STRING(dest, src, src_offset, len) \
|
||||||
|
(dest) = System.Text.Encoding.ASCII.GetString(src, src_offset, len)
|
||||||
|
#define SUBSTRING(dest, src, src_offset, len) \
|
||||||
|
(dest) = (src).Substring(src_offset, len)
|
||||||
|
|
||||||
|
#define RESOURCE byte[]
|
||||||
|
#define GET_RESOURCE(name, ext) name##_##ext
|
||||||
|
|
||||||
|
#elif defined(JAVASCRIPT) || defined(ACTIONSCRIPT)
|
||||||
|
|
||||||
|
#ifdef ACTIONSCRIPT
|
||||||
|
#define abool Boolean
|
||||||
|
#define char String
|
||||||
|
#define STRING String
|
||||||
|
#define BYTEARRAY ByteArray
|
||||||
|
#define BOOLARRAY Array
|
||||||
|
#define VOIDPTR ByteArray
|
||||||
|
#define RESOURCE Array
|
||||||
|
#define FUNC(type, name, pars) private static function name pars : type
|
||||||
|
#define P(type, name) name : type
|
||||||
|
#define V(type, name) var name : type
|
||||||
|
#define TO_INT(x) int(x)
|
||||||
|
#define CONST_ARRAY(type, name) private static const name : Array = [
|
||||||
|
#else
|
||||||
|
#define FUNC(type, name, pars) function name pars
|
||||||
|
#define P(type, name) name
|
||||||
|
#define V(type, name) var name
|
||||||
|
#define TO_INT(x) Math.floor(x)
|
||||||
|
#define CONST_ARRAY(type, name) var name = [
|
||||||
|
#endif
|
||||||
|
#define PTR
|
||||||
|
#define ADDRESSOF
|
||||||
|
#define CAST(type)
|
||||||
|
#define TO_BYTE(x) ((x) & 0xff)
|
||||||
|
#define UBYTE(data) (data)
|
||||||
|
#define SBYTE(data) ((data) < 0x80 ? (data) : (data) - 256)
|
||||||
|
#define END_CONST_ARRAY ]
|
||||||
|
#define sizeof(array) array.length
|
||||||
|
#define ZERO_ARRAY(array) for (V(int, ii) = 0; ii < array.length; ii++) array[ii] = 0
|
||||||
|
#define COPY_ARRAY(dest, dest_offset, src, src_offset, len) \
|
||||||
|
for (V(int, ii) = 0; ii < len; ii++) dest[dest_offset + ii] = src[src_offset + ii]
|
||||||
|
#define NEW_ARRAY(type, name, size) \
|
||||||
|
V(Array, name) = new Array(size)
|
||||||
|
#define INIT_ARRAY(array) for (V(int, ii) = 0; ii < array.length; ii++) array[ii] = 0
|
||||||
|
#define CHARAT(s, i) (s).charAt(i)
|
||||||
|
#define CHARCODEAT(s, i) (s).charCodeAt(i)
|
||||||
|
#define CHARCODE(c) (c).charCodeAt(0)
|
||||||
|
#define strlen(s) (s).length
|
||||||
|
#define EQUAL_STRINGS(s1, s2) ((s1) == (s2))
|
||||||
|
#define EMPTY_STRING(s) s = ""
|
||||||
|
#define SUBSTR(s, i) (s).substr(i)
|
||||||
|
#define BYTES_TO_STRING(dest, src, src_offset, len) \
|
||||||
|
{ dest = ""; for (V(int, ii) = 0; ii < len; ii++) dest += String.fromCharCode(src[src_offset + ii]); }
|
||||||
|
#define SUBSTRING(dest, src, src_offset, len) \
|
||||||
|
dest = (src).substring(src_offset, src_offset + len)
|
||||||
|
|
||||||
|
#define GET_RESOURCE(name, ext) name##_##ext
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _ANYLANG_H_ */
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* apokeysnd.c - another POKEY sound emulator
|
* apokeysnd.c - another POKEY sound emulator
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2008 Piotr Fusik
|
* Copyright (C) 2007-2009 Piotr Fusik
|
||||||
*
|
*
|
||||||
* This file is part of ASAP (Another Slight Atari Player),
|
* This file is part of ASAP (Another Slight Atari Player),
|
||||||
* see http://asap.sourceforge.net
|
* see http://asap.sourceforge.net
|
||||||
|
@ -20,114 +20,109 @@
|
||||||
* along with ASAP; if not, write to the Free Software Foundation, Inc.,
|
* along with ASAP; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#include "codeclib.h"
|
|
||||||
#if !defined(JAVA) && !defined(CSHARP)
|
|
||||||
#include <string.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "asap_internal.h"
|
#include "asap_internal.h"
|
||||||
|
|
||||||
#define memset ci->memset
|
|
||||||
#define ULTRASOUND_CYCLES 112
|
#define ULTRASOUND_CYCLES 112
|
||||||
|
|
||||||
#define MUTE_FREQUENCY 1
|
#define MUTE_FREQUENCY 1
|
||||||
#define MUTE_INIT 2
|
#define MUTE_INIT 2
|
||||||
#define MUTE_USER 4
|
#define MUTE_USER 4
|
||||||
|
|
||||||
CONST_LOOKUP(byte, poly4_lookup) =
|
CONST_ARRAY(byte, poly4_lookup)
|
||||||
{ 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1 };
|
0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1
|
||||||
CONST_LOOKUP(byte, poly5_lookup) =
|
END_CONST_ARRAY;
|
||||||
{ 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1,
|
CONST_ARRAY(byte, poly5_lookup)
|
||||||
0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1 };
|
0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1,
|
||||||
|
0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1
|
||||||
|
END_CONST_ARRAY;
|
||||||
|
|
||||||
FILE_FUNC void init_state(PokeyState PTR pst)
|
PRIVATE FUNC(void, PokeySound_InitializeChip, (P(PokeyState PTR, pst)))
|
||||||
{
|
{
|
||||||
PST audctl = 0;
|
pst _ audctl = 0;
|
||||||
PST init = FALSE;
|
pst _ init = FALSE;
|
||||||
PST poly_index = 15 * 31 * 131071;
|
pst _ poly_index = 15 * 31 * 131071;
|
||||||
PST div_cycles = 28;
|
pst _ div_cycles = 28;
|
||||||
PST mute1 = MUTE_FREQUENCY | MUTE_USER;
|
pst _ mute1 = MUTE_FREQUENCY | MUTE_USER;
|
||||||
PST mute2 = MUTE_FREQUENCY | MUTE_USER;
|
pst _ mute2 = MUTE_FREQUENCY | MUTE_USER;
|
||||||
PST mute3 = MUTE_FREQUENCY | MUTE_USER;
|
pst _ mute3 = MUTE_FREQUENCY | MUTE_USER;
|
||||||
PST mute4 = MUTE_FREQUENCY | MUTE_USER;
|
pst _ mute4 = MUTE_FREQUENCY | MUTE_USER;
|
||||||
PST audf1 = 0;
|
pst _ audf1 = 0;
|
||||||
PST audf2 = 0;
|
pst _ audf2 = 0;
|
||||||
PST audf3 = 0;
|
pst _ audf3 = 0;
|
||||||
PST audf4 = 0;
|
pst _ audf4 = 0;
|
||||||
PST audc1 = 0;
|
pst _ audc1 = 0;
|
||||||
PST audc2 = 0;
|
pst _ audc2 = 0;
|
||||||
PST audc3 = 0;
|
pst _ audc3 = 0;
|
||||||
PST audc4 = 0;
|
pst _ audc4 = 0;
|
||||||
PST tick_cycle1 = NEVER;
|
pst _ tick_cycle1 = NEVER;
|
||||||
PST tick_cycle2 = NEVER;
|
pst _ tick_cycle2 = NEVER;
|
||||||
PST tick_cycle3 = NEVER;
|
pst _ tick_cycle3 = NEVER;
|
||||||
PST tick_cycle4 = NEVER;
|
pst _ tick_cycle4 = NEVER;
|
||||||
PST period_cycles1 = 28;
|
pst _ period_cycles1 = 28;
|
||||||
PST period_cycles2 = 28;
|
pst _ period_cycles2 = 28;
|
||||||
PST period_cycles3 = 28;
|
pst _ period_cycles3 = 28;
|
||||||
PST period_cycles4 = 28;
|
pst _ period_cycles4 = 28;
|
||||||
PST reload_cycles1 = 28;
|
pst _ reload_cycles1 = 28;
|
||||||
PST reload_cycles3 = 28;
|
pst _ reload_cycles3 = 28;
|
||||||
PST out1 = 0;
|
pst _ out1 = 0;
|
||||||
PST out2 = 0;
|
pst _ out2 = 0;
|
||||||
PST out3 = 0;
|
pst _ out3 = 0;
|
||||||
PST out4 = 0;
|
pst _ out4 = 0;
|
||||||
PST delta1 = 0;
|
pst _ delta1 = 0;
|
||||||
PST delta2 = 0;
|
pst _ delta2 = 0;
|
||||||
PST delta3 = 0;
|
pst _ delta3 = 0;
|
||||||
PST delta4 = 0;
|
pst _ delta4 = 0;
|
||||||
PST skctl = 3;
|
pst _ skctl = 3;
|
||||||
ZERO_ARRAY(PST delta_buffer);
|
ZERO_ARRAY(pst _ delta_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASAP_FUNC void PokeySound_Initialize(ASAP_State PTR ast)
|
FUNC(void, PokeySound_Initialize, (P(ASAP_State PTR, ast)))
|
||||||
{
|
{
|
||||||
int i;
|
V(int, i);
|
||||||
int reg;
|
V(int, reg);
|
||||||
reg = 0x1ff;
|
reg = 0x1ff;
|
||||||
for (i = 0; i < 511; i++) {
|
for (i = 0; i < 511; i++) {
|
||||||
reg = ((((reg >> 5) ^ reg) & 1) << 8) + (reg >> 1);
|
reg = ((((reg >> 5) ^ reg) & 1) << 8) + (reg >> 1);
|
||||||
AST poly9_lookup[i] = (byte) reg;
|
ast _ poly9_lookup[i] = TO_BYTE(reg);
|
||||||
}
|
}
|
||||||
reg = 0x1ffff;
|
reg = 0x1ffff;
|
||||||
for (i = 0; i < 16385; i++) {
|
for (i = 0; i < 16385; i++) {
|
||||||
reg = ((((reg >> 5) ^ reg) & 0xff) << 9) + (reg >> 8);
|
reg = ((((reg >> 5) ^ reg) & 0xff) << 9) + (reg >> 8);
|
||||||
AST poly17_lookup[i] = (byte) (reg >> 1);
|
ast _ poly17_lookup[i] = TO_BYTE(reg >> 1);
|
||||||
}
|
}
|
||||||
AST sample_offset = 0;
|
ast _ sample_offset = 0;
|
||||||
AST sample_index = 0;
|
ast _ sample_index = 0;
|
||||||
AST samples = 0;
|
ast _ samples = 0;
|
||||||
AST iir_acc_left = 0;
|
ast _ iir_acc_left = 0;
|
||||||
AST iir_acc_right = 0;
|
ast _ iir_acc_right = 0;
|
||||||
init_state(ADDRESSOF AST base_pokey);
|
PokeySound_InitializeChip(ADDRESSOF ast _ base_pokey);
|
||||||
init_state(ADDRESSOF AST extra_pokey);
|
PokeySound_InitializeChip(ADDRESSOF ast _ extra_pokey);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CYCLE_TO_SAMPLE(cycle) (((cycle) * ASAP_SAMPLE_RATE + AST sample_offset) / ASAP_MAIN_CLOCK)
|
|
||||||
|
|
||||||
#define DO_TICK(ch) \
|
#define DO_TICK(ch) \
|
||||||
if (PST init) { \
|
if (pst _ init) { \
|
||||||
switch (PST audc##ch >> 4) { \
|
switch (pst _ audc##ch >> 4) { \
|
||||||
case 10: \
|
case 10: \
|
||||||
case 14: \
|
case 14: \
|
||||||
PST out##ch ^= 1; \
|
pst _ out##ch ^= 1; \
|
||||||
PST delta_buffer[CYCLE_TO_SAMPLE(cycle)] += PST delta##ch = -PST delta##ch; \
|
pst _ delta_buffer[CYCLE_TO_SAMPLE(cycle)] += pst _ delta##ch = -pst _ delta##ch; \
|
||||||
break; \
|
break; \
|
||||||
default: \
|
default: \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
int poly = cycle + PST poly_index - (ch - 1); \
|
V(int, poly) = cycle + pst _ poly_index - (ch - 1); \
|
||||||
int newout = PST out##ch; \
|
V(int, newout) = pst _ out##ch; \
|
||||||
switch (PST audc##ch >> 4) { \
|
switch (pst _ audc##ch >> 4) { \
|
||||||
case 0: \
|
case 0: \
|
||||||
if (poly5_lookup[poly % 31] != 0) { \
|
if (poly5_lookup[poly % 31] != 0) { \
|
||||||
if ((PST audctl & 0x80) != 0) \
|
if ((pst _ audctl & 0x80) != 0) \
|
||||||
newout = AST poly9_lookup[poly % 511] & 1; \
|
newout = ast _ poly9_lookup[poly % 511] & 1; \
|
||||||
else { \
|
else { \
|
||||||
poly %= 131071; \
|
poly %= 131071; \
|
||||||
newout = (AST poly17_lookup[poly >> 3] >> (poly & 7)) & 1; \
|
newout = (ast _ poly17_lookup[poly >> 3] >> (poly & 7)) & 1; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
break; \
|
break; \
|
||||||
|
@ -140,11 +135,11 @@ ASAP_FUNC void PokeySound_Initialize(ASAP_State PTR ast)
|
||||||
newout = poly4_lookup[poly % 15]; \
|
newout = poly4_lookup[poly % 15]; \
|
||||||
break; \
|
break; \
|
||||||
case 8: \
|
case 8: \
|
||||||
if ((PST audctl & 0x80) != 0) \
|
if ((pst _ audctl & 0x80) != 0) \
|
||||||
newout = AST poly9_lookup[poly % 511] & 1; \
|
newout = ast _ poly9_lookup[poly % 511] & 1; \
|
||||||
else { \
|
else { \
|
||||||
poly %= 131071; \
|
poly %= 131071; \
|
||||||
newout = (AST poly17_lookup[poly >> 3] >> (poly & 7)) & 1; \
|
newout = (ast _ poly17_lookup[poly >> 3] >> (poly & 7)) & 1; \
|
||||||
} \
|
} \
|
||||||
break; \
|
break; \
|
||||||
case 10: \
|
case 10: \
|
||||||
|
@ -157,125 +152,141 @@ ASAP_FUNC void PokeySound_Initialize(ASAP_State PTR ast)
|
||||||
default: \
|
default: \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
if (newout != PST out##ch) { \
|
if (newout != pst _ out##ch) { \
|
||||||
PST out##ch = newout; \
|
pst _ out##ch = newout; \
|
||||||
PST delta_buffer[CYCLE_TO_SAMPLE(cycle)] += PST delta##ch = -PST delta##ch; \
|
pst _ delta_buffer[CYCLE_TO_SAMPLE(cycle)] += pst _ delta##ch = -pst _ delta##ch; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE_FUNC void generate(ASAP_State PTR ast, PokeyState PTR pst, int current_cycle)
|
/* Fills delta_buffer up to current_cycle basing on current AUDF/AUDC/AUDCTL values. */
|
||||||
|
PRIVATE FUNC(void, PokeySound_GenerateUntilCycle, (P(ASAP_State PTR, ast), P(PokeyState PTR, pst), P(int, current_cycle)))
|
||||||
{
|
{
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int cycle = current_cycle;
|
V(int, cycle) = current_cycle;
|
||||||
if (cycle > PST tick_cycle1)
|
if (cycle > pst _ tick_cycle1)
|
||||||
cycle = PST tick_cycle1;
|
cycle = pst _ tick_cycle1;
|
||||||
if (cycle > PST tick_cycle2)
|
if (cycle > pst _ tick_cycle2)
|
||||||
cycle = PST tick_cycle2;
|
cycle = pst _ tick_cycle2;
|
||||||
if (cycle > PST tick_cycle3)
|
if (cycle > pst _ tick_cycle3)
|
||||||
cycle = PST tick_cycle3;
|
cycle = pst _ tick_cycle3;
|
||||||
if (cycle > PST tick_cycle4)
|
if (cycle > pst _ tick_cycle4)
|
||||||
cycle = PST tick_cycle4;
|
cycle = pst _ tick_cycle4;
|
||||||
if (cycle == current_cycle)
|
if (cycle == current_cycle)
|
||||||
break;
|
break;
|
||||||
if (cycle == PST tick_cycle3) {
|
if (cycle == pst _ tick_cycle3) {
|
||||||
PST tick_cycle3 += PST period_cycles3;
|
pst _ tick_cycle3 += pst _ period_cycles3;
|
||||||
if ((PST audctl & 4) != 0 && PST delta1 > 0 && PST mute1 == 0)
|
if ((pst _ audctl & 4) != 0 && pst _ delta1 > 0 && pst _ mute1 == 0)
|
||||||
PST delta_buffer[CYCLE_TO_SAMPLE(cycle)] += PST delta1 = -PST delta1;
|
pst _ delta_buffer[CYCLE_TO_SAMPLE(cycle)] += pst _ delta1 = -pst _ delta1;
|
||||||
DO_TICK(3);
|
DO_TICK(3);
|
||||||
}
|
}
|
||||||
if (cycle == PST tick_cycle4) {
|
if (cycle == pst _ tick_cycle4) {
|
||||||
PST tick_cycle4 += PST period_cycles4;
|
pst _ tick_cycle4 += pst _ period_cycles4;
|
||||||
if ((PST audctl & 8) != 0)
|
if ((pst _ audctl & 8) != 0)
|
||||||
PST tick_cycle3 = cycle + PST reload_cycles3;
|
pst _ tick_cycle3 = cycle + pst _ reload_cycles3;
|
||||||
if ((PST audctl & 2) != 0 && PST delta2 > 0 && PST mute2 == 0)
|
if ((pst _ audctl & 2) != 0 && pst _ delta2 > 0 && pst _ mute2 == 0)
|
||||||
PST delta_buffer[CYCLE_TO_SAMPLE(cycle)] += PST delta2 = -PST delta2;
|
pst _ delta_buffer[CYCLE_TO_SAMPLE(cycle)] += pst _ delta2 = -pst _ delta2;
|
||||||
DO_TICK(4);
|
DO_TICK(4);
|
||||||
}
|
}
|
||||||
if (cycle == PST tick_cycle1) {
|
if (cycle == pst _ tick_cycle1) {
|
||||||
PST tick_cycle1 += PST period_cycles1;
|
pst _ tick_cycle1 += pst _ period_cycles1;
|
||||||
if ((PST skctl & 0x88) == 8)
|
if ((pst _ skctl & 0x88) == 8) /* two-tone, sending 1 (i.e. timer1) */
|
||||||
PST tick_cycle2 = cycle + PST period_cycles2;
|
pst _ tick_cycle2 = cycle + pst _ period_cycles2;
|
||||||
DO_TICK(1);
|
DO_TICK(1);
|
||||||
}
|
}
|
||||||
if (cycle == PST tick_cycle2) {
|
if (cycle == pst _ tick_cycle2) {
|
||||||
PST tick_cycle2 += PST period_cycles2;
|
pst _ tick_cycle2 += pst _ period_cycles2;
|
||||||
if ((PST audctl & 0x10) != 0)
|
if ((pst _ audctl & 0x10) != 0)
|
||||||
PST tick_cycle1 = cycle + PST reload_cycles1;
|
pst _ tick_cycle1 = cycle + pst _ reload_cycles1;
|
||||||
else if ((PST skctl & 8) != 0)
|
else if ((pst _ skctl & 8) != 0) /* two-tone */
|
||||||
PST tick_cycle1 = cycle + PST period_cycles1;
|
pst _ tick_cycle1 = cycle + pst _ period_cycles1;
|
||||||
DO_TICK(2);
|
DO_TICK(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef APOKEYSND
|
||||||
|
|
||||||
|
#define CURRENT_CYCLE 0
|
||||||
|
#define CURRENT_SAMPLE 0
|
||||||
|
#define DO_STORE(reg) \
|
||||||
|
if (data == pst _ reg) \
|
||||||
|
break; \
|
||||||
|
pst _ reg = data;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define CURRENT_CYCLE ast _ cycle
|
||||||
|
#define CURRENT_SAMPLE CYCLE_TO_SAMPLE(ast _ cycle)
|
||||||
|
#define DO_STORE(reg) \
|
||||||
|
if (data == pst _ reg) \
|
||||||
|
break; \
|
||||||
|
PokeySound_GenerateUntilCycle(ast, pst, ast _ cycle); \
|
||||||
|
pst _ reg = data;
|
||||||
|
|
||||||
|
#endif /* APOKEYSND */
|
||||||
|
|
||||||
#define MUTE_CHANNEL(ch, cond, mask) \
|
#define MUTE_CHANNEL(ch, cond, mask) \
|
||||||
if (cond) { \
|
if (cond) { \
|
||||||
PST mute##ch |= mask; \
|
pst _ mute##ch |= mask; \
|
||||||
PST tick_cycle##ch = NEVER; \
|
pst _ tick_cycle##ch = NEVER; \
|
||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
PST mute##ch &= ~mask; \
|
pst _ mute##ch &= ~mask; \
|
||||||
if (PST tick_cycle##ch == NEVER && PST mute##ch == 0) \
|
if (pst _ tick_cycle##ch == NEVER && pst _ mute##ch == 0) \
|
||||||
PST tick_cycle##ch = AST cycle; \
|
pst _ tick_cycle##ch = CURRENT_CYCLE; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DO_ULTRASOUND(ch) \
|
#define DO_ULTRASOUND(ch) \
|
||||||
MUTE_CHANNEL(ch, PST period_cycles##ch <= ULTRASOUND_CYCLES && (PST audc##ch >> 4 == 10 || PST audc##ch >> 4 == 14), MUTE_FREQUENCY)
|
MUTE_CHANNEL(ch, pst _ period_cycles##ch <= ULTRASOUND_CYCLES && (pst _ audc##ch >> 4 == 10 || pst _ audc##ch >> 4 == 14), MUTE_FREQUENCY)
|
||||||
|
|
||||||
#define DO_AUDC(ch) \
|
#define DO_AUDC(ch) \
|
||||||
if (data == PST audc##ch) \
|
DO_STORE(audc##ch); \
|
||||||
break; \
|
|
||||||
generate(ast, pst, AST cycle); \
|
|
||||||
PST audc##ch = data; \
|
|
||||||
if ((data & 0x10) != 0) { \
|
if ((data & 0x10) != 0) { \
|
||||||
data &= 0xf; \
|
data = (data & 0xf) << DELTA_SHIFT_POKEY; \
|
||||||
if ((PST mute##ch & MUTE_USER) == 0) \
|
if ((pst _ mute##ch & MUTE_USER) == 0) \
|
||||||
PST delta_buffer[CYCLE_TO_SAMPLE(AST cycle)] \
|
pst _ delta_buffer[CURRENT_SAMPLE] \
|
||||||
+= PST delta##ch > 0 ? data - PST delta##ch : data; \
|
+= pst _ delta##ch > 0 ? data - pst _ delta##ch : data; \
|
||||||
PST delta##ch = data; \
|
pst _ delta##ch = data; \
|
||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
data &= 0xf; \
|
data = (data & 0xf) << DELTA_SHIFT_POKEY; \
|
||||||
DO_ULTRASOUND(ch); \
|
DO_ULTRASOUND(ch); \
|
||||||
if (PST delta##ch > 0) { \
|
if (pst _ delta##ch > 0) { \
|
||||||
if ((PST mute##ch & MUTE_USER) == 0) \
|
if ((pst _ mute##ch & MUTE_USER) == 0) \
|
||||||
PST delta_buffer[CYCLE_TO_SAMPLE(AST cycle)] \
|
pst _ delta_buffer[CURRENT_SAMPLE] \
|
||||||
+= data - PST delta##ch; \
|
+= data - pst _ delta##ch; \
|
||||||
PST delta##ch = data; \
|
pst _ delta##ch = data; \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
PST delta##ch = -data; \
|
pst _ delta##ch = -data; \
|
||||||
} \
|
} \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#define DO_INIT(ch, cond) \
|
#define DO_INIT(ch, cond) \
|
||||||
MUTE_CHANNEL(ch, PST init && cond, MUTE_INIT)
|
MUTE_CHANNEL(ch, pst _ init && cond, MUTE_INIT)
|
||||||
|
|
||||||
ASAP_FUNC void PokeySound_PutByte(ASAP_State PTR ast, int addr, int data)
|
FUNC(void, PokeySound_PutByte, (P(ASAP_State PTR, ast), P(int, addr), P(int, data)))
|
||||||
{
|
{
|
||||||
PokeyState PTR pst = (addr & AST extra_pokey_mask) != 0
|
V(PokeyState PTR, pst) = (addr & ast _ extra_pokey_mask) != 0
|
||||||
? ADDRESSOF AST extra_pokey : ADDRESSOF AST base_pokey;
|
? ADDRESSOF ast _ extra_pokey : ADDRESSOF ast _ base_pokey;
|
||||||
switch (addr & 0xf) {
|
switch (addr & 0xf) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
if (data == PST audf1)
|
DO_STORE(audf1);
|
||||||
break;
|
switch (pst _ audctl & 0x50) {
|
||||||
generate(ast, pst, AST cycle);
|
|
||||||
PST audf1 = data;
|
|
||||||
switch (PST audctl & 0x50) {
|
|
||||||
case 0x00:
|
case 0x00:
|
||||||
PST period_cycles1 = PST div_cycles * (data + 1);
|
pst _ period_cycles1 = pst _ div_cycles * (data + 1);
|
||||||
break;
|
break;
|
||||||
case 0x10:
|
case 0x10:
|
||||||
PST period_cycles2 = PST div_cycles * (data + 256 * PST audf2 + 1);
|
pst _ period_cycles2 = pst _ div_cycles * (data + 256 * pst _ audf2 + 1);
|
||||||
PST reload_cycles1 = PST div_cycles * (data + 1);
|
pst _ reload_cycles1 = pst _ div_cycles * (data + 1);
|
||||||
DO_ULTRASOUND(2);
|
DO_ULTRASOUND(2);
|
||||||
break;
|
break;
|
||||||
case 0x40:
|
case 0x40:
|
||||||
PST period_cycles1 = data + 4;
|
pst _ period_cycles1 = data + 4;
|
||||||
break;
|
break;
|
||||||
case 0x50:
|
case 0x50:
|
||||||
PST period_cycles2 = data + 256 * PST audf2 + 7;
|
pst _ period_cycles2 = data + 256 * pst _ audf2 + 7;
|
||||||
PST reload_cycles1 = data + 4;
|
pst _ reload_cycles1 = data + 4;
|
||||||
DO_ULTRASOUND(2);
|
DO_ULTRASOUND(2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -284,20 +295,17 @@ ASAP_FUNC void PokeySound_PutByte(ASAP_State PTR ast, int addr, int data)
|
||||||
case 0x01:
|
case 0x01:
|
||||||
DO_AUDC(1)
|
DO_AUDC(1)
|
||||||
case 0x02:
|
case 0x02:
|
||||||
if (data == PST audf2)
|
DO_STORE(audf2);
|
||||||
break;
|
switch (pst _ audctl & 0x50) {
|
||||||
generate(ast, pst, AST cycle);
|
|
||||||
PST audf2 = data;
|
|
||||||
switch (PST audctl & 0x50) {
|
|
||||||
case 0x00:
|
case 0x00:
|
||||||
case 0x40:
|
case 0x40:
|
||||||
PST period_cycles2 = PST div_cycles * (data + 1);
|
pst _ period_cycles2 = pst _ div_cycles * (data + 1);
|
||||||
break;
|
break;
|
||||||
case 0x10:
|
case 0x10:
|
||||||
PST period_cycles2 = PST div_cycles * (PST audf1 + 256 * data + 1);
|
pst _ period_cycles2 = pst _ div_cycles * (pst _ audf1 + 256 * data + 1);
|
||||||
break;
|
break;
|
||||||
case 0x50:
|
case 0x50:
|
||||||
PST period_cycles2 = PST audf1 + 256 * data + 7;
|
pst _ period_cycles2 = pst _ audf1 + 256 * data + 7;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DO_ULTRASOUND(2);
|
DO_ULTRASOUND(2);
|
||||||
|
@ -305,25 +313,22 @@ ASAP_FUNC void PokeySound_PutByte(ASAP_State PTR ast, int addr, int data)
|
||||||
case 0x03:
|
case 0x03:
|
||||||
DO_AUDC(2)
|
DO_AUDC(2)
|
||||||
case 0x04:
|
case 0x04:
|
||||||
if (data == PST audf3)
|
DO_STORE(audf3);
|
||||||
break;
|
switch (pst _ audctl & 0x28) {
|
||||||
generate(ast, pst, AST cycle);
|
|
||||||
PST audf3 = data;
|
|
||||||
switch (PST audctl & 0x28) {
|
|
||||||
case 0x00:
|
case 0x00:
|
||||||
PST period_cycles3 = PST div_cycles * (data + 1);
|
pst _ period_cycles3 = pst _ div_cycles * (data + 1);
|
||||||
break;
|
break;
|
||||||
case 0x08:
|
case 0x08:
|
||||||
PST period_cycles4 = PST div_cycles * (data + 256 * PST audf4 + 1);
|
pst _ period_cycles4 = pst _ div_cycles * (data + 256 * pst _ audf4 + 1);
|
||||||
PST reload_cycles3 = PST div_cycles * (data + 1);
|
pst _ reload_cycles3 = pst _ div_cycles * (data + 1);
|
||||||
DO_ULTRASOUND(4);
|
DO_ULTRASOUND(4);
|
||||||
break;
|
break;
|
||||||
case 0x20:
|
case 0x20:
|
||||||
PST period_cycles3 = data + 4;
|
pst _ period_cycles3 = data + 4;
|
||||||
break;
|
break;
|
||||||
case 0x28:
|
case 0x28:
|
||||||
PST period_cycles4 = data + 256 * PST audf4 + 7;
|
pst _ period_cycles4 = data + 256 * pst _ audf4 + 7;
|
||||||
PST reload_cycles3 = data + 4;
|
pst _ reload_cycles3 = data + 4;
|
||||||
DO_ULTRASOUND(4);
|
DO_ULTRASOUND(4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -332,20 +337,17 @@ ASAP_FUNC void PokeySound_PutByte(ASAP_State PTR ast, int addr, int data)
|
||||||
case 0x05:
|
case 0x05:
|
||||||
DO_AUDC(3)
|
DO_AUDC(3)
|
||||||
case 0x06:
|
case 0x06:
|
||||||
if (data == PST audf4)
|
DO_STORE(audf4);
|
||||||
break;
|
switch (pst _ audctl & 0x28) {
|
||||||
generate(ast, pst, AST cycle);
|
|
||||||
PST audf4 = data;
|
|
||||||
switch (PST audctl & 0x28) {
|
|
||||||
case 0x00:
|
case 0x00:
|
||||||
case 0x20:
|
case 0x20:
|
||||||
PST period_cycles4 = PST div_cycles * (data + 1);
|
pst _ period_cycles4 = pst _ div_cycles * (data + 1);
|
||||||
break;
|
break;
|
||||||
case 0x08:
|
case 0x08:
|
||||||
PST period_cycles4 = PST div_cycles * (PST audf3 + 256 * data + 1);
|
pst _ period_cycles4 = pst _ div_cycles * (pst _ audf3 + 256 * data + 1);
|
||||||
break;
|
break;
|
||||||
case 0x28:
|
case 0x28:
|
||||||
PST period_cycles4 = PST audf3 + 256 * data + 7;
|
pst _ period_cycles4 = pst _ audf3 + 256 * data + 7;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DO_ULTRASOUND(4);
|
DO_ULTRASOUND(4);
|
||||||
|
@ -353,141 +355,153 @@ ASAP_FUNC void PokeySound_PutByte(ASAP_State PTR ast, int addr, int data)
|
||||||
case 0x07:
|
case 0x07:
|
||||||
DO_AUDC(4)
|
DO_AUDC(4)
|
||||||
case 0x08:
|
case 0x08:
|
||||||
if (data == PST audctl)
|
DO_STORE(audctl);
|
||||||
break;
|
pst _ div_cycles = ((data & 1) != 0) ? 114 : 28;
|
||||||
generate(ast, pst, AST cycle);
|
|
||||||
PST audctl = data;
|
|
||||||
PST div_cycles = ((data & 1) != 0) ? 114 : 28;
|
|
||||||
/* TODO: tick_cycles */
|
/* TODO: tick_cycles */
|
||||||
switch (data & 0x50) {
|
switch (data & 0x50) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
PST period_cycles1 = PST div_cycles * (PST audf1 + 1);
|
pst _ period_cycles1 = pst _ div_cycles * (pst _ audf1 + 1);
|
||||||
PST period_cycles2 = PST div_cycles * (PST audf2 + 1);
|
pst _ period_cycles2 = pst _ div_cycles * (pst _ audf2 + 1);
|
||||||
break;
|
break;
|
||||||
case 0x10:
|
case 0x10:
|
||||||
PST period_cycles1 = PST div_cycles * 256;
|
pst _ period_cycles1 = pst _ div_cycles * 256;
|
||||||
PST period_cycles2 = PST div_cycles * (PST audf1 + 256 * PST audf2 + 1);
|
pst _ period_cycles2 = pst _ div_cycles * (pst _ audf1 + 256 * pst _ audf2 + 1);
|
||||||
PST reload_cycles1 = PST div_cycles * (PST audf1 + 1);
|
pst _ reload_cycles1 = pst _ div_cycles * (pst _ audf1 + 1);
|
||||||
break;
|
break;
|
||||||
case 0x40:
|
case 0x40:
|
||||||
PST period_cycles1 = PST audf1 + 4;
|
pst _ period_cycles1 = pst _ audf1 + 4;
|
||||||
PST period_cycles2 = PST div_cycles * (PST audf2 + 1);
|
pst _ period_cycles2 = pst _ div_cycles * (pst _ audf2 + 1);
|
||||||
break;
|
break;
|
||||||
case 0x50:
|
case 0x50:
|
||||||
PST period_cycles1 = 256;
|
pst _ period_cycles1 = 256;
|
||||||
PST period_cycles2 = PST audf1 + 256 * PST audf2 + 7;
|
pst _ period_cycles2 = pst _ audf1 + 256 * pst _ audf2 + 7;
|
||||||
PST reload_cycles1 = PST audf1 + 4;
|
pst _ reload_cycles1 = pst _ audf1 + 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DO_ULTRASOUND(1);
|
DO_ULTRASOUND(1);
|
||||||
DO_ULTRASOUND(2);
|
DO_ULTRASOUND(2);
|
||||||
switch (data & 0x28) {
|
switch (data & 0x28) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
PST period_cycles3 = PST div_cycles * (PST audf3 + 1);
|
pst _ period_cycles3 = pst _ div_cycles * (pst _ audf3 + 1);
|
||||||
PST period_cycles4 = PST div_cycles * (PST audf4 + 1);
|
pst _ period_cycles4 = pst _ div_cycles * (pst _ audf4 + 1);
|
||||||
break;
|
break;
|
||||||
case 0x08:
|
case 0x08:
|
||||||
PST period_cycles3 = PST div_cycles * 256;
|
pst _ period_cycles3 = pst _ div_cycles * 256;
|
||||||
PST period_cycles4 = PST div_cycles * (PST audf3 + 256 * PST audf4 + 1);
|
pst _ period_cycles4 = pst _ div_cycles * (pst _ audf3 + 256 * pst _ audf4 + 1);
|
||||||
PST reload_cycles3 = PST div_cycles * (PST audf3 + 1);
|
pst _ reload_cycles3 = pst _ div_cycles * (pst _ audf3 + 1);
|
||||||
break;
|
break;
|
||||||
case 0x20:
|
case 0x20:
|
||||||
PST period_cycles3 = PST audf3 + 4;
|
pst _ period_cycles3 = pst _ audf3 + 4;
|
||||||
PST period_cycles4 = PST div_cycles * (PST audf4 + 1);
|
pst _ period_cycles4 = pst _ div_cycles * (pst _ audf4 + 1);
|
||||||
break;
|
break;
|
||||||
case 0x28:
|
case 0x28:
|
||||||
PST period_cycles3 = 256;
|
pst _ period_cycles3 = 256;
|
||||||
PST period_cycles4 = PST audf3 + 256 * PST audf4 + 7;
|
pst _ period_cycles4 = pst _ audf3 + 256 * pst _ audf4 + 7;
|
||||||
PST reload_cycles3 = PST audf3 + 4;
|
pst _ reload_cycles3 = pst _ audf3 + 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DO_ULTRASOUND(3);
|
DO_ULTRASOUND(3);
|
||||||
DO_ULTRASOUND(4);
|
DO_ULTRASOUND(4);
|
||||||
|
DO_INIT(1, (data & 0x40) == 0);
|
||||||
|
DO_INIT(2, (data & 0x50) != 0x50);
|
||||||
|
DO_INIT(3, (data & 0x20) == 0);
|
||||||
|
DO_INIT(4, (data & 0x28) != 0x28);
|
||||||
break;
|
break;
|
||||||
case 0x09:
|
case 0x09:
|
||||||
/* TODO: STIMER */
|
/* TODO: STIMER */
|
||||||
break;
|
break;
|
||||||
case 0x0f:
|
case 0x0f:
|
||||||
PST skctl = data;
|
DO_STORE(skctl);
|
||||||
PST init = ((data & 3) == 0);
|
pst _ init = ((data & 3) == 0);
|
||||||
DO_INIT(1, (PST audctl & 0x40) == 0);
|
DO_INIT(1, (pst _ audctl & 0x40) == 0);
|
||||||
DO_INIT(2, (PST audctl & 0x50) != 0x50);
|
DO_INIT(2, (pst _ audctl & 0x50) != 0x50);
|
||||||
DO_INIT(3, (PST audctl & 0x20) == 0);
|
DO_INIT(3, (pst _ audctl & 0x20) == 0);
|
||||||
DO_INIT(4, (PST audctl & 0x28) != 0x28);
|
DO_INIT(4, (pst _ audctl & 0x28) != 0x28);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASAP_FUNC int PokeySound_GetRandom(ASAP_State PTR ast, int addr)
|
FUNC(int, PokeySound_GetRandom, (P(ASAP_State PTR, ast), P(int, addr), P(int, cycle)))
|
||||||
{
|
{
|
||||||
PokeyState PTR pst = (addr & AST extra_pokey_mask) != 0
|
V(PokeyState PTR, pst) = (addr & ast _ extra_pokey_mask) != 0
|
||||||
? ADDRESSOF AST extra_pokey : ADDRESSOF AST base_pokey;
|
? ADDRESSOF ast _ extra_pokey : ADDRESSOF ast _ base_pokey;
|
||||||
int i;
|
V(int, i);
|
||||||
if (PST init)
|
if (pst _ init)
|
||||||
return 0xff;
|
return 0xff;
|
||||||
i = AST cycle + PST poly_index;
|
i = cycle + pst _ poly_index;
|
||||||
if ((PST audctl & 0x80) != 0)
|
if ((pst _ audctl & 0x80) != 0)
|
||||||
return AST poly9_lookup[i % 511];
|
return ast _ poly9_lookup[i % 511];
|
||||||
else {
|
else {
|
||||||
int j;
|
V(int, j);
|
||||||
i %= 131071;
|
i %= 131071;
|
||||||
j = i >> 3;
|
j = i >> 3;
|
||||||
i &= 7;
|
i &= 7;
|
||||||
return ((AST poly17_lookup[j] >> i) + (AST poly17_lookup[j + 1] << (8 - i))) & 0xff;
|
return ((ast _ poly17_lookup[j] >> i) + (ast _ poly17_lookup[j + 1] << (8 - i))) & 0xff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE_FUNC void end_frame(ASAP_State PTR ast, PokeyState PTR pst, int cycle_limit)
|
PRIVATE FUNC(void, end_frame, (P(ASAP_State PTR, ast), P(PokeyState PTR, pst), P(int, cycle_limit)))
|
||||||
{
|
{
|
||||||
int m;
|
V(int, m);
|
||||||
generate(ast, pst, cycle_limit);
|
PokeySound_GenerateUntilCycle(ast, pst, cycle_limit);
|
||||||
PST poly_index += cycle_limit;
|
pst _ poly_index += cycle_limit;
|
||||||
m = ((PST audctl & 0x80) != 0) ? 15 * 31 * 511 : 15 * 31 * 131071;
|
m = ((pst _ audctl & 0x80) != 0) ? 15 * 31 * 511 : 15 * 31 * 131071;
|
||||||
if (PST poly_index >= 2 * m)
|
if (pst _ poly_index >= 2 * m)
|
||||||
PST poly_index -= m;
|
pst _ poly_index -= m;
|
||||||
if (PST tick_cycle1 != NEVER)
|
if (pst _ tick_cycle1 != NEVER)
|
||||||
PST tick_cycle1 -= cycle_limit;
|
pst _ tick_cycle1 -= cycle_limit;
|
||||||
if (PST tick_cycle2 != NEVER)
|
if (pst _ tick_cycle2 != NEVER)
|
||||||
PST tick_cycle2 -= cycle_limit;
|
pst _ tick_cycle2 -= cycle_limit;
|
||||||
if (PST tick_cycle3 != NEVER)
|
if (pst _ tick_cycle3 != NEVER)
|
||||||
PST tick_cycle3 -= cycle_limit;
|
pst _ tick_cycle3 -= cycle_limit;
|
||||||
if (PST tick_cycle4 != NEVER)
|
if (pst _ tick_cycle4 != NEVER)
|
||||||
PST tick_cycle4 -= cycle_limit;
|
pst _ tick_cycle4 -= cycle_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASAP_FUNC void PokeySound_StartFrame(ASAP_State PTR ast)
|
FUNC(void, PokeySound_StartFrame, (P(ASAP_State PTR, ast)))
|
||||||
{
|
{
|
||||||
ZERO_ARRAY(AST base_pokey.delta_buffer);
|
ZERO_ARRAY(ast _ base_pokey.delta_buffer);
|
||||||
if (AST extra_pokey_mask != 0)
|
if (ast _ extra_pokey_mask != 0)
|
||||||
ZERO_ARRAY(AST extra_pokey.delta_buffer);
|
ZERO_ARRAY(ast _ extra_pokey.delta_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASAP_FUNC void PokeySound_EndFrame(ASAP_State PTR ast, int current_cycle)
|
FUNC(void, PokeySound_EndFrame, (P(ASAP_State PTR, ast), P(int, current_cycle)))
|
||||||
{
|
{
|
||||||
end_frame(ast, ADDRESSOF AST base_pokey, current_cycle);
|
end_frame(ast, ADDRESSOF ast _ base_pokey, current_cycle);
|
||||||
if (AST extra_pokey_mask != 0)
|
if (ast _ extra_pokey_mask != 0)
|
||||||
end_frame(ast, ADDRESSOF AST extra_pokey, current_cycle);
|
end_frame(ast, ADDRESSOF ast _ extra_pokey, current_cycle);
|
||||||
AST sample_offset += current_cycle * ASAP_SAMPLE_RATE;
|
ast _ sample_offset += current_cycle * ASAP_SAMPLE_RATE;
|
||||||
AST sample_index = 0;
|
ast _ sample_index = 0;
|
||||||
AST samples = AST sample_offset / ASAP_MAIN_CLOCK;
|
ast _ samples = TO_INT(ast _ sample_offset / ASAP_MAIN_CLOCK);
|
||||||
AST sample_offset %= ASAP_MAIN_CLOCK;
|
ast _ sample_offset %= ASAP_MAIN_CLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASAP_FUNC int PokeySound_Generate(ASAP_State PTR ast, byte ARRAY buffer, int buffer_offset, int blocks, ASAP_SampleFormat format)
|
/* Fills buffer with samples from delta_buffer. */
|
||||||
|
FUNC(int, PokeySound_Generate, (P(ASAP_State PTR, ast), P(BYTEARRAY, buffer), P(int, buffer_offset), P(int, blocks), P(ASAP_SampleFormat, format)))
|
||||||
{
|
{
|
||||||
int i = AST sample_index;
|
V(int, i) = ast _ sample_index;
|
||||||
int samples = AST samples;
|
V(int, samples) = ast _ samples;
|
||||||
int acc_left = AST iir_acc_left;
|
V(int, acc_left) = ast _ iir_acc_left;
|
||||||
int acc_right = AST iir_acc_right;
|
V(int, acc_right) = ast _ iir_acc_right;
|
||||||
if (blocks < samples - i)
|
if (blocks < samples - i)
|
||||||
samples = i + blocks;
|
samples = i + blocks;
|
||||||
else
|
else
|
||||||
blocks = samples - i;
|
blocks = samples - i;
|
||||||
for (; i < samples; i++) {
|
for (; i < samples; i++) {
|
||||||
int sample;
|
#ifdef ACTIONSCRIPT
|
||||||
acc_left += (AST base_pokey.delta_buffer[i] << 20) - (acc_left * 3 >> 10);
|
acc_left += ast _ base_pokey.delta_buffer[i] - (acc_left * 3 >> 10);
|
||||||
|
var sample : Number = acc_left / 33553408;
|
||||||
|
buffer.writeFloat(sample);
|
||||||
|
if (ast.extra_pokey_mask != 0) {
|
||||||
|
acc_right += ast _ extra_pokey.delta_buffer[i] - (acc_right * 3 >> 10);
|
||||||
|
sample = acc_right / 33553408;
|
||||||
|
}
|
||||||
|
buffer.writeFloat(sample);
|
||||||
|
#else
|
||||||
|
V(int, sample);
|
||||||
|
acc_left += ast _ base_pokey.delta_buffer[i] - (acc_left * 3 >> 10);
|
||||||
sample = acc_left >> 10;
|
sample = acc_left >> 10;
|
||||||
#define STORE_SAMPLE \
|
#define STORE_SAMPLE \
|
||||||
if (sample < -32767) \
|
if (sample < -32767) \
|
||||||
|
@ -496,43 +510,89 @@ ASAP_FUNC int PokeySound_Generate(ASAP_State PTR ast, byte ARRAY buffer, int buf
|
||||||
sample = 32767; \
|
sample = 32767; \
|
||||||
switch (format) { \
|
switch (format) { \
|
||||||
case ASAP_FORMAT_U8: \
|
case ASAP_FORMAT_U8: \
|
||||||
buffer[buffer_offset++] = (byte) ((sample >> 8) + 128); \
|
buffer[buffer_offset++] = CAST(byte) ((sample >> 8) + 128); \
|
||||||
break; \
|
break; \
|
||||||
case ASAP_FORMAT_S16_LE: \
|
case ASAP_FORMAT_S16_LE: \
|
||||||
buffer[buffer_offset++] = (byte) sample; \
|
buffer[buffer_offset++] = TO_BYTE(sample); \
|
||||||
buffer[buffer_offset++] = (byte) (sample >> 8); \
|
buffer[buffer_offset++] = TO_BYTE(sample >> 8); \
|
||||||
break; \
|
break; \
|
||||||
case ASAP_FORMAT_S16_BE: \
|
case ASAP_FORMAT_S16_BE: \
|
||||||
buffer[buffer_offset++] = (byte) (sample >> 8); \
|
buffer[buffer_offset++] = TO_BYTE(sample >> 8); \
|
||||||
buffer[buffer_offset++] = (byte) sample; \
|
buffer[buffer_offset++] = TO_BYTE(sample); \
|
||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
STORE_SAMPLE;
|
STORE_SAMPLE;
|
||||||
if (AST extra_pokey_mask != 0) {
|
if (ast _ extra_pokey_mask != 0) {
|
||||||
acc_right += (AST extra_pokey.delta_buffer[i] << 20) - (acc_right * 3 >> 10);
|
acc_right += ast _ extra_pokey.delta_buffer[i] - (acc_right * 3 >> 10);
|
||||||
sample = acc_right >> 10;
|
sample = acc_right >> 10;
|
||||||
STORE_SAMPLE;
|
STORE_SAMPLE;
|
||||||
}
|
}
|
||||||
|
#endif /* ACTIONSCRIPT */
|
||||||
}
|
}
|
||||||
if (i == AST samples) {
|
if (i == ast _ samples) {
|
||||||
acc_left += AST base_pokey.delta_buffer[i] << 20;
|
acc_left += ast _ base_pokey.delta_buffer[i];
|
||||||
acc_right += AST extra_pokey.delta_buffer[i] << 20;
|
acc_right += ast _ extra_pokey.delta_buffer[i];
|
||||||
}
|
}
|
||||||
AST sample_index = i;
|
ast _ sample_index = i;
|
||||||
AST iir_acc_left = acc_left;
|
ast _ iir_acc_left = acc_left;
|
||||||
AST iir_acc_right = acc_right;
|
ast _ iir_acc_right = acc_right;
|
||||||
|
#ifdef APOKEYSND
|
||||||
|
return buffer_offset;
|
||||||
|
#else
|
||||||
return blocks;
|
return blocks;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ASAP_FUNC abool PokeySound_IsSilent(const PokeyState PTR pst)
|
FUNC(abool, PokeySound_IsSilent, (P(CONST PokeyState PTR, pst)))
|
||||||
{
|
{
|
||||||
return ((PST audc1 | PST audc2 | PST audc3 | PST audc4) & 0xf) == 0;
|
return ((pst _ audc1 | pst _ audc2 | pst _ audc3 | pst _ audc4) & 0xf) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASAP_FUNC void PokeySound_Mute(const ASAP_State PTR ast, PokeyState PTR pst, int mask)
|
FUNC(void, PokeySound_Mute, (P(CONST ASAP_State PTR, ast), P(PokeyState PTR, pst), P(int, mask)))
|
||||||
{
|
{
|
||||||
MUTE_CHANNEL(1, (mask & 1) != 0, MUTE_USER);
|
MUTE_CHANNEL(1, (mask & 1) != 0, MUTE_USER);
|
||||||
MUTE_CHANNEL(2, (mask & 2) != 0, MUTE_USER);
|
MUTE_CHANNEL(2, (mask & 2) != 0, MUTE_USER);
|
||||||
MUTE_CHANNEL(3, (mask & 4) != 0, MUTE_USER);
|
MUTE_CHANNEL(3, (mask & 4) != 0, MUTE_USER);
|
||||||
MUTE_CHANNEL(4, (mask & 8) != 0, MUTE_USER);
|
MUTE_CHANNEL(4, (mask & 8) != 0, MUTE_USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef APOKEYSND
|
||||||
|
|
||||||
|
static ASAP_State asap;
|
||||||
|
|
||||||
|
__declspec(dllexport) void APokeySound_Initialize(abool stereo)
|
||||||
|
{
|
||||||
|
asap.extra_pokey_mask = stereo ? 0x10 : 0;
|
||||||
|
PokeySound_Initialize(&asap);
|
||||||
|
PokeySound_Mute(&asap, &asap.base_pokey, 0);
|
||||||
|
PokeySound_Mute(&asap, &asap.extra_pokey, 0);
|
||||||
|
PokeySound_StartFrame(&asap);
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) void APokeySound_PutByte(int addr, int data)
|
||||||
|
{
|
||||||
|
PokeySound_PutByte(&asap, addr, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) int APokeySound_GetRandom(int addr, int cycle)
|
||||||
|
{
|
||||||
|
return PokeySound_GetRandom(&asap, addr, cycle);
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) int APokeySound_Generate(int cycles, byte buffer[], ASAP_SampleFormat format)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
PokeySound_EndFrame(&asap, cycles);
|
||||||
|
len = PokeySound_Generate(&asap, buffer, 0, asap.samples, format);
|
||||||
|
PokeySound_StartFrame(&asap);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) void APokeySound_About(const char **name, const char **author, const char **description)
|
||||||
|
{
|
||||||
|
*name = "Another POKEY sound emulator, v" ASAP_VERSION;
|
||||||
|
*author = "Piotr Fusik, (C) " ASAP_YEARS;
|
||||||
|
*description = "Part of ASAP, http://asap.sourceforge.net";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* APOKEYSND */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* asap.h - public interface of the ASAP engine
|
* asap.h - public interface of ASAP
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005-2008 Piotr Fusik
|
* Copyright (C) 2005-2010 Piotr Fusik
|
||||||
*
|
*
|
||||||
* This file is part of ASAP (Another Slight Atari Player),
|
* This file is part of ASAP (Another Slight Atari Player),
|
||||||
* see http://asap.sourceforge.net
|
* see http://asap.sourceforge.net
|
||||||
|
@ -29,17 +29,19 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ASAP version. */
|
/* ASAP version. */
|
||||||
#define ASAP_VERSION_MAJOR 1
|
#define ASAP_VERSION_MAJOR 2
|
||||||
#define ASAP_VERSION_MINOR 2
|
#define ASAP_VERSION_MINOR 1
|
||||||
#define ASAP_VERSION_MICRO 0
|
#define ASAP_VERSION_MICRO 0
|
||||||
#define ASAP_VERSION "1.2.0"
|
#define ASAP_VERSION "2.1.0"
|
||||||
|
|
||||||
/* Short credits of the ASAP engine. */
|
/* Short credits of the ASAP engine. */
|
||||||
#define ASAP_YEARS "2005-2008"
|
#define ASAP_YEARS "2005-2010"
|
||||||
#define ASAP_CREDITS \
|
#define ASAP_CREDITS \
|
||||||
"Another Slight Atari Player (C) 2005-2008 Piotr Fusik\n" \
|
"Another Slight Atari Player (C) 2005-2010 Piotr Fusik\n" \
|
||||||
"CMC, MPT, TMC players (C) 1994-2005 Marcin Lewandowski\n" \
|
"CMC, MPT, TMC, TM2 players (C) 1994-2005 Marcin Lewandowski\n" \
|
||||||
"RMT player (C) 2002-2005 Radek Sterba\n"
|
"RMT player (C) 2002-2005 Radek Sterba\n" \
|
||||||
|
"DLT player (C) 2009 Marek Konopka\n" \
|
||||||
|
"CMS player (C) 1999 David Spilka\n"
|
||||||
|
|
||||||
/* Short GPL notice.
|
/* Short GPL notice.
|
||||||
Display after the credits. */
|
Display after the credits. */
|
||||||
|
@ -49,6 +51,32 @@ extern "C" {
|
||||||
"by the Free Software Foundation; either version 2 of the License,\n" \
|
"by the Free Software Foundation; either version 2 of the License,\n" \
|
||||||
"or (at your option) any later version."
|
"or (at your option) any later version."
|
||||||
|
|
||||||
|
/* Maximum length of AUTHOR, NAME and DATE tags including the terminator. */
|
||||||
|
#define ASAP_INFO_CHARS 128
|
||||||
|
|
||||||
|
/* Maximum length of a "mm:ss.xxx" string including the terminator. */
|
||||||
|
#define ASAP_DURATION_CHARS 10
|
||||||
|
|
||||||
|
/* Maximum length of a supported input file.
|
||||||
|
You can assume that files longer than this are not supported by ASAP. */
|
||||||
|
#define ASAP_MODULE_MAX 65000
|
||||||
|
|
||||||
|
/* Maximum number of songs in a file. */
|
||||||
|
#define ASAP_SONGS_MAX 32
|
||||||
|
|
||||||
|
/* Output sample rate. */
|
||||||
|
#define ASAP_SAMPLE_RATE 44100
|
||||||
|
|
||||||
|
/* WAV file header length. */
|
||||||
|
#define ASAP_WAV_HEADER_BYTES 44
|
||||||
|
|
||||||
|
/* Output formats. */
|
||||||
|
typedef enum {
|
||||||
|
ASAP_FORMAT_U8 = 8, /* unsigned char */
|
||||||
|
ASAP_FORMAT_S16_LE = 16, /* signed short, little-endian */
|
||||||
|
ASAP_FORMAT_S16_BE = -16 /* signed short, big-endian */
|
||||||
|
} ASAP_SampleFormat;
|
||||||
|
|
||||||
/* Useful type definitions. */
|
/* Useful type definitions. */
|
||||||
#ifndef FALSE
|
#ifndef FALSE
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
|
@ -59,24 +87,25 @@ extern "C" {
|
||||||
typedef int abool;
|
typedef int abool;
|
||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
|
|
||||||
/* Information about a file. */
|
/* Information about a music file. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char author[128]; /* author's name */
|
char author[ASAP_INFO_CHARS]; /* author's name */
|
||||||
char name[128]; /* title */
|
char name[ASAP_INFO_CHARS]; /* title */
|
||||||
char date[128]; /* creation date */
|
char date[ASAP_INFO_CHARS]; /* creation date */
|
||||||
int channels; /* 1 for mono or 2 for stereo */
|
int channels; /* 1 for mono or 2 for stereo */
|
||||||
int songs; /* number of subsongs */
|
int songs; /* number of subsongs */
|
||||||
int default_song; /* 0-based index of the "main" subsong */
|
int default_song; /* 0-based index of the "main" subsong */
|
||||||
int durations[32]; /* lengths of songs, in milliseconds, -1 = unspecified */
|
int durations[ASAP_SONGS_MAX]; /* lengths of songs, in milliseconds, -1 = indeterminate */
|
||||||
abool loops[32]; /* whether songs repeat or not */
|
abool loops[ASAP_SONGS_MAX]; /* whether songs repeat or not */
|
||||||
/* the following technical information should not be used outside ASAP. */
|
/* the following technical information should not be used outside ASAP. */
|
||||||
char type;
|
int type;
|
||||||
int fastplay;
|
int fastplay;
|
||||||
int music;
|
int music;
|
||||||
int init;
|
int init;
|
||||||
int player;
|
int player;
|
||||||
|
int covox_addr;
|
||||||
int header_len;
|
int header_len;
|
||||||
byte song_pos[128];
|
byte song_pos[ASAP_SONGS_MAX];
|
||||||
} ASAP_ModuleInfo;
|
} ASAP_ModuleInfo;
|
||||||
|
|
||||||
/* POKEY state.
|
/* POKEY state.
|
||||||
|
@ -117,7 +146,7 @@ typedef struct {
|
||||||
int delta3;
|
int delta3;
|
||||||
int delta4;
|
int delta4;
|
||||||
int skctl;
|
int skctl;
|
||||||
signed char delta_buffer[888];
|
int delta_buffer[888];
|
||||||
} PokeyState;
|
} PokeyState;
|
||||||
|
|
||||||
/* Player state.
|
/* Player state.
|
||||||
|
@ -140,6 +169,8 @@ typedef struct {
|
||||||
int timer4_cycle;
|
int timer4_cycle;
|
||||||
int irqst;
|
int irqst;
|
||||||
int extra_pokey_mask;
|
int extra_pokey_mask;
|
||||||
|
int consol;
|
||||||
|
byte covox[4];
|
||||||
PokeyState base_pokey;
|
PokeyState base_pokey;
|
||||||
PokeyState extra_pokey;
|
PokeyState extra_pokey;
|
||||||
int sample_offset;
|
int sample_offset;
|
||||||
|
@ -160,23 +191,6 @@ typedef struct {
|
||||||
byte memory[65536];
|
byte memory[65536];
|
||||||
} ASAP_State;
|
} ASAP_State;
|
||||||
|
|
||||||
/* Maximum length of a "mm:ss.xxx" string including the terminator. */
|
|
||||||
#define ASAP_DURATION_CHARS 10
|
|
||||||
|
|
||||||
/* Maximum length of a supported input file.
|
|
||||||
You can assume that files longer than this are not supported by ASAP. */
|
|
||||||
#define ASAP_MODULE_MAX 65000
|
|
||||||
|
|
||||||
/* Output sample rate. */
|
|
||||||
#define ASAP_SAMPLE_RATE 44100
|
|
||||||
|
|
||||||
/* Output formats. */
|
|
||||||
typedef enum {
|
|
||||||
ASAP_FORMAT_U8 = 8, /* unsigned char */
|
|
||||||
ASAP_FORMAT_S16_LE = 16, /* signed short, little-endian */
|
|
||||||
ASAP_FORMAT_S16_BE = -16 /* signed short, big-endian */
|
|
||||||
} ASAP_SampleFormat;
|
|
||||||
|
|
||||||
/* Parses the string in the "mm:ss.xxx" format
|
/* Parses the string in the "mm:ss.xxx" format
|
||||||
and returns the number of milliseconds or -1 if an error occurs. */
|
and returns the number of milliseconds or -1 if an error occurs. */
|
||||||
int ASAP_ParseDuration(const char *s);
|
int ASAP_ParseDuration(const char *s);
|
||||||
|
@ -203,7 +217,7 @@ abool ASAP_GetModuleInfo(ASAP_ModuleInfo *module_info, const char *filename,
|
||||||
const byte module[], int module_len);
|
const byte module[], int module_len);
|
||||||
|
|
||||||
/* Loads music data.
|
/* Loads music data.
|
||||||
"as" is the destination structure.
|
"ast" is the destination structure.
|
||||||
"filename" determines file format.
|
"filename" determines file format.
|
||||||
"module" is the music data (contents of the file).
|
"module" is the music data (contents of the file).
|
||||||
"module_len" is the number of data bytes.
|
"module_len" is the number of data bytes.
|
||||||
|
@ -212,39 +226,50 @@ abool ASAP_GetModuleInfo(ASAP_ModuleInfo *module_info, const char *filename,
|
||||||
ASAP_Load() returns true on success.
|
ASAP_Load() returns true on success.
|
||||||
If false is returned, the structure is invalid and you cannot
|
If false is returned, the structure is invalid and you cannot
|
||||||
call the following functions. */
|
call the following functions. */
|
||||||
abool ASAP_Load(ASAP_State *as, const char *filename,
|
abool ASAP_Load(ASAP_State *ast, const char *filename,
|
||||||
const byte module[], int module_len);
|
const byte module[], int module_len);
|
||||||
|
|
||||||
/* Enables silence detection.
|
/* Enables silence detection.
|
||||||
Makes ASAP finish playing after the specified period of silence.
|
Makes ASAP finish playing after the specified period of silence.
|
||||||
"as" is ASAP state initialized by ASAP_Load().
|
"ast" is ASAP state initialized by ASAP_Load().
|
||||||
"seconds" is the minimum length of silence that ends playback. */
|
"seconds" is the minimum length of silence that ends playback. */
|
||||||
void ASAP_DetectSilence(ASAP_State *as, int seconds);
|
void ASAP_DetectSilence(ASAP_State *ast, int seconds);
|
||||||
|
|
||||||
/* Prepares ASAP to play the specified song of the loaded module.
|
/* Prepares ASAP to play the specified song of the loaded module.
|
||||||
"as" is ASAP state initialized by ASAP_Load().
|
"ast" is ASAP state initialized by ASAP_Load().
|
||||||
"song" is a zero-based index which must be less than the "songs" field
|
"song" is a zero-based index which must be less than the "songs" field
|
||||||
of the ASAP_ModuleInfo structure.
|
of the ASAP_ModuleInfo structure.
|
||||||
"duration" is playback time in milliseconds - use durations[song]
|
"duration" is playback time in milliseconds - use durations[song]
|
||||||
unless you want to override it. -1 means indefinitely. */
|
unless you want to override it. -1 means indefinitely. */
|
||||||
void ASAP_PlaySong(ASAP_State *as, int song, int duration);
|
void ASAP_PlaySong(ASAP_State *ast, int song, int duration);
|
||||||
|
|
||||||
/* Mutes the selected POKEY channels.
|
/* Mutes the selected POKEY channels.
|
||||||
This is only useful for people who want to grab samples of individual
|
This is only useful for people who want to grab samples of individual
|
||||||
instruments.
|
instruments.
|
||||||
"as" is ASAP state after calling ASAP_PlaySong().
|
"ast" is ASAP state after calling ASAP_PlaySong().
|
||||||
"mask" is a bit mask which selects POKEY channels to be muted.
|
"mask" is a bit mask which selects POKEY channels to be muted.
|
||||||
Bits 0-3 control the base POKEY channels,
|
Bits 0-3 control the base POKEY channels,
|
||||||
bits 4-7 control the extra POKEY channels. */
|
bits 4-7 control the extra POKEY channels. */
|
||||||
void ASAP_MutePokeyChannels(ASAP_State *as, int mask);
|
void ASAP_MutePokeyChannels(ASAP_State *ast, int mask);
|
||||||
|
|
||||||
|
/* Returns current position in milliseconds.
|
||||||
|
"ast" is ASAP state initialized by ASAP_PlaySong(). */
|
||||||
|
int ASAP_GetPosition(const ASAP_State *ast);
|
||||||
|
|
||||||
/* Rewinds the current song.
|
/* Rewinds the current song.
|
||||||
"as" is ASAP state initialized by ASAP_PlaySong().
|
"ast" is ASAP state initialized by ASAP_PlaySong().
|
||||||
"position" is the requested absolute position in milliseconds. */
|
"position" is the requested absolute position in milliseconds. */
|
||||||
void ASAP_Seek(ASAP_State *as, int position);
|
void ASAP_Seek(ASAP_State *ast, int position);
|
||||||
|
|
||||||
|
/* Fills the specified buffer with WAV file header.
|
||||||
|
"ast" is ASAP state initialized by ASAP_PlaySong() with a positive "duration".
|
||||||
|
"buffer" is buffer of ASAP_WAV_HEADER_BYTES bytes.
|
||||||
|
"format" is the format of samples. */
|
||||||
|
void ASAP_GetWavHeader(const ASAP_State *ast, byte buffer[],
|
||||||
|
ASAP_SampleFormat format);
|
||||||
|
|
||||||
/* Fills the specified buffer with generated samples.
|
/* Fills the specified buffer with generated samples.
|
||||||
"as" is ASAP state initialized by ASAP_PlaySong().
|
"ast" is ASAP state initialized by ASAP_PlaySong().
|
||||||
"buffer" is the destination buffer.
|
"buffer" is the destination buffer.
|
||||||
"buffer_len" is the length of this buffer in bytes.
|
"buffer_len" is the length of this buffer in bytes.
|
||||||
"format" is the format of samples.
|
"format" is the format of samples.
|
||||||
|
@ -252,7 +277,7 @@ void ASAP_Seek(ASAP_State *as, int position);
|
||||||
(less than buffer_len if reached the end of the song).
|
(less than buffer_len if reached the end of the song).
|
||||||
Normally you use a buffer of a few kilobytes or less,
|
Normally you use a buffer of a few kilobytes or less,
|
||||||
and call ASAP_Generate() in a loop or via a callback. */
|
and call ASAP_Generate() in a loop or via a callback. */
|
||||||
int ASAP_Generate(ASAP_State *as, void *buffer, int buffer_len,
|
int ASAP_Generate(ASAP_State *ast, void *buffer, int buffer_len,
|
||||||
ASAP_SampleFormat format);
|
ASAP_SampleFormat format);
|
||||||
|
|
||||||
/* Checks whether information in the specified file can be edited. */
|
/* Checks whether information in the specified file can be edited. */
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* asap_internal.h - private interface of the ASAP engine
|
* asap_internal.h - private interface of ASAP
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005-2008 Piotr Fusik
|
* Copyright (C) 2005-2010 Piotr Fusik
|
||||||
*
|
*
|
||||||
* This file is part of ASAP (Another Slight Atari Player),
|
* This file is part of ASAP (Another Slight Atari Player),
|
||||||
* see http://asap.sourceforge.net
|
* see http://asap.sourceforge.net
|
||||||
|
@ -24,34 +24,36 @@
|
||||||
#ifndef _ASAP_INTERNAL_H_
|
#ifndef _ASAP_INTERNAL_H_
|
||||||
#define _ASAP_INTERNAL_H_
|
#define _ASAP_INTERNAL_H_
|
||||||
|
|
||||||
#if !defined(JAVA) && !defined(CSHARP)
|
#include "anylang.h"
|
||||||
|
|
||||||
|
#ifndef C
|
||||||
|
|
||||||
|
#define ASAP_SONGS_MAX 32
|
||||||
|
#define ASAP_SAMPLE_RATE 44100
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef JAVA
|
||||||
|
|
||||||
|
#define ASAP_FORMAT_U8 8
|
||||||
|
#define ASAP_FORMAT_S16_LE 16
|
||||||
|
#define ASAP_FORMAT_S16_BE -16
|
||||||
|
#define ASAP_SampleFormat int
|
||||||
|
|
||||||
|
#elif defined(CSHARP) || defined(JAVASCRIPT)
|
||||||
|
|
||||||
|
#define ASAP_FORMAT_U8 ASAP_SampleFormat.U8
|
||||||
|
#define ASAP_FORMAT_S16_LE ASAP_SampleFormat.S16LE
|
||||||
|
#define ASAP_FORMAT_S16_BE ASAP_SampleFormat.S16BE
|
||||||
|
|
||||||
|
#elif defined(ACTIONSCRIPT)
|
||||||
|
|
||||||
|
#define ASAP_SampleFormat int
|
||||||
|
|
||||||
|
#else /* C */
|
||||||
|
|
||||||
#include "asap.h"
|
#include "asap.h"
|
||||||
|
|
||||||
#define CONST_LOOKUP(type, name) \
|
|
||||||
static const type name[]
|
|
||||||
#define FILE_FUNC static
|
|
||||||
#define ASAP_FUNC
|
|
||||||
#define PTR *
|
|
||||||
#define ADDRESSOF &
|
|
||||||
#define ARRAY *
|
|
||||||
#define VOIDPTR void *
|
|
||||||
#define UBYTE(data) (data)
|
|
||||||
#define SBYTE(data) (signed char) (data)
|
|
||||||
#define STRING const char *
|
|
||||||
#define ZERO_ARRAY(array) memset(array, 0, sizeof(array))
|
|
||||||
#define COPY_ARRAY(dest, dest_offset, src, src_offset, len) \
|
|
||||||
memcpy(dest + dest_offset, src + src_offset, len)
|
|
||||||
#define NEW_ARRAY(type, name, size) \
|
|
||||||
type name[size]
|
|
||||||
#define INIT_ARRAY(array) memset(array, 0, sizeof(array))
|
|
||||||
|
|
||||||
#define AST ast->
|
|
||||||
#define PST pst->
|
|
||||||
#define MODULE_INFO module_info->
|
|
||||||
#define ASAP_OBX const byte *
|
|
||||||
#define GET_OBX(name) name##_obx
|
|
||||||
|
|
||||||
int ASAP_GetByte(ASAP_State *ast, int addr);
|
int ASAP_GetByte(ASAP_State *ast, int addr);
|
||||||
void ASAP_PutByte(ASAP_State *ast, int addr, int data);
|
void ASAP_PutByte(ASAP_State *ast, int addr, int data);
|
||||||
|
|
||||||
|
@ -60,7 +62,7 @@ void Cpu_RunScanlines(ASAP_State *ast, int scanlines);
|
||||||
void PokeySound_Initialize(ASAP_State *ast);
|
void PokeySound_Initialize(ASAP_State *ast);
|
||||||
void PokeySound_StartFrame(ASAP_State *ast);
|
void PokeySound_StartFrame(ASAP_State *ast);
|
||||||
void PokeySound_PutByte(ASAP_State *ast, int addr, int data);
|
void PokeySound_PutByte(ASAP_State *ast, int addr, int data);
|
||||||
int PokeySound_GetRandom(ASAP_State *ast, int addr);
|
int PokeySound_GetRandom(ASAP_State *ast, int addr, int cycle);
|
||||||
void PokeySound_EndFrame(ASAP_State *ast, int cycle_limit);
|
void PokeySound_EndFrame(ASAP_State *ast, int cycle_limit);
|
||||||
int PokeySound_Generate(ASAP_State *ast, byte buffer[], int buffer_offset, int blocks, ASAP_SampleFormat format);
|
int PokeySound_Generate(ASAP_State *ast, byte buffer[], int buffer_offset, int blocks, ASAP_SampleFormat format);
|
||||||
abool PokeySound_IsSilent(const PokeyState *pst);
|
abool PokeySound_IsSilent(const PokeyState *pst);
|
||||||
|
@ -68,11 +70,11 @@ void PokeySound_Mute(const ASAP_State *ast, PokeyState *pst, int mask);
|
||||||
|
|
||||||
#ifdef ASAPSCAN
|
#ifdef ASAPSCAN
|
||||||
abool call_6502_player(ASAP_State *ast);
|
abool call_6502_player(ASAP_State *ast);
|
||||||
extern abool cpu_trace;
|
extern int cpu_trace;
|
||||||
void print_cpu_state(const ASAP_State *ast, int pc, int a, int x, int y, int s, int nz, int vdi, int c);
|
void trace_cpu(const ASAP_State *ast, int pc, int a, int x, int y, int s, int nz, int vdi, int c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* !defined(JAVA) && !defined(CSHARP) */
|
#endif /* C */
|
||||||
|
|
||||||
#define ASAP_MAIN_CLOCK 1773447
|
#define ASAP_MAIN_CLOCK 1773447
|
||||||
|
|
||||||
|
@ -83,11 +85,32 @@ void print_cpu_state(const ASAP_State *ast, int pc, int a, int x, int y, int s,
|
||||||
|
|
||||||
#define NEVER 0x800000
|
#define NEVER 0x800000
|
||||||
|
|
||||||
#define dGetByte(addr) UBYTE(AST memory[addr])
|
#define DELTA_SHIFT_POKEY 20
|
||||||
#define dPutByte(addr, data) AST memory[addr] = (byte) (data)
|
#define DELTA_SHIFT_GTIA 20
|
||||||
|
#define DELTA_SHIFT_COVOX 17
|
||||||
|
|
||||||
|
/* 6502 player types */
|
||||||
|
#define ASAP_TYPE_SAP_B 1
|
||||||
|
#define ASAP_TYPE_SAP_C 2
|
||||||
|
#define ASAP_TYPE_SAP_D 3
|
||||||
|
#define ASAP_TYPE_SAP_S 4
|
||||||
|
#define ASAP_TYPE_CMC 5
|
||||||
|
#define ASAP_TYPE_CM3 6
|
||||||
|
#define ASAP_TYPE_CMR 7
|
||||||
|
#define ASAP_TYPE_CMS 8
|
||||||
|
#define ASAP_TYPE_DLT 9
|
||||||
|
#define ASAP_TYPE_MPT 10
|
||||||
|
#define ASAP_TYPE_RMT 11
|
||||||
|
#define ASAP_TYPE_TMC 12
|
||||||
|
#define ASAP_TYPE_TM2 13
|
||||||
|
|
||||||
|
#define dGetByte(addr) UBYTE(ast _ memory[addr])
|
||||||
|
#define dPutByte(addr, data) ast _ memory[addr] = CAST(byte) (data)
|
||||||
#define dGetWord(addr) (dGetByte(addr) + (dGetByte((addr) + 1) << 8))
|
#define dGetWord(addr) (dGetByte(addr) + (dGetByte((addr) + 1) << 8))
|
||||||
#define GetByte(addr) (((addr) & 0xf900) == 0xd000 ? ASAP_GetByte(ast, addr) : dGetByte(addr))
|
#define GetByte(addr) (((addr) & 0xf900) == 0xd000 ? ASAP_GetByte(ast, addr) : dGetByte(addr))
|
||||||
#define PutByte(addr, data) do { if (((addr) & 0xf900) == 0xd000) ASAP_PutByte(ast, addr, data); else dPutByte(addr, data); } while (FALSE)
|
#define PutByte(addr, data) do { if (((addr) & 0xf900) == 0xd000) ASAP_PutByte(ast, addr, data); else dPutByte(addr, data); } while (FALSE)
|
||||||
#define RMW_GetByte(dest, addr) do { if (((addr) >> 8) == 0xd2) { dest = ASAP_GetByte(ast, addr); AST cycle--; ASAP_PutByte(ast, addr, dest); AST cycle++; } else dest = dGetByte(addr); } while (FALSE)
|
#define RMW_GetByte(dest, addr) do { if (((addr) >> 8) == 0xd2) { dest = ASAP_GetByte(ast, addr); ast _ cycle--; ASAP_PutByte(ast, addr, dest); ast _ cycle++; } else dest = dGetByte(addr); } while (FALSE)
|
||||||
|
|
||||||
|
#define CYCLE_TO_SAMPLE(cycle) TO_INT(((cycle) * ASAP_SAMPLE_RATE + ast _ sample_offset) / ASAP_MAIN_CLOCK)
|
||||||
|
|
||||||
#endif /* _ASAP_INTERNAL_H_ */
|
#endif /* _ASAP_INTERNAL_H_ */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -111,7 +111,7 @@ const struct afmt_entry audio_formats[AFMT_NUM_CODECS] =
|
||||||
/* Amiga MOD File */
|
/* Amiga MOD File */
|
||||||
[AFMT_MOD] =
|
[AFMT_MOD] =
|
||||||
AFMT_ENTRY("MOD", "mod", NULL, "mod\0" ),
|
AFMT_ENTRY("MOD", "mod", NULL, "mod\0" ),
|
||||||
/* Amiga SAP File */
|
/* Atari SAP File */
|
||||||
[AFMT_SAP] =
|
[AFMT_SAP] =
|
||||||
AFMT_ENTRY("SAP", "asap", NULL, "sap\0" ),
|
AFMT_ENTRY("SAP", "asap", NULL, "sap\0" ),
|
||||||
/* Cook in RM/RA */
|
/* Cook in RM/RA */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue