added Emscripten src files for sdcc

This commit is contained in:
Steven Hugg 2017-04-04 09:09:48 -04:00
parent e4e59d6c0d
commit 03a5745bb5
13 changed files with 7561 additions and 0 deletions

25
emsrc/cc65/Makefile.emcc Normal file
View File

@ -0,0 +1,25 @@
# Emscripten target (see https://github.com/apiaryio/emscripten-docker)
DOCKEREMCC=docker run --rm -v $(shell pwd):/src -e USERID=$(shell id -u) -t apiaryio/emcc
%.js: bin/%.bc
$(DOCKEREMCC) emcc -O2 --memory-init-file 0 \
-s ASM_JS=1 \
-s MODULARIZE=1 \
-s EXPORT_NAME=\"'$*'\" \
-s 'EXTRA_EXPORTED_RUNTIME_METHODS=["FS"]' \
-s FORCE_FILESYSTEM=1 \
bin/$*.bc -o $@ $(ARGS_$*)
bin/%.bc:
mkdir -p bin js
$(DOCKEREMCC) emmake make $*
cp bin/$*.exe bin/$*.bc
emscripten: include asminc cfg lib/apple2.lib target/apple2
cp -rp src Makefile js
make -C js cc65.js ca65.js co65.js ld65.js
$(DOCKEREMCC) \
python /emscripten/tools/file_packager.py fs65.data \
--preload include asminc cfg lib/apple2.lib target/apple2 \
--separate-metadata --js-output=fs65.js

1
emsrc/sdcc/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.bz2

12
emsrc/sdcc/Dockerfile Normal file
View File

@ -0,0 +1,12 @@
FROM apiaryio/emcc
RUN apt-get update
RUN apt-get install -y bison flex bzip2 g++ texinfo sdcc
COPY boost* /tmp
RUN mkdir /boost
WORKDIR /boost
RUN tar xvjf /tmp/boost*
WORKDIR /boost/boost_1_63_0/
RUN emconfigure ./bootstrap.sh
RUN emmake ./b2 install --prefix=/emscripten/system --with-graph link=static variant=release threading=single runtime-link=static
RUN apt-get install -y zlib1g-dev
WORKDIR /src

11
emsrc/sdcc/Makefile.emcc Normal file
View File

@ -0,0 +1,11 @@
all: js/sdcc.js js/sdasz80.js js/sdldz80.js
js/%.js: js/%.bc
docker run --rm -v $(shell pwd):/src -e USERID=1000 -t apiaryio/emcc emcc -O2 --memory-init-file 0 \
-s ASM_JS=1 \
-s MODULARIZE=1 \
-s EXPORT_NAME=\"'$*'\" \
-s 'EXTRA_EXPORTED_RUNTIME_METHODS=["FS"]' \
-s FORCE_FILESYSTEM=1 \
$< -o $@ $(ARGS_$*) \

45
emsrc/sdcc/build.sh Normal file
View File

@ -0,0 +1,45 @@
rm -fr /tmp/sdcc
mkdir /tmp/sdcc
git archive --format tar HEAD |tar xv -C /tmp/sdcc
cd /tmp/sdcc/sdcc
echo Configuring SDCC...
docker run --rm -v `pwd`:/src -e USERID=$UID -t sehugg/emcc emconfigure ./configure --host x86_64-unknown-linux-gnu --includedir /src \
--enable-z80-port \
--disable-mcs51-port \
--disable-z180-port \
--disable-r2k-port \
--disable-r3ka-port \
--enable-gbz80-port \
--disable-tlcs90-port \
--disable-ds390-port \
--disable-ds400-port \
--disable-pic14-port \
--disable-pic16-port \
--disable-hc08-port \
--disable-s08-port \
--disable-stm8-port \
--disable-ucsim \
--disable-device-lib \
--disable-packihx \
--disable-sdcpp \
--disable-sdcdb \
--disable-sdbinutils \
--disable-non-free \
echo Configuring sdbinutils...
cd support/sdbinutils
./configure
make
cd ../..
echo Making SDCC...
docker run --rm -v `pwd`:/src -e USERID=$UID -t sehugg/emcc emmake make
echo Making JS files...
mkdir -p ./js
cp /tmp/sdcc/sdcc/bin/sdcc js/sdcc.bc
cp /tmp/sdcc/sdcc/bin/sdasz80 js/sdasz80.bc
cp /tmp/sdcc/sdcc/bin/sdldz80 js/sdldz80.bc
make -f Makefile.emcc

