new sdcc versions; swave

This commit is contained in:
Steven Hugg 2017-04-15 00:12:21 -04:00
parent 64c843027e
commit 8a8638b295
26 changed files with 355 additions and 190 deletions

31
emsrc/sdcc/Makefile.local Normal file
View File

@ -0,0 +1,31 @@
all: js/sdcc.js js/sdasz80.js js/sdldz80.js \
wasm/sdcc.js wasm/sdasz80.js wasm/sdldz80.js
js/%.js: js/%.bc
emcc -Oz --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_$*) \
wasm/%.js: js/%.bc
emcc -Oz --memory-init-file 0 \
-s WASM=1 \
-s MODULARIZE=1 \
-s EXPORT_NAME=\"'$*'\" \
-s 'EXTRA_EXPORTED_RUNTIME_METHODS=["FS"]' \
-s FORCE_FILESYSTEM=1 \
$< -o $@ $(ARGS_$*) \
debugjs/%.js: js/%.bc
emcc -O1 --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_$*) \

8
emsrc/sdcc/boost.sh Normal file
View File

@ -0,0 +1,8 @@
#!/bin/sh
rm -fr /tmp/boost
mkdir /tmp/boost
cd /tmp/boost
tar xjf ~/PuzzlingPlans/8bitworkshop/emsrc/sdcc/boost*
cd boost_1_63_0
emconfigure ./bootstrap.sh
emmake ./b2 install --prefix=/home/huggvey/emsdk-portable/emscripten/1.37.9/system --with-graph link=static variant=release threading=single runtime-link=static

1
emsrc/sdcc/build.sh Normal file → Executable file
View File

@ -1,3 +1,4 @@
#!/bin/bash
rm -fr /tmp/sdcc rm -fr /tmp/sdcc
mkdir /tmp/sdcc mkdir /tmp/sdcc

52
emsrc/sdcc/emcc-local.sh Normal file
View File

@ -0,0 +1,52 @@
rm -fr /tmp/sdcc
mkdir /tmp/sdcc
git archive --format tar HEAD |tar x -C /tmp/sdcc
pushd /tmp/sdcc/sdcc
#echo Configuring sdbinutils...
#cd support/sdbinutils
#./configure
#make
#cd ../..
echo Configuring SDCC...
emconfigure ./configure \
--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...
emmake make
echo Making JS files...
popd
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.local

0
emsrc/sdcc/mkdocker.sh Normal file → Executable file
View File

View File