1
emsrc/sdcc/mkdocker.sh Normal file
View File

@ -0,0 +1 @@
docker build -t sehugg/emcc .

4
emsrc/votrax/Makefile Normal file
View File

@ -0,0 +1,4 @@
main: main.c
gcc -o main *.c -lm

BIN
emsrc/votrax/main Executable file

Binary file not shown.

38
emsrc/votrax/main.c Normal file
View File

@ -0,0 +1,38 @@
#include <unistd.h>
#include "votrax.h"
static double ratio = 1.0;
static int votrax_sync_samples = 0;
static int votrax_written = FALSE;
static int votrax_written_byte = 0x3f;
static char VOTRAXSND_busy = 0;
void VOTRAXSND_PutByte(UBYTE byte)
{
/* put byte to voice box */
votrax_sync_samples = (int)((1.0/ratio)*(double)Votrax_Samples((votrax_written_byte&0x3f), (byte&0x3f), votrax_sync_samples));
votrax_written = TRUE;
votrax_written_byte = byte;
if (!VOTRAXSND_busy) {
VOTRAXSND_busy = TRUE;
}
}
int main(int argc, char** argv) {
struct Votrax_interface interface;
SWORD buf[2048];
if (Votrax_Start(&interface)) {
return 1;
}
VOTRAXSND_PutByte(0xc);
Votrax_Update(0, buf, sizeof(buf)/sizeof(SWORD));
write(STDOUT_FILENO, &buf, sizeof(buf));
Votrax_Stop();
return 0;
}

12
emsrc/votrax/util.h Normal file
View File

@ -0,0 +1,12 @@
#include <stdint.h>
typedef uint8_t UBYTE;
typedef int8_t SBYTE;
typedef uint16_t UWORD;
typedef int16_t SWORD;
#define Util_malloc malloc
#define FALSE 0
#define TRUE 1

472
emsrc/votrax/votrax.c Executable file
View File

@ -0,0 +1,472 @@
/* License note by perry_m:
Permission has been granted by the authors Mike Coates and Tom Haukap
to distribute this file under the terms of the GNU GPL license of Atari800.
The original version written by Mike Coates is from MAME.
This extensively modified version with new samples and mixing written
by Tom Haukap is from PinMAME.
I have also made modifications to this file for use in Atari800 and
allow any modifications to be distributed under any of the licenses
of Atari800, MAME and PinMAME. */
/**************************************************************************
Votrax SC-01 Emulator
Mike@Dissfulfils.co.uk
Tom.Haukap@t-online.de
modified for Atari800 by perry_m@fastmail.fm
**************************************************************************
Votrax_Start - Start emulation, load samples from Votrax subdirectory
Votrax_Stop - End emulation, free memory used for samples
Votrax_PutByte - Write data to votrax port
Votrax_GetStatus - Return busy status (1 = busy)
**************************************************************************/
#ifdef PBI_DEBUG
#define VERBOSE 1
#endif
#if VERBOSE
#define LOG(x) printf x
#else
#define LOG(x)
#endif
#include "votrax.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
static struct {
int busy;
int actPhoneme;
int actIntonation;
struct Votrax_interface *intf;
SWORD* pActPos;
int iRemainingSamples;
SWORD *lpBuffer;
SWORD* pBufferPos;
int iSamplesInBuffer;
int iDelay; /* a count of samples to output '0' in a Delay state */
} votraxsc01_locals;
#define INT16 SWORD
#define UINT16 UWORD
#include "vtxsmpls.inc"
#if VERBOSE
static const char *PhonemeNames[65] =
{
"EH3","EH2","EH1","PA0","DT" ,"A2" ,"A1" ,"ZH",
"AH2","I3" ,"I2" ,"I1" ,"M" ,"N" ,"B" ,"V",
"CH" ,"SH" ,"Z" ,"AW1","NG" ,"AH1","OO1","OO",
"L" ,"K" ,"J" ,"H" ,"G" ,"F" ,"D" ,"S",
"A" ,"AY" ,"Y1" ,"UH3","AH" ,"P" ,"O" ,"I",
"U" ,"Y" ,"T" ,"R" ,"E" ,"W" ,"AE" ,"AE1",
"AW2","UH2","UH1","UH" ,"O2" ,"O1" ,"IU" ,"U1",
"THV","TH" ,"ER" ,"EH" ,"E1" ,"AW" ,"PA1","STOP",
0
};
#endif
/* phoneme types*/
#define PT_NS 0
#define PT_V 1
#define PT_VF 2
#define PT_F 3
#define PT_N 4
#define PT_VS 5
#define PT_FS 6
static int sample_rate[4] = {22050, 22050, 22050, 22050};
/* converts milliseconds to a count of samples */
static int time_to_samples(int ms)
{
return sample_rate[votraxsc01_locals.actIntonation]*ms/1000;
}
static void PrepareVoiceData(int nextPhoneme, int nextIntonation)
{
int iNextRemainingSamples;
SWORD *pNextPos, *lpHelp;
int iFadeOutSamples;
int iFadeOutPos;
int iFadeInSamples;
int iFadeInPos;
int doMix;
/* used only for SecondStart phonemes */
int AdditionalSamples;
/* dwCount is the length of samples to produce in ms from iLengthms */
int dwCount, i;
SWORD data;
AdditionalSamples = 0;
/* some phonenemes have a SecondStart */
if ( PhonemeData[votraxsc01_locals.actPhoneme].iType>=PT_VS && votraxsc01_locals.actPhoneme!=nextPhoneme ) {
AdditionalSamples = PhonemeData[votraxsc01_locals.actPhoneme].iSecondStart;
}
if ( PhonemeData[nextPhoneme].iType>=PT_VS ) {
/* 'stop phonemes' will stop playing until the next phoneme is sent*/
votraxsc01_locals.iRemainingSamples = 0;
return;
}
/* length of samples to produce*/
dwCount = time_to_samples(PhonemeData[nextPhoneme].iLengthms);
votraxsc01_locals.iSamplesInBuffer = dwCount+AdditionalSamples;
if ( AdditionalSamples )
memcpy(votraxsc01_locals.lpBuffer, PhonemeData[votraxsc01_locals.actPhoneme].lpStart[votraxsc01_locals.actIntonation], AdditionalSamples*sizeof(SWORD));
lpHelp = votraxsc01_locals.lpBuffer + AdditionalSamples;
iNextRemainingSamples = 0;
pNextPos = NULL;
iFadeOutSamples = 0;
iFadeOutPos = 0;
iFadeInSamples = 0;
iFadeInPos = 0;
doMix = 0;
/* set up processing*/
if ( PhonemeData[votraxsc01_locals.actPhoneme].sameAs!=PhonemeData[nextPhoneme].sameAs ) {
/* do something, if they are the same all FadeIn/Out values are 0, */
/* the buffer is simply filled with the samples of the new phoneme */
switch ( PhonemeData[votraxsc01_locals.actPhoneme].iType ) {
case PT_NS:
/* "fade" out NS:*/
iFadeOutSamples = time_to_samples(30);
iFadeOutPos = 0;
/* fade in new phoneme*/
iFadeInPos = -time_to_samples(30);
iFadeInSamples = time_to_samples(30);
break;
case PT_V:
case PT_VF:
switch ( PhonemeData[nextPhoneme].iType ){
case PT_F:
case PT_VF:
/* V-->F, V-->VF: fade out 30 ms fade in from 30 ms to 60 ms without mixing*/
iFadeOutPos = 0;
iFadeOutSamples = time_to_samples(30);
iFadeInPos = -time_to_samples(30);
iFadeInSamples = time_to_samples(30);
break;
case PT_N:
/* V-->N: fade out 40 ms fade from 0 ms to 40 ms without mixing*/
iFadeOutPos = 0;
iFadeOutSamples = time_to_samples(40);
iFadeInPos = -time_to_samples(10);
iFadeInSamples = time_to_samples(10);
break;
default:
/* fade out 20 ms, no fade in from 10 ms to 30 ms*/
iFadeOutPos = 0;
iFadeOutSamples = time_to_samples(20);
iFadeInPos = -time_to_samples(0);
iFadeInSamples = time_to_samples(20);
break;
}
break;
case PT_N:
switch ( PhonemeData[nextPhoneme].iType ){
case PT_V:
case PT_VF:
/* N-->V, N-->VF: fade out 30 ms fade in from 10 ms to 50 ms without mixing*/
iFadeOutPos = 0;
iFadeOutSamples = time_to_samples(30);
iFadeInPos = -time_to_samples(10);
iFadeInSamples = time_to_samples(40);
break;
default:
break;
}
case PT_VS:
case PT_FS:
iFadeOutPos = 0;
iFadeOutSamples = PhonemeData[votraxsc01_locals.actPhoneme].iLength[votraxsc01_locals.actIntonation] - PhonemeData[votraxsc01_locals.actPhoneme].iSecondStart;
votraxsc01_locals.pActPos = PhonemeData[votraxsc01_locals.actPhoneme].lpStart[votraxsc01_locals.actIntonation] + PhonemeData[votraxsc01_locals.actPhoneme].iSecondStart;
votraxsc01_locals.iRemainingSamples = iFadeOutSamples;
doMix = 1;
iFadeInPos = -time_to_samples(0);
iFadeInSamples = time_to_samples(0);
break;
default:
/* fade out 30 ms, no fade in*/
iFadeOutPos = 0;
iFadeOutSamples = time_to_samples(20);
iFadeInPos = -time_to_samples(20);
break;
}
if ( !votraxsc01_locals.iDelay ) {
/* this is true if after a stop and a phoneme was sent a second phoneme is sent*/
/* during the delay time of the chip. Ignore the first phoneme data*/
iFadeOutPos = 0;
iFadeOutSamples = 0;
}
}
else {
/* the next one is of the same type as the previous one; continue to use the samples of the last phoneme*/
iNextRemainingSamples = votraxsc01_locals.iRemainingSamples;
pNextPos = votraxsc01_locals.pActPos;
}
for (i=0; i<dwCount; i++)
{
data = 0x00;
/* fade out*/
if ( iFadeOutPos<iFadeOutSamples )
{
double dFadeOut = 1.0;
if ( !doMix )
dFadeOut = 1.0-sin((1.0*iFadeOutPos/iFadeOutSamples)*3.1415/2);
if ( !votraxsc01_locals.iRemainingSamples ) {
votraxsc01_locals.iRemainingSamples = PhonemeData[votraxsc01_locals.actPhoneme].iLength[votraxsc01_locals.actIntonation];
votraxsc01_locals.pActPos = PhonemeData[votraxsc01_locals.actPhoneme].lpStart[votraxsc01_locals.actIntonation];
}
data = (SWORD) (*votraxsc01_locals.pActPos++ * dFadeOut);
votraxsc01_locals.iRemainingSamples--;
iFadeOutPos++;
}
/* fade in or copy*/
if ( iFadeInPos>=0 )
{
double dFadeIn = 1.0;
if ( iFadeInPos<iFadeInSamples ) {
dFadeIn = sin((1.0*iFadeInPos/iFadeInSamples)*3.1415/2);
iFadeInPos++;
}
if ( !iNextRemainingSamples ) {
iNextRemainingSamples = PhonemeData[nextPhoneme].iLength[nextIntonation];
pNextPos = PhonemeData[nextPhoneme].lpStart[nextIntonation];
}
data += (SWORD) (*pNextPos++ * dFadeIn);
iNextRemainingSamples--;
}
iFadeInPos++;
*lpHelp++ = data;
}
votraxsc01_locals.pBufferPos = votraxsc01_locals.lpBuffer;
votraxsc01_locals.pActPos = pNextPos;
votraxsc01_locals.iRemainingSamples = iNextRemainingSamples;
}
void Votrax_PutByte(UBYTE data)
{
int Phoneme, Intonation;
Phoneme = data & 0x3F;
Intonation = (data >> 6)&0x03;
#ifdef VERBOSE
if (!votraxsc01_locals.intf) {
LOG(("Error: votraxsc01_locals.intf not set"));
return;
}
#endif /* VERBOSE */
LOG(("Votrax SC-01: %s at intonation %d\n", PhonemeNames[Phoneme], Intonation));
PrepareVoiceData(Phoneme, Intonation);
if ( votraxsc01_locals.actPhoneme==0x3f )
votraxsc01_locals.iDelay = time_to_samples(20);
if ( !votraxsc01_locals.busy )
{
votraxsc01_locals.busy = 1;
if ( votraxsc01_locals.intf->BusyCallback )
(*votraxsc01_locals.intf->BusyCallback)(votraxsc01_locals.busy);
}
votraxsc01_locals.actPhoneme = Phoneme;
votraxsc01_locals.actIntonation = Intonation;
}
UBYTE Votrax_GetStatus(void)
{
return votraxsc01_locals.busy;
}
void Votrax_Update(int num, SWORD *buffer, int length)
{
int samplesToCopy;
#if 0
/* if it is a different intonation */
if ( num!=votraxsc01_locals.actIntonation ) {
/* clear buffer */
memset(buffer, 0x00, length*sizeof(SWORD));
return;
}
#endif
while ( length ) {
/* Case 1: if in a delay state, output 0's*/
if ( votraxsc01_locals.iDelay ) {
samplesToCopy = (length<=votraxsc01_locals.iDelay)?length:votraxsc01_locals.iDelay;
memset(buffer, 0x00, samplesToCopy*sizeof(SWORD));
buffer += samplesToCopy;
votraxsc01_locals.iDelay -= samplesToCopy;
length -= samplesToCopy; /* missing in the original */
}
/* Case 2: there are no samples left in the buffer */
else if ( votraxsc01_locals.iSamplesInBuffer==0 ) {
if ( votraxsc01_locals.busy ) {
/* busy -> idle */
votraxsc01_locals.busy = 0;
if ( votraxsc01_locals.intf->BusyCallback )
(*votraxsc01_locals.intf->BusyCallback)(votraxsc01_locals.busy);
}
if ( votraxsc01_locals.iRemainingSamples==0 ) {
if ( PhonemeData[votraxsc01_locals.actPhoneme].iType>=PT_VS ) {
votraxsc01_locals.pActPos = PhonemeData[0x3f].lpStart[0];
votraxsc01_locals.iRemainingSamples = PhonemeData[0x3f].iLength[0];
}
else {
votraxsc01_locals.pActPos = PhonemeData[votraxsc01_locals.actPhoneme].lpStart[votraxsc01_locals.actIntonation];
votraxsc01_locals.iRemainingSamples = PhonemeData[votraxsc01_locals.actPhoneme].iLength[votraxsc01_locals.actIntonation];
}
}
/* if there aren't enough remaining, reduce the amount */
samplesToCopy = (length<=votraxsc01_locals.iRemainingSamples)?length:votraxsc01_locals.iRemainingSamples;
memcpy(buffer, votraxsc01_locals.pActPos, samplesToCopy*sizeof(SWORD));
buffer += samplesToCopy;
votraxsc01_locals.pActPos += samplesToCopy;
votraxsc01_locals.iRemainingSamples -= samplesToCopy;
length -= samplesToCopy;
}
/* Case 3: output the samples in the buffer */
else {
samplesToCopy = (length<=votraxsc01_locals.iSamplesInBuffer)?length:votraxsc01_locals.iSamplesInBuffer;
memcpy(buffer, votraxsc01_locals.pBufferPos, samplesToCopy*sizeof(SWORD));
buffer += samplesToCopy;
votraxsc01_locals.pBufferPos += samplesToCopy;
votraxsc01_locals.iSamplesInBuffer -= samplesToCopy;
length -= samplesToCopy;
}
}
}
int Votrax_Start(void *sound_interface)
{
int i, buffer_size;
/* clear local variables */
memset(&votraxsc01_locals, 0x00, sizeof votraxsc01_locals);
/* copy interface */
votraxsc01_locals.intf = (struct Votrax_interface *)sound_interface;
votraxsc01_locals.actPhoneme = 0x3f;
/* find the largest possible size of iSamplesInBuffer */
buffer_size = 0;
for (i = 0; i <= 0x3f; i++) {
int dwCount;
int size;
int AdditionalSamples;
AdditionalSamples = PhonemeData[i].iSecondStart;
dwCount = time_to_samples(PhonemeData[i].iLengthms);
size = dwCount + AdditionalSamples;
if (size > buffer_size) buffer_size = size;
}
votraxsc01_locals.lpBuffer = (SWORD*) Util_malloc(buffer_size*sizeof(SWORD));
PrepareVoiceData(votraxsc01_locals.actPhoneme, votraxsc01_locals.actIntonation);
return 0;
}
void Votrax_Stop(void)
{
if ( votraxsc01_locals.lpBuffer ) {
free(votraxsc01_locals.lpBuffer);
votraxsc01_locals.lpBuffer = NULL;
}
}
int Votrax_Samples(int currentP, int nextP, int cursamples)
{
int AdditionalSamples = 0;
int dwCount;
int delay = 0;
/* some phonemes have a SecondStart */
if ( PhonemeData[currentP].iType>=PT_VS && currentP!=nextP) {
AdditionalSamples = PhonemeData[currentP].iSecondStart;
}
if ( PhonemeData[nextP].iType>=PT_VS ) {
/* 'stop phonemes' will stop playing until the next phoneme is sent*/
/* votraxsc01_locals.iRemainingSamples = 0; */
return cursamples;
}
if (currentP == 0x3f) delay = time_to_samples(20);
/* length of samples to produce*/
dwCount = time_to_samples(PhonemeData[nextP].iLengthms);
return dwCount + AdditionalSamples + delay ;
}
/*
vim:ts=4:sw=4:
*/

23
emsrc/votrax/votrax.h Executable file
View File

@ -0,0 +1,23 @@
#ifndef VOTRAX_H_
#define VOTRAX_H_
#include "util.h"
typedef void (*Votrax_BusyCallBack)(int);
struct Votrax_interface
{
int num; /* total number of chips */
Votrax_BusyCallBack BusyCallback; /* callback function when busy signal changes */
};
int Votrax_Start(void *sound_interface);
void Votrax_Stop(void);
void Votrax_PutByte(UBYTE data);
UBYTE Votrax_GetStatus(void);
void Votrax_Update(int num, SWORD *buffer, int length);
int Votrax_Samples(int currentP, int nextP, int cursamples);
#endif /* VOTRAX_H_ */

6917
emsrc/votrax/vtxsmpls.inc Executable file

File diff suppressed because it is too large Load Diff