@ -16,6 +16,7 @@
"scripts": { "scripts": {
"test": "npm run test-node && npm run test-browser", "test": "npm run test-node && npm run test-browser",
"test-node": "mocha --recursive --timeout 20000 test/cli", "test-node": "mocha --recursive --timeout 20000 test/cli",
"test-profile": "mocha --recursive --timeout 60000 --prof test/cli",
"test-browser": "mocha-phantomjs ./testemu.html" "test-browser": "mocha-phantomjs ./testemu.html"
}, },
"repository": { "repository": {

View File

@ -17,53 +17,84 @@ typedef struct {
word offset; word offset;
word delta; word delta;
int deltainc; int deltainc;
byte wavetable; byte* wavetable;
byte wavemask;
signed char lfo; signed char lfo;
} SoundEffect; } SoundEffect;
const char WAVES[] = { const char SQUARE_LOFREQ[32] = {
-64,-64,-64,-64,-64,-64,-64, -64,-64,-64,-64,-64,-64,-64,
-64,-64,-64,-64,-64,-64,-64, -64,-64,-64,-64,-64,-64,-64,
64,64,64,64,64,64,64,64, 64,64,64,64,64,64,64,64,
64,64,64,64,64,64,64,64, 64,64,64,64,64,64,64,64
};
const char SQUARE_HIFREQ[32] = {
-64,64,-64,64,-64,64,-64,64, -64,64,-64,64,-64,64,-64,64,
-64,64,-64,64,-64,64,-64,64, -64,64,-64,64,-64,64,-64,64,
-64,64,-64,64,-64,64,-64,64, -64,64,-64,64,-64,64,-64,64,
-64,64,-64,64,-64,64,-64,64, -64,64,-64,64,-64,64,-64,64,
};
const char SINTBL[128] = {
0, 3, 6, 9, 12, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46,
49, 51, 54, 57, 60, 63, 65, 68, 71, 73, 76, 78, 81, 83, 85, 88,
90, 92, 94, 96, 98, 100, 102, 104, 106, 107, 109, 111, 112, 113, 115, 116,
117, 118, 120, 121, 122, 122, 123, 124, 125, 125, 126, 126, 126, 127, 127, 127,
127, 127, 127, 127, 126, 126, 126, 125, 125, 124, 123, 122, 122, 121, 120, 118,
117, 116, 115, 113, 112, 111, 109, 107, 106, 104, 102, 100, 98, 96, 94, 92,
90, 88, 85, 83, 81, 78, 76, 73, 71, 68, 65, 63, 60, 57, 54, 51,
49, 46, 43, 40, 37, 34, 31, 28, 25, 22, 19, 16, 12, 9, 6, 3,
};
const char TRIANGLE[32] = {
-0x80,-0x78,-0x70,-0x68, -0x60,-0x58,-0x50,-0x48, -0x80,-0x78,-0x70,-0x68, -0x60,-0x58,-0x50,-0x48,
-0x40,-0x38,-0x30,-0x28, -0x20,-0x18,-0x10,-0x08, -0x40,-0x38,-0x30,-0x28, -0x20,-0x18,-0x10,-0x08,
0x00,0x08,0x10,0x18, 0x20,0x28,0x30,0x38, 0x00,0x08,0x10,0x18, 0x20,0x28,0x30,0x38,
0x40,0x48,0x50,0x58, 0x60,0x68,0x70,0x78, 0x40,0x48,0x50,0x58, 0x60,0x68,0x70,0x78,
};
const char NOISE[32] = {
0x60,0x37,0x3f,0x5c,0x16,0xca,0xc2,0xa5,0xfe,0xba,0x77,0x89,0xaa,0x77,0x13,0xd8, 0x60,0x37,0x3f,0x5c,0x16,0xca,0xc2,0xa5,0xfe,0xba,0x77,0x89,0xaa,0x77,0x13,0xd8,
0xae,0x82,0xfd,0x22,0x9c,0x46,0xde,0x14,0x50,0xb4,0x97,0x46,0x54,0x9d,0x60,0x2b, 0xae,0x82,0xfd,0x22,0x9c,0x46,0xde,0x14,0x50,0xb4,0x97,0x46,0x54,0x9d,0x60,0x2b,
}; };
const sbyte* wav;
SoundEffect e; SoundEffect e;
byte volume;
const SoundEffect SOUNDS[] = { const SoundEffect SOUNDS[] = {
{ 2000, 0, 3000, -1, 0x40, 0 } { 1200, 0, 0, 1, NOISE, 0xff, 0 },
{ 250, 0, 1000, -4, SINTBL, 0x7f, 0 },
{ 500, 0, 1000, 2, TRIANGLE, 0x1f, 0 },
{ 600, 0, 3000, -1, SQUARE_LOFREQ, 0x1f, 0 },
{ 600, 0, 3000, -1, SQUARE_HIFREQ, 0x1f, 0 },
{ 600, 0, 3000, 1, SQUARE_LOFREQ, 0x3f, 0 },
{ 1200, 0, 0, 1, SINTBL, 0x7f, 1 },
}; };
void play(); void play();
void main() { void main() {
// halt on command = 0
if (command == 0) HALT; if (command == 0) HALT;
// load stack pointer
__asm
ld sp,#0x8000
di
__endasm;
// copy sound to RAM
memcpy(&e, &SOUNDS[command-1], sizeof(e)); memcpy(&e, &SOUNDS[command-1], sizeof(e));
// play sound
play(); play();
// turn off speaker and halt
dac = 0;
HALT; HALT;
} }
void sample() { void sample() {
dac = wav[(e.offset >> 11) & 0x1f]; byte val = e.wavetable[(byte)(e.offset >> 8) & e.wavemask];
if (val <= volume) dac = val;
e.offset += e.delta; e.offset += e.delta;
} }
void play() { void play() {
wav = &WAVES[e.wavetable]; volume = 0xff;
while (e.duration--) { while (e.duration--) {
sample(); sample();
sample(); sample();
@ -75,5 +106,7 @@ void play() {
sample(); sample();
e.delta += e.deltainc; e.delta += e.deltainc;
e.deltainc += e.lfo; e.deltainc += e.lfo;
// taper off volume
if (e.duration <= 0xff) volume = e.duration;
} }
} }

View File

@ -962,7 +962,9 @@ void main() {
// SOUND ROM // SOUND ROM
const byte __at(0x9000) SOUND_ROM[] = { const byte __at(0x9000) SOUND_ROM[] = {
0xdb,0x00,0xb7,0x20,0x01,0x76,0x11,0x02,0x40,0xdb,0x00,0x4f,0x0d,0x06,0x00,0x69,0x60,0x29,0x29,0x09,0x29,0x01,0xc5,0x00,0x09,0x01,0x0a,0x00,0xed,0xb0,0xcd,0x04,0x01,0x3e,0x00,0xd3,0x00,0x76,0xc9,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8,0xc0,0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8,0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50, 0xdb,0x00,0xb7,0x20,0x01,0x76,0x31,0x00,0x80,0xf3,0x11,0x00,0x40,0xdb,0x00,0x4f,0x0d,0x06,0x00,0x69,0x60,0x29,0x09,0x29,0x29,0x01,0x2b,0x01,0x09,0x01,0x0c,0x00,0xed,0xb0,0xcd,0xb5,0x01,0x3e,0x00,0xd3,0x00,0x76,0xc9,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0x00,0x03,0x06,0x09,0x0c,0x10,0x13,0x16,0x19,0x1c,0x1f,0x22,0x25,0x28,0x2b,0x2e,0x31,0x33,0x36,0x39,0x3c,
0x58,0x60,0x68,0x70,0x78,0x00,0x0c,0x18,0x24,0x2d,0x35,0x3b,0x3f,0x40,0x3f,0x3b,0x35,0x2d,0x24,0x18,0x0c,0x00,0xf4,0xe8,0xdc,0xd3,0xcb,0xc5,0xc1,0xc0,0xc1,0xc5,0xcb,0xd3,0xdc,0xe8,0xf4,0x60,0x37,0x3f,0x5c,0x16,0xca,0xc2,0xa5,0xfe,0xba,0x77,0x89,0xaa,0x77,0x13,0xd8,0xae,0x82,0xfd,0x22,0x9c,0x46,0xde,0x14,0x50,0xb4,0x97,0x46,0x54,0x9d,0x60,0x2b,0xd0,0x07,0x00,0x00,0xb8,0x0b,0xff,0xff,0x40,0x00,0xf4,0x01,0x00,0x00,0xd0,0x07,0xfc,0xff,0x60,0x00,0xed,0x4b,0x04,0x40,0x78,0x0f,0x0f,0x0f,0xe6,0x1f,0xe6,0x1f,0x5f,0x16,0x00,0xfd,0x21,0x00,0x40,0xfd,0x7e,0x00,0x83,0x5f,0xfd,0x7e,0x01,0x8a,0x57,0x1a,0xd3,0x00,0x2a,0x06,0x40,0x09,0x4d,0x44,0xed, 0x3f,0x41,0x44,0x47,0x49,0x4c,0x4e,0x51,0x53,0x55,0x58,0x5a,0x5c,0x5e,0x60,0x62,0x64,0x66,0x68,0x6a,0x6b,0x6d,0x6f,0x70,0x71,0x73,0x74,0x75,0x76,0x78,0x79,0x7a,0x7a,0x7b,0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7e,0x7e,0x7e,0x7d,0x7d,0x7c,0x7b,0x7a,0x7a,0x79,0x78,0x76,0x75,0x74,0x73,0x71,0x70,0x6f,0x6d,0x6b,0x6a,0x68,0x66,0x64,0x62,0x60,0x5e,0x5c,0x5a,0x58,0x55,0x53,0x51,0x4e,0x4c,0x49,0x47,0x44,0x41,0x3f,0x3c,0x39,0x36,0x33,0x31,0x2e,0x2b,0x28,0x25,0x22,0x1f,0x1c,0x19,0x16,0x13,0x10,0x0c,0x09,0x06,0x03,0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8,0xc0,0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8,0x00,0x08,0x10,0x18,0x20,
0x43,0x04,0x40,0xc9,0x01,0x27,0x00,0x21,0x0a,0x40,0x5e,0x6b,0x26,0x00,0x09,0x22,0x00,0x40,0xed,0x4b,0x02,0x40,0x59,0x50,0x1b,0xed,0x53,0x02,0x40,0x78,0xb1,0xc8,0xcd,0xd9,0x00,0xcd,0xd9,0x00,0xcd,0xd9,0x00,0xcd,0xd9,0x00,0xcd,0xd9,0x00,0xcd,0xd9,0x00,0xcd,0xd9,0x00,0xcd,0xd9,0x00,0xed,0x4b,0x06,0x40,0x2a,0x08,0x40,0x09,0x4d,0x44,0xed,0x43,0x06,0x40,0xed,0x4b,0x08,0x40,0x3a,0x0b,0x40,0x6f,0x17,0x9f,0x67,0x09,0x4d,0x44,0xed,0x43,0x08,0x40,0x18,0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78,0x60,0x37,0x3f,0x5c,0x16,0xca,0xc2,0xa5,0xfe,0xba,0x77,0x89,0xaa,0x77,0x13,0xd8,0xae,0x82,0xfd,0x22,0x9c,0x46,0xde,0x14,0x50,0xb4,0x97,0x46,0x54,0x9d,0x60,0x2b,0xb0,0x04,0x00,0x00,0x00,0x00,0x01,0x00,0x0b,0x01,0xff,0x00,0xfa,0x00,0x00,0x00,0xe8,0x03,0xfc,0xff,0x6b,0x00,0x7f,0x00,0xf4,0x01,0x00,0x00,0xe8,0x03,0x02,0x00,0xeb,0x00,0x1f,0x00,0x58,0x02,0x00,0x00,0xb8,0x0b,0xff,0xff,0x2b,0x00,0x1f,0x00,0x58,0x02,0x00,0x00,0xb8,0x0b,0xff,0xff,0x4b,0x00,0x1f,0x00,0x58,0x02,0x00,0x00,0xb8,0x0b,0x01,0x00,0x2b,0x00,0x3f,0x00,0xb0,0x04,0x00,0x00,0x00,0x00,0x01,0x00,0x6b,0x00,0x7f,0x01,0xdd,
0xe5,0xdd,0x21,0x00,0x00,0xdd,0x39,0x3b,0xed,0x5b,0x08,0x40,0xed,0x4b,0x02,0x40,0xdd,0x70,0xff,0x3a,0x0a,0x40,0xdd,0xa6,0xff,0x6f,0x26,0x00,0x19,0x5e,0x3a,0x0c,0x40,0x93,0x38,0x03,0x7b,0xd3,0x00,0x2a,0x04,0x40,0x09,0x4d,0x44,0xed,0x43,0x02,0x40,0x33,0xdd,0xe1,0xc9,0x21,0x0c,0x40,0x36,0xff,0xed,0x4b,0x00,0x40,0x59,0x50,0x1b,0xed,0x53,0x00,0x40,0x78,0xb1,0xc8,0xcd,0x7f,0x01,0xcd,0x7f,0x01,0xcd,0x7f,0x01,0xcd,0x7f,0x01,0xcd,0x7f,0x01,0xcd,0x7f,0x01,0xcd,0x7f,0x01,0xcd,0x7f,0x01,0xed,0x4b,0x04,0x40,0x2a,0x06,0x40,0x09,0x4d,0x44,0xed,0x43,0x04,0x40,0xed,0x4b,0x06,0x40,0x3a,0x0b,0x40,0x6f,0x17,0x9f,0x67,0x09,0x4d,0x44,0xed,0x43,0x06,0x40,
0x2a,0x00,0x40,0x3e,0xff,0xbd,0x3e,0x00,0x9c,0x38,0xaf,0xfd,0x21,0x0c,0x40,0xfd,0x75,0x00,0x18,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
}; };

View File

@ -304,3 +304,111 @@ var WorkerSoundChannel = function(worker) {
} }
} }
// SampleAudio
var SampleAudio = function(clockfreq) {
var self = this;
var sfrac, sinc, accum;
var buffer, bufpos, bufferlist;
function mix(ape) {
var buflen=ape.outputBuffer.length;
var lbuf = ape.outputBuffer.getChannelData(0);
//var rbuf = ape.outputBuffer.getChannelData(1);
var m = this.module;
if (!m) m = ape.srcElement.module;
if (!m) return;
if (m.callback) {
m.callback(lbuf);
return;
} else {
var buf = bufferlist[1];
for (var i=0; i<lbuf.length; i++) {
lbuf[i] = buf[i];
}
}
}
function createContext() {
var AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext;
if (! AudioContext) {
console.log("no web audio context");
return;
}
self.context = new AudioContext();
self.sr=self.context.sampleRate;
self.bufferlen=(self.sr > 44100) ? 4096 : 2048;
// Amiga 500 fixed filter at 6kHz. WebAudio lowpass is 12dB/oct, whereas
// older Amigas had a 6dB/oct filter at 4900Hz.
self.filterNode=self.context.createBiquadFilter();
if (self.amiga500) {
self.filterNode.frequency.value=6000;
} else {
self.filterNode.frequency.value=28867;
}
// "LED filter" at 3275kHz - off by default
self.lowpassNode=self.context.createBiquadFilter();
self.lowpassNode.frequency.value=28867;
self.filter=false;
// mixer
if ( typeof self.context.createScriptProcessor === 'function') {
self.mixerNode=self.context.createScriptProcessor(self.bufferlen, 1, 1);
} else {
self.mixerNode=self.context.createJavaScriptNode(self.bufferlen, 1, 1);
}
self.mixerNode.module=self;
self.mixerNode.onaudioprocess=mix;
// compressor for a bit of volume boost, helps with multich tunes
self.compressorNode=self.context.createDynamicsCompressor();
// patch up some cables :)
self.mixerNode.connect(self.filterNode);
self.filterNode.connect(self.lowpassNode);
self.lowpassNode.connect(self.compressorNode);
self.compressorNode.connect(self.context.destination);
}
this.start = function() {
if (!this.context) createContext();
sinc = this.sr * 1.0 / clockfreq;
sfrac = 0;
accum = 0;
bufpos = 0;
bufferlist = [];
for (var i=0; i<2; i++) {
var arrbuf = new ArrayBuffer(self.bufferlen*4);
bufferlist[i] = new Float32Array(arrbuf);
}
buffer = bufferlist[0];
}
this.stop = function() {
if (this.context) {
this.context.close();
this.context = null;
}
}
this.feedSample = function(value, count) {
while (count-- > 0) {
accum += value;
sfrac += sinc;
if (sfrac >= 1) {
buffer[bufpos++] = accum / sfrac;
sfrac -= 1;
accum = 0;
if (bufpos >= buffer.length) {
bufpos = 0;
bufferlist[0] = bufferlist[1];
bufferlist[1] = buffer;
}
}
}
}
}

View File

@ -69,10 +69,10 @@ function start() {
membus = { membus = {
read: new AddressDecoder([ read: new AddressDecoder([
[0x0000, 0x3fff, 0x3fff, function(a) { return rom ? rom[a] : null; }], [0x0000, 0x3fff, 0x3fff, function(a) { return rom ? rom[a] : null; }],
[0x4000, 0x5fff, 0xfff, function(a) { return ram.mem[a]; }] [0x4000, 0x7fff, 0x3ff, function(a) { return ram.mem[a]; }]
]), ]),
write: new AddressDecoder([ write: new AddressDecoder([
[0x4000, 0x5fff, 0xfff, function(a,v) { ram.mem[a] = v; }], [0x4000, 0x7fff, 0x3ff, function(a,v) { ram.mem[a] = v; }],
]), ]),
isContended: function() { return false; }, isContended: function() { return false; },
}; };
@ -116,7 +116,6 @@ function timerCallback() {
function reset() { function reset() {
if (!bufferLength) return; if (!bufferLength) return;
cpu.setHalted(0);
cpu.reset(); cpu.reset();
if (!timer) { if (!timer) {
curTime = new Date().getTime() - timerPeriod*4; curTime = new Date().getTime() - timerPeriod*4;

View File

@ -240,112 +240,6 @@ var AnimationTimer = function(frequencyHz, callback) {
// //
var SampleAudio = function(clockfreq) {
var self = this;
var sfrac, sinc, accum;
var buffer, bufpos, bufferlist;
function mix(ape) {
var buflen=ape.outputBuffer.length;
var lbuf = ape.outputBuffer.getChannelData(0);
//var rbuf = ape.outputBuffer.getChannelData(1);
var m = this.module;
if (!m) m = ape.srcElement.module;
if (!m) return;
if (m.callback) {
m.callback(lbuf);
return;
} else {
var buf = bufferlist[1];
for (var i=0; i<lbuf.length; i++) {
lbuf[i] = buf[i];
}
}
}
function createContext() {
var AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext;
if (! AudioContext) {
console.log("no web audio context");
return;
}
self.context = new AudioContext();
self.sr=self.context.sampleRate;
self.bufferlen=(self.sr > 44100) ? 4096 : 2048;
// Amiga 500 fixed filter at 6kHz. WebAudio lowpass is 12dB/oct, whereas
// older Amigas had a 6dB/oct filter at 4900Hz.
self.filterNode=self.context.createBiquadFilter();
if (self.amiga500) {
self.filterNode.frequency.value=6000;
} else {
self.filterNode.frequency.value=28867;
}
// "LED filter" at 3275kHz - off by default
self.lowpassNode=self.context.createBiquadFilter();
self.lowpassNode.frequency.value=28867;
self.filter=false;
// mixer
if ( typeof self.context.createScriptProcessor === 'function') {
self.mixerNode=self.context.createScriptProcessor(self.bufferlen, 1, 1);
} else {
self.mixerNode=self.context.createJavaScriptNode(self.bufferlen, 1, 1);
}
self.mixerNode.module=self;
self.mixerNode.onaudioprocess=mix;
// compressor for a bit of volume boost, helps with multich tunes
self.compressorNode=self.context.createDynamicsCompressor();
// patch up some cables :)
self.mixerNode.connect(self.filterNode);
self.filterNode.connect(self.lowpassNode);
self.lowpassNode.connect(self.compressorNode);
self.compressorNode.connect(self.context.destination);
}
this.start = function() {
if (!this.context) createContext();
sinc = this.sr * 1.0 / clockfreq;
sfrac = 0;
accum = 0;
bufpos = 0;
bufferlist = [];
for (var i=0; i<2; i++) {
var arrbuf = new ArrayBuffer(self.bufferlen*4);
bufferlist[i] = new Float32Array(arrbuf);
}
buffer = bufferlist[0];
}
this.stop = function() {
if (this.context) {
this.context.close();
this.context = null;
}
}
this.feedSample = function(value, count) {
while (count-- > 0) {
accum += value;
sfrac += sinc;
if (sfrac >= 1) {
buffer[bufpos++] = accum / sfrac;
sfrac -= 1;
accum = 0;
if (bufpos >= buffer.length) {
bufpos = 0;
bufferlist[0] = bufferlist[1];
bufferlist[1] = buffer;
}
}
}
}
}
function cpuStateToLongString_6502(c) { function cpuStateToLongString_6502(c) {
function decodeFlags(c, flags) { function decodeFlags(c, flags) {
var s = ""; var s = "";

View File

@ -62,10 +62,10 @@ var WilliamsSoundPlatform = function(mainElement) {
membus = { membus = {
read: new AddressDecoder([ read: new AddressDecoder([
[0x0000, 0x3fff, 0x3fff, function(a) { return rom ? rom[a] : null; }], [0x0000, 0x3fff, 0x3fff, function(a) { return rom ? rom[a] : null; }],
[0x4000, 0x5fff, 0xfff, function(a) { return ram.mem[a]; }] [0x4000, 0x7fff, 0x3ff, function(a) { return ram.mem[a]; }]
]), ]),
write: new AddressDecoder([ write: new AddressDecoder([
[0x4000, 0x5fff, 0xfff, function(a,v) { ram.mem[a] = v; }], [0x4000, 0x7fff, 0x3ff, function(a,v) { ram.mem[a] = v; }],
]), ]),
isContended: function() { return false; }, isContended: function() { return false; },
}; };

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -41,14 +41,14 @@ var PLATFORM_PARAMS = {
code_start: 0x0, code_start: 0x0,
code_size: 0x4000, code_size: 0x4000,
data_start: 0x4000, data_start: 0x4000,
data_size: 0x1000, data_size: 0x400,
}, },
}; };
var loaded = {} var loaded = {}
function load(modulename) { function load(modulename, debug) {
if (!loaded[modulename]) { if (!loaded[modulename]) {
importScripts(modulename+".js"); importScripts(modulename+(debug?"."+debug+".js":".js"));
loaded[modulename] = 1; loaded[modulename] = 1;
} }
} }
@ -712,6 +712,7 @@ function compileSDCC(code, platform) {
else code = preproc.code; else code = preproc.code;
load("sdcc"); load("sdcc");
//console.profile("sdcc");
var params = PLATFORM_PARAMS[platform]; var params = PLATFORM_PARAMS[platform];
if (!params) throw Error("Platform not supported: " + platform); if (!params) throw Error("Platform not supported: " + platform);
var SDCC = sdcc({ var SDCC = sdcc({
@ -726,15 +727,21 @@ function compileSDCC(code, platform) {
setupFS(FS, 'sdcc'); setupFS(FS, 'sdcc');
//FS.writeFile("main.c", code, {encoding:'utf8'}); //FS.writeFile("main.c", code, {encoding:'utf8'});
msvc_errors = []; msvc_errors = [];
var t1 = new Date();
SDCC.callMain(['--vc', '--std-sdcc99', '-mz80', //'-Wall', SDCC.callMain(['--vc', '--std-sdcc99', '-mz80', //'-Wall',
'--c1mode', // '--debug', '--c1mode', // '--debug',
//'-S', 'main.c', //'-S', 'main.c',
//'--asm=z80asm', //'--asm=z80asm',
'--less-pedantic', '--less-pedantic',
//'--fomit-frame-pointer', ///'--fomit-frame-pointer',
'--opt-code-speed', '--opt-code-speed',
'--oldralloc', // TODO: does this make it fater? '--oldralloc', // TODO: does this make it fater?
//'--cyclomatic',
//'--nooverlay','--nogcse','--nolabelopt','--noinvariant','--noinduction','--nojtbound','--noloopreverse','--no-peep','--nolospre',
'-o', 'main.asm']); '-o', 'main.asm']);
var t2 = new Date();
//console.profileEnd();
//console.log(t2.getTime() - t1.getTime());
/* /*
// ignore if all are warnings (TODO?) // ignore if all are warnings (TODO?)
var nwarnings = 0; var nwarnings = 0;

View File

@ -1,17 +1,24 @@
This directory contains tools for bitmap conversion. This directory contains 8bitworkshop tools for bitmap and
music conversion.
Requires ImageMagick (convert) and Python 2.x. Requires ImageMagick (convert) and Python 2.x.
MIDI tools require Mido (pip install mido).
make <filename>.pf.hex On Ubuntu:
Converts a .jpg into a 40-pixel wide playfield bitmap. $ sudo apt update
Cut-and-paste output into program. $ sudo apt install python python-pip imagemagick curl
(See Chapter 20, Asynchronous Bitmaps) $ sudo pip install mido
make <filename>.48.hex To use the tools, go to the appropriate directory and
look at the Makefile for each:
Converts a .jpg into a 48-pixel wide sprite bitmap. vcs/ Atari 2600/VCS
Cut-and-paste output into program. mw8080/ Midway 8080
(See Chapter 22, A Big 48-Pixel Sprite) scramble/ Galaxian/Scramble
vicdual/ VIC Dual
williams/ Williams
fonts/ Example fonts
images/ Example images

View File

@ -1,11 +1,16 @@
#!/usr/bin/python #!/usr/bin/python
import sys, math import sys, string, math, argparse
test_notes = int(sys.argv[1]) or 49 parser = argparse.ArgumentParser()
final_notes = int(sys.argv[2]) or 64 parser.add_argument('-l', '--length', type=int, default=64, help="length of note table")
parser.add_argument('-u', '--upper', type=int, default=49, help="upper note # to test")
parser.add_argument('-f', '--freq', type=float, default=3579545/32.0, help="base frequency (Hz)")
args = parser.parse_args()
basehz = 3579545/32.0 test_notes = args.upper
final_notes = args.length
basehz = args.freq
results = [] results = []

View File

@ -1,9 +1,14 @@
#!/usr/bin/python #!/usr/bin/python
import sys, math import sys, string, math, argparse
test_notes = int(sys.argv[1]) or 49 parser = argparse.ArgumentParser()
final_notes = int(sys.argv[2]) or 64 parser.add_argument('-l', '--length', type=int, default=64, help="length of note table")
parser.add_argument('-u', '--upper', type=int, default=49, help="upper note # to test")
args = parser.parse_args()
test_notes = args.upper
final_notes = args.length
basehz = 15720.0 #4 basehz = 15720.0 #4
basehz2 = 5240.0 #12 basehz2 = 5240.0 #12

View File

@ -1,27 +1,29 @@
all: cp437.mw8080.c c64.mw8080.c baddies-horiz.rot.c scrappy.rot.c all: cp437.mw8080.c c64.mw8080.c baddies-horiz.rot.c scrappy.rot.c
# convert DOS CP437 font (256 chars)
cp437.mw8080.c: ../fonts/cp437-8x8.bdf cp437.mw8080.c: ../fonts/cp437-8x8.bdf
python ../parsebdf8.py $< -f -r -C > $@ python ../parsebdf8.py $< -f -r -C > $@
# convert C64 font (63 chars)
c64.mw8080.c: ../fonts/c64.bdf c64.mw8080.c: ../fonts/c64.bdf
python ../parsebdf8.py $< -f -r -C -s 32 -e 94 > $@ python ../parsebdf8.py $< -f -r -C -s 32 -e 94 > $@
%.h: %.h:
cat $* | hexdump -v -e '"\n" 128/1 "0x%02x,"' cat $* | hexdump -v -e '"\n" 128/1 "0x%02x,"'
# convert PBM bitmap to C array
%.c: %.pbm %.c: %.pbm
python ../pbm_to_c.py $< > $@ python ../pbm_to_c.py $< > $@
#%.rot.pbm: %.pbm #%.rot.pbm: %.pbm
# convert $< -transpose -bordercolor white -border 4x4 $@ # convert $< -transpose -bordercolor white -border 4x4 $@
# rotate and dither example bitmaps
baddies-horiz.rot.pbm: ../images/baddies-horiz.png baddies-horiz.rot.pbm: ../images/baddies-horiz.png
convert $< +dither -brightness-contrast 50x50 -fill black -transpose -negate $@ convert $< +dither -brightness-contrast 50x50 -fill black -transpose -negate $@
scrappy.rot.pbm: ../images/scrappy48x64.pbm scrappy.rot.pbm: ../images/scrappy48x64.pbm
convert $< -transpose -bordercolor white -border 4x4 $@ convert $< -transpose -bordercolor white -border 4x4 $@

View File

@ -8,17 +8,11 @@ import sys,string,argparse
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('-s', '--start', type=int, default=0, help="index of first character") parser.add_argument('-s', '--start', type=int, default=0, help="index of first character")
parser.add_argument('-e', '--end', type=int, default=255, help="index of last character") parser.add_argument('-e', '--end', type=int, default=255, help="index of last character")
parser.add_argument('-i', '--invert', action="store_true", help="invert bits")
parser.add_argument('-r', '--rotate', action="store_true", help="rotate bits (vertical)")
parser.add_argument('-f', '--flip', action="store_true", help="flip bits (horizontal)")
parser.add_argument('bdffile', help="BDF bitmap file") parser.add_argument('bdffile', help="BDF bitmap file")
args = parser.parse_args() args = parser.parse_args()
lochar = args.start lochar = args.start
hichar = args.end hichar = args.end
invert = args.invert
flip = args.flip
rotate = args.rotate
def tohex(v): def tohex(v):
return '%02x'%v return '%02x'%v
@ -27,7 +21,7 @@ def tohex2(v):
chars = {} chars = {}
inbitmap = 0 inbitmap = 0
with open(sys.argv[1],'r') as f: with open(args.bdffile,'r') as f:
lines = f.readlines() lines = f.readlines()
for l in lines: for l in lines:
l = l.strip() l = l.strip()

View File

@ -28,7 +28,7 @@ rotate = args.rotate
chars = {} chars = {}
inbitmap = 0 inbitmap = 0
with open(sys.argv[1],'r') as f: with open(args.bdffile,'r') as f:
lines = f.readlines() lines = f.readlines()
for l in lines: for l in lines:
l = l.strip() l = l.strip()

View File

@ -7,6 +7,7 @@ import math
n = 64 n = 64
m = 127 m = 127
n=32
for i in range(0,n*4): for i in range(0,n*4):
print '%d,' % int(round(math.sin(i*math.pi/2/n)*m)), print '%d,' % int(round(math.sin(i*math.pi/2/n)*m)),

View File

@ -1,10 +1,14 @@
# convert PBM bitmap to playfield bytes
%-pf.hex: %-pf.pbm p4_to_pfbytes.py %-pf.hex: %-pf.pbm p4_to_pfbytes.py
python p4_to_pfbytes.py $< > $@ python p4_to_pfbytes.py $< > $@
# convert PBM bitmap to 48-pixel sprite
%-48.hex: %-48.pbm p4_to_48pix.py %-48.hex: %-48.pbm p4_to_48pix.py
python p4_to_48pix.py $< > $@ python p4_to_48pix.py $< > $@
# convert JPG to pbm
%-pf.pbm: %.jpg %-pf.pbm: %.jpg
convert $< -resize 40x192\! -colorspace Gray -dither FloydSteinberg $@ convert $< -resize 40x192\! -colorspace Gray -dither FloydSteinberg $@

View File

@ -1,9 +1,11 @@
all: cp437.vicdual.c c64.vicdual.c all: cp437.vicdual.c c64.vicdual.c
# convert DOS CP437 font (256 chars)
cp437.vicdual.c: ../fonts/cp437-8x8.bdf cp437.vicdual.c: ../fonts/cp437-8x8.bdf
python ../parsebdf8.py $< -r -C > $@ python ../parsebdf8.py $< -r -C > $@
# convert C64 font (256 chars, some unused)
c64.vicdual.c: ../fonts/c64.bdf c64.vicdual.c: ../fonts/c64.bdf
python ../parsebdf8.py $< -r -C > $@ python ../parsebdf8.py $< -r -C > $@

View File

@ -1,18 +1,27 @@
all: baddies.4.pcx.h badspacerobots.tga all: baddies.c badspacerobots.tga tom-thumb.c
%.h: % %.h: %
cat $* | hexdump -v -e '"\n" 128/1 "0x%02x,"' > $@ cat $* | hexdump -v -e '"\n" 128/1 "0x%02x,"' > $@
# convert PCX (or PNG) file to Williams C sprite
%.c: %.pcx
python ../pcx2will.py $< > $@
# convert PNG into RLE-encoded TGA bitmap
%.tga: %.png %.tga: %.png
convert $< -resize 192 $<.gif convert $< -resize 192 $<.gif
convert $<.gif +dither -type palette -depth 4 -compress RLE -colors 8 -flip $@ convert $<.gif +dither -type palette -depth 4 -compress RLE -colors 8 -flip $@
convert $@ $@.png convert $@ $@.png
# convert PNG to 15-color PCX
%.pcx: %.png %.pcx: %.png
convert $< -format raw -type palette -compress none -colors 15 +dither $@ convert $< -format raw -type palette -compress none -colors 15 +dither $@
%.rle.pcx: %.png
convert $< -format raw -type palette -compress rle -colors 15 +dither $@ #%.4.pcx: %.png
%.4.pcx: %.png # convert $< -format raw -type palette -compress none -colors 4 +dither $@
convert $< -format raw -type palette -compress none -colors 4 +dither $@
# convert BDF font file to definitions
%.c: ../fonts/%.bdf
python ../parsebdf4bit.py -s 33 -e 97 $< > $@