Compare commits

...

39 commits

Author SHA1 Message Date
datajerk
f5840bdab0
Merge pull request #20 from ryandesign/patch-4
Remove c2t.h.[12] after makeheader is done
2021-10-07 19:26:52 -06:00
datajerk
a75cfc7240
Merge pull request #21 from ryandesign/patch-5
Allow Makefile compiler to be set with CC variable
2021-10-07 19:23:34 -06:00
datajerk
5354285b93
Merge pull request #19 from ryandesign/patch-3
c2t.h depends on c2t.h.0 and makeheader
2021-10-07 19:20:37 -06:00
datajerk
5d70955811
Merge pull request #18 from ryandesign/patch-2
Fix typo in c2t.h / c2t.h.0
2021-10-07 19:19:58 -06:00
datajerk
59607941d8
Merge pull request #16 from ryandesign/patch-1
Fix typos in README.md
2021-10-07 19:19:24 -06:00
Ryan Schmidt
4cd51e90c3 Fix typos in README.md 2021-10-05 18:56:12 -05:00
Ryan Schmidt
2fa723c7b7 Allow Makefile compiler to be set with CC variable 2021-09-30 17:08:11 -05:00
Ryan Schmidt
7a2c8cd0f7 Remove c2t.h.[12] after makeheader is done 2021-09-30 16:46:01 -05:00
Ryan Schmidt
4321502369 c2t.h depends on c2t.h.0 and makeheader
If either c2t.h.0 or makeheader changes, c2t.h should be regenerated.
2021-09-30 16:42:28 -05:00
Ryan Schmidt
867ebc6fbb Fix typo in c2t.h / c2t.h.0 2021-09-30 16:40:13 -05:00
datajerk
10857ec0bc
Merge pull request #15 from ryandesign/patch-1
Fix Virtual ][ and MinGW URLs in README.md
2021-09-29 17:44:14 -06:00
Ryan Schmidt
8f0ef0f3c2
Fix Virtual ][ and MinGW URLs in README.md 2021-09-29 15:13:50 -05:00
Egan Ford
a46733a60a cleanup and tests 2021-08-22 13:22:42 -06:00
Egan Ford
90096d3f2e minor updates 2021-08-22 13:11:05 -06:00
Egan Ford
61efd1beab macos universal binaries (x86_64/arm64) 2021-08-22 13:07:48 -06:00
Egan Ford
dd6a0de61c updated README with link to ubuntu build notes 2021-08-22 11:59:57 -06:00
Egan Ford
c93a5ee2ec updated README with link to ubuntu build notes 2021-08-22 11:59:31 -06:00
Egan Ford
a3b7d75f44 updated README with link to ubuntu build notes 2021-08-22 11:59:07 -06:00
Egan Ford
85fa3a60af updated ubuntu notes for installing cc65 in home dir to avoid possible conflict 2021-08-22 11:56:57 -06:00
Egan Ford
505035859c fresh builds (no new func), added ubuntu notes 2021-08-22 10:41:17 -06:00
Egan Ford
df0c177c90 updated url to cl65 2021-08-22 09:53:06 -06:00
Egan Ford
fd80c0c7b1 new binaries built 2020-06-16 11:35:12 -06:00
datajerk
e8fb623567
Merge pull request #11 from sntfrc/patch-1
Fix for hexdump parsing
2020-06-16 11:27:21 -06:00
Federico Santandrea
215adb3a64
Fix for hexdump parsing
On my machine, makeheader produced headers with lots of casts of 16-bit variables to unsigned char. Compiler warned about this many times and then successfully produced executable files, which warn about simulated inflate failures and produce unusable WAV files. This little modification in how hexdump is called fixes it for me. I believe this is the same issue as https://github.com/datajerk/c2t/issues/1
2020-06-16 17:06:13 +02:00
Egan Ford
085bef08ad updates to support MacOS Catalina lack of 32bit support, wine in docker, new Virtual ][ 2020-03-12 08:21:12 -06:00
Egan Ford
d3e5058598 updates to support MacOS Catalina lack of 32bit support, wine in docker, new Virtual ][ 2020-03-12 08:04:57 -06:00
Egan Ford
008faedd31 updates to support MacOS Catalina lack of 32bit support, wine in docker, new Virtual ][ 2020-03-12 08:01:24 -06:00
Egan Ford
b0555698c4 windows prebuilt added to repo 2019-04-04 09:46:03 -06:00
Egan Ford
82303cbf94 fixed README.md (-Wno-misleading-indentation added), squashed yet another warning 2019-04-04 08:41:38 -06:00
Egan Ford
0bee480203 fixed README.md (-I. added) for building on windows 2019-04-04 08:37:19 -06:00
datajerk
0708f49575
Merge pull request #9 from ep00ch/master
Update README.md curl instructions
2018-11-16 10:47:41 -07:00
ep00ch
b816e205a2
Update README.md 2018-11-16 09:13:41 -08:00
Egan Ford
cfaff7c951 minor changes, README.md for Virtual version 2018-07-02 09:39:40 -06:00
Egan Ford
a8e7965761 minor changes, makefile gcc warnings clean up, revert to using Virtual Box 7.6 for testing 2018-07-02 09:36:12 -06:00
Egan Ford
0ed656220a new binaries 2017-10-23 11:03:06 -06:00
datajerk
43d41a476f Merge pull request #8 from raphlinus/buf_refactor
Refactor appendtone signature
2017-10-23 10:55:52 -06:00
Raph Levien
ca608e9ca2 Set rate before outbuf_init
Fixes failing tests in dsk case, due to rate mismatch.
2017-10-23 12:34:33 -04:00
Raph Levien
07e57f3f05 Refactor appendtone signature
Creates an "outbuf" struct with all the state needed for rendering
pulses into an audio buffer. Calls to appendtone take a pointer to
this struct instead of four separate args.

This patch shouldn't affect behavior at all. It is a step toward
providing band-limited waveform generation (see #4).

Also uses doubling approach to reallocate audio buffer, one of the
existing todo items.
2017-10-23 12:33:58 -04:00
datajerk
c85a35257e Merge pull request #7 from datajerk/revert-6-buf_refactor
Revert "Refactor appendtone signature"
2017-10-23 09:33:55 -06:00
21 changed files with 289 additions and 147 deletions

12
Dockerfile.wine32 Normal file
View file

@ -0,0 +1,12 @@
# docker build --no-cache -t wine32 -f Dockerfile.wine32 .
FROM ubuntu:19.10
ENV LC_CTYPE C.UTF-8
ENV DEBIAN_FRONTEND noninteractive
RUN dpkg --add-architecture i386
RUN apt-get update
RUN apt-get -qy install wine32
WORKDIR /root
RUN wine foobar || true

View file

@ -1,29 +1,51 @@
WIN32GCC = /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin/i586-mingw32-gcc WIN32GCC = /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin/i586-mingw32-gcc
export SDKROOT = $(shell xcrun --sdk macosx --show-sdk-path)
all: bin/c2t bin/c2t-96h all: nix
nix: bin/c2t bin/c2t-96h
windows: bin/c2t.exe bin/c2t-96h.exe windows: bin/c2t.exe bin/c2t-96h.exe
dist: all windows macos: bin/c2t_x86 bin/c2t_arm bin/c2t-96h_x86 bin/c2t-96h_arm
lipo -create -output bin/c2t bin/c2t_x86 bin/c2t_arm
lipo -create -output bin/c2t-96h bin/c2t-96h_x86 bin/c2t-96h_arm
dist: macos windows
clean: testclean clean: testclean
rm -f c2t.h bin/c2t bin/c2t-96h bin/c2t.exe bin/c2t-96h.exe rm -f c2t.h bin/c2t bin/c2t-96h bin/c2t.exe bin/c2t-96h.exe bin/c2t_x86 bin/c2t_arm bin/c2t-96h_x86 bin/c2t-96h_arm
cd asm; make clean cd asm; make clean
# nix
bin/c2t: c2t.c c2t.h bin/c2t: c2t.c c2t.h
gcc -Wall -Wno-strict-aliasing -Wno-misleading-indentation -Wno-unused-value -Wno-unused-function -I. -O3 -o bin/c2t c2t.c -lm $(CC) -Wall -Wno-strict-aliasing -Wno-unused-value -Wno-unused-function -I. -O3 -o bin/c2t c2t.c -lm
bin/c2t-96h: c2t-96h.c c2t.h bin/c2t-96h: c2t-96h.c c2t.h
gcc -Wall -Wno-strict-aliasing -Wno-misleading-indentation -Wno-unused-value -Wno-unused-function -I. -O3 -o bin/c2t-96h c2t-96h.c -lm $(CC) -Wall -Wno-strict-aliasing -Wno-unused-value -Wno-unused-function -I. -O3 -o bin/c2t-96h c2t-96h.c -lm
# macos universal
bin/c2t_x86: c2t.c c2t.h
$(CC) -Wall -Wno-strict-aliasing -Wno-unused-value -Wno-unused-function -I. -O3 -target x86_64-apple-macos10.12 -o $@ c2t.c -lm
bin/c2t-96h_x86: c2t-96h.c c2t.h
$(CC) -Wall -Wno-strict-aliasing -Wno-unused-value -Wno-unused-function -I. -O3 -target x86_64-apple-macos10.12 -o $@ c2t-96h.c -lm
bin/c2t_arm: c2t.c c2t.h
$(CC) -Wall -Wno-strict-aliasing -Wno-unused-value -Wno-unused-function -I. -O3 -target arm64-apple-macos11 -o $@ c2t.c -lm
bin/c2t-96h_arm: c2t-96h.c c2t.h
$(CC) -Wall -Wno-strict-aliasing -Wno-unused-value -Wno-unused-function -I. -O3 -target arm64-apple-macos11 -o $@ c2t-96h.c -lm
# windows
bin/c2t.exe: c2t.c c2t.h bin/c2t.exe: c2t.c c2t.h
$(WIN32GCC) -Wall -Wno-strict-aliasing -Wno-unused-value -Wno-unused-function -I. -O3 -o bin/c2t.exe c2t.c $(WIN32GCC) -Wall -Wno-strict-aliasing -Wno-unused-value -Wno-unused-function -I. -O3 -o bin/c2t.exe c2t.c
bin/c2t-96h.exe: c2t-96h.c c2t.h bin/c2t-96h.exe: c2t-96h.c c2t.h
$(WIN32GCC) -Wall -Wno-strict-aliasing -Wno-unused-value -Wno-unused-function -I. -O3 -o bin/c2t-96h.exe c2t-96h.c $(WIN32GCC) -Wall -Wno-strict-aliasing -Wno-unused-value -Wno-unused-function -I. -O3 -o bin/c2t-96h.exe c2t-96h.c
c2t.h: mon/dos33.boot1.mon mon/dos33.boot2.mon asm/autoload.s asm/diskload2.s asm/diskload3.s asm/diskload8000.s asm/diskload9600.s asm/fastload8000.s asm/fastload9600.s asm/fastloadcd.s asm/inflate.s c2t.h: c2t.h.0 makeheader mon/dos33.boot1.mon mon/dos33.boot2.mon asm/autoload.s asm/diskload2.s asm/diskload3.s asm/diskload8000.s asm/diskload9600.s asm/fastload8000.s asm/fastload9600.s asm/fastloadcd.s asm/inflate.s
./makeheader ./makeheader
test: bin/c2t-96h bin/c2t-96h.exe tests/test.md test: bin/c2t-96h bin/c2t-96h.exe tests/test.md

View file

@ -39,49 +39,69 @@ You clearly do not understand the awesomeness of the Apple II, move along.
Download <https://github.com/datajerk/c2t/archive/master.zip> and extract. Download <https://github.com/datajerk/c2t/archive/master.zip> and extract.
Both the archive and the repo `bin` directory contain OS/X 64-bit (`c2t`) and Windows 32-bit (`c2t.exe`) binaries. Just copy to any directory in your path. Both the archive and the repo `bin` directory contain macOS 64-bit (`c2t`) and Windows 32-bit (`c2t.exe`) binaries. Just copy to any directory in your path.
> OS/X users may need to adjust the permissions, e.g.: > macOS users may need to adjust the permissions, e.g.:
>
``` ```
cp bin/c2t /usr/local/bin sudo cp bin/c2t bin/c2t-96h /usr/local/bin
cp bin/c2t-96h /usr/local/bin sudo chmod 755 /usr/local/bin/c2t-96h /usr/local/bin/c2t
chmod 755 /usr/local/bin/c2t
chmod 755 /usr/local/bin/c2t-96h
``` ```
An alternative and perhaps simplier install for OS/X: An alternative and perhaps simplier install for macOS:
``` ```
sudo curl https://github.com/datajerk/c2t/raw/master/bin/c2t-96h >/usr/local/bin/c2t-96h sudo curl https://raw.githubusercontent.com/datajerk/c2t/master/bin/c2t-96h >/usr/local/bin/c2t-96h
sudo chmod 755 /usr/local/bin/c2t-96h sudo curl https://raw.githubusercontent.com/datajerk/c2t/master/bin/c2t >/usr/local/bin/c2t
sudo curl https://github.com/datajerk/c2t/raw/master/bin/c2t-96h >/usr/local/bin/c2t sudo chmod 755 /usr/local/bin/c2t-96h /usr/local/bin/c2t
sudo chmod 755 /usr/local/bin/c2t
``` ```
## Build from Source ## Build from Source
Prerequisites: Prerequisites:
- `cl65` version 2.13.3 (<https://github.com/mrdudz/cc65-old/blob/master/cc65-sources-2.13.3.tar.bz2>) - `cl65` version 2.13.3 (<https://github.com/mrdudz/cc65-old/raw/master/cc65-sources-2.13.3.tar.bz2>)
``` ```
git clone https://github.com/datajerk/c2t.git git clone https://github.com/datajerk/c2t.git
``` ```
To build for OS/X or Linux:
### (UNIX, Linux, BSD, macOS (will not be universal), etc...)
``` ```
make clean make clean
make make
``` ```
To build from Windows, first install MinGW (<http://www.mingw.org/>), then type from the root of this distribution: > For Linux, read [ubuntu_notes.md](ubuntu_notes.md) for build tips.
```
PATH=C:\MinGW\bin;%PATH% ### Universal macOS (x86_64/arm64)
gcc -Wall -Wno-unused-value -Wno-unused-function -O3 -static -o c2t c2t.c
```
To cross build for Windows from OS/X, first install <http://crossgcc.rts-software.org/download/gcc-4.8.0-qt-4.8.4-win32/gcc-4.8.0-qt-4.8.4-for-mingw32.dmg>, then type:
``` ```
make clean make clean
make windows # or 'make dist' if you want both OS/X and Windows built make macos
```
### Windows
First install MinGW (<https://osdn.net/projects/mingw/>), then type from the root of this distribution:
```
PATH=C:\MinGW\bin;%PATH%
gcc -Wall -Wno-unused-value -Wno-unused-function -Wno-misleading-indentation -I. -O3 -static -o c2t c2t.c
```
To cross build for Windows from macOS, first install <http://crossgcc.rts-software.org/download/gcc-4.8.0-qt-4.8.4-win32/gcc-4.8.0-qt-4.8.4-for-mingw32.dmg>, then type:
```
make clean
make windows # or 'make dist' if you want both macOS and Windows built
```
> If macOS errors with _cannot be opened because the developer cannot be verified_ with the mingw32 gcc binaries, then type:
>
```
sudo xattr -r -d com.apple.quarantine /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32
``` ```
@ -138,20 +158,29 @@ Single load binaries will auto extract and execute. Disk images will auto extra
## Testing ## Testing
Automated testing is only supported on OS/X and requires the following: Automated testing is only supported on macOS and requires the following:
* Virtual ][ (<http://http://www.virtualii.com/>) * Virtual ][ 10.0.1 (<http://www.virtualii.com/>)
* Windows cross-compiling tools <http://crossgcc.rts-software.org/download/gcc-4.8.0-qt-4.8.4-win32/gcc-4.8.0-qt-4.8.4-for-mingw32.dmg> * Windows cross-compiling tools <http://crossgcc.rts-software.org/download/gcc-4.8.0-qt-4.8.4-win32/gcc-4.8.0-qt-4.8.4-for-mingw32.dmg>
* Wine (<http://winehq.org>) installed in `~/wine` (extract the tarball in `~/wine` and move the contents of `~/wine/usr` to `~/wine`, or change the path to `wine` in `tests/test.sh`). * Docker Desktop for Mac (<https://hub.docker.com/editions/community/docker-ce-desktop-mac/>)
> You can edit `tests/test.md` if you do not want to test Windows binaries or want to use different images for test. > You can edit `tests/test.md` if you do not want to test Windows binaries or want to use different images for test.
Build wine32 container (if testing Windows binaries):
```
# start docker first, make sure it is running
docker build --no-cache -t wine32 -f Dockerfile.wine32 .
```
To test, type: To test, type:
``` ```
make testclean # only once, unless you want to start over make testclean # only once, unless you want to start over
make test make test
``` ```
> If Virtual ][ crashes while testing, just `make test` again to restart failed test and continue where it left off. Do not type `make testclean` again unless you want to start over. > If Virtual ][ crashes while testing, just `make test` again to restart failed test and continue where it left off. Do not type `make testclean` again unless you want to start over.
Example output: <https://youtu.be/FCOb4f2hYN8> Example output: <https://youtu.be/FCOb4f2hYN8>

BIN
bin/c2t

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

204
c2t-96h.c
View file

@ -57,7 +57,6 @@ Notes:
Not yet done: Not yet done:
* Test big-endian. * Test big-endian.
* gnuindent * gnuindent
* Redo malloc code in appendtone
Thinking about: Thinking about:
* Check for existing file and abort, or warn, or prompt. * Check for existing file and abort, or warn, or prompt.
@ -98,23 +97,32 @@ Bugs:
for(wb_j=0;wb_j<8;wb_j++) { \ for(wb_j=0;wb_j<8;wb_j++) { \
if(wb_temp & 0x80) { \ if(wb_temp & 0x80) { \
if(freq1 == 6000) { \ if(freq1 == 6000) { \
appendtone(&output,&outputlength,freq1,rate,0,0.5,&offset); \ appendtone(&buf,freq1,0,0.5); \
appendtone(&output,&outputlength,freq0,rate,0,0.5,&offset); \ appendtone(&buf,freq0,0,0.5); \
} \ } \
else { \ else { \
appendtone(&output,&outputlength,freq1,rate,0,1,&offset); \ appendtone(&buf,freq1,0,1); \
} \ } \
} \ } \
else { \ else { \
appendtone(&output,&outputlength,freq0,rate,0,1,&offset); \ appendtone(&buf,freq0,0,1); \
} \ } \
wb_temp<<=1; \ wb_temp<<=1; \
} \ } \
} }
typedef struct outbuf {
double *sound;
long length;
long capacity;
int offset;
int rate;
} outbuf;
void usage(); void usage();
char *getext(char *filename); char *getext(char *filename);
void appendtone(double **sound, long *length, int freq, int rate, double time, double cycles, int *offset); void outbuf_init(outbuf *buf, int rate);
void appendtone(outbuf *buf, int freq, double time, double cycles);
void Write_AIFF(FILE * fptr, double *samples, long nsamples, int nfreq, int bits, double amp); void Write_AIFF(FILE * fptr, double *samples, long nsamples, int nfreq, int bits, double amp);
void Write_WAVE(FILE * fptr, double *samples, long nsamples, int nfreq, int bits, double amp); void Write_WAVE(FILE * fptr, double *samples, long nsamples, int nfreq, int bits, double amp);
void ConvertToIeeeExtended(double num, unsigned char *bytes); void ConvertToIeeeExtended(double num, unsigned char *bytes);
@ -160,9 +168,9 @@ int square = 1;
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
FILE *ofp; FILE *ofp;
double *output = NULL, amp=0.75; outbuf buf;
long outputlength=0; double amp=0.75;
int i, c, model=0, outputtype, offset=0, fileoutput=1, warm=0, dsk=0, noformat=0, k8=0, qr=0; int i, c, model=0, outputtype, fileoutput=1, warm=0, dsk=0, noformat=0, k8=0, qr=0;
int autoload=0, basicload=0, compress=0, fast=0, cd=0, tape=0, endpage=0, longmon=0, rate=11025, bits=8, freq0=2000, freq1=1000, freq_pre=770, freq_end=770; int autoload=0, basicload=0, compress=0, fast=0, cd=0, tape=0, endpage=0, longmon=0, rate=11025, bits=8, freq0=2000, freq1=1000, freq_pre=770, freq_end=770;
char *filetypes[] = {"binary","monitor","aiff","wave","disk"}; char *filetypes[] = {"binary","monitor","aiff","wave","disk"};
char *modeltypes[] = {"\b","I","II"}; char *modeltypes[] = {"\b","I","II"};
@ -259,7 +267,7 @@ int main(int argc, char **argv)
return 1; return 1;
} }
// read intput files // read input files
fprintf(stderr,"\n"); fprintf(stderr,"\n");
for(i=optind;i<argc-fileoutput;i++) { for(i=optind;i<argc-fileoutput;i++) {
@ -574,6 +582,10 @@ int main(int argc, char **argv)
return 0; return 0;
} }
if(dsk)
rate = 48000;
outbuf_init(&buf, rate);
// write out code // write out code
if(!autoload && !dsk) { if(!autoload && !dsk) {
int i, j; int i, j;
@ -585,13 +597,13 @@ int main(int argc, char **argv)
for(i=0;i<numseg;i++) { for(i=0;i<numseg;i++) {
// header // header
if(model == 1) { if(model == 1) {
appendtone(&output,&outputlength,1000,rate,4.0+tape,0,&offset); appendtone(&buf,1000,4.0+tape,0);
appendtone(&output,&outputlength,2000,rate,0,1,&offset); appendtone(&buf,2000,0,1);
} }
else { else {
appendtone(&output,&outputlength,770,rate,4.0+tape,0,&offset); appendtone(&buf,770,4.0+tape,0);
appendtone(&output,&outputlength,2500,rate,0,0.5,&offset); appendtone(&buf,2500,0,0.5);
appendtone(&output,&outputlength,2000,rate,0,0.5,&offset); appendtone(&buf,2000,0,0.5);
} }
checksum = 0xff; checksum = 0xff;
@ -609,7 +621,7 @@ int main(int argc, char **argv)
// checksum/endbits // checksum/endbits
if(model == 2) if(model == 2)
WRITEBYTE(checksum); WRITEBYTE(checksum);
appendtone(&output,&outputlength,1000,rate,0,1,&offset); appendtone(&buf,1000,0,1);
} }
// friendly help // friendly help
@ -641,9 +653,9 @@ int main(int argc, char **argv)
unsigned int length, move_len; unsigned int length, move_len;
int i, j; int i, j;
appendtone(&output,&outputlength,770,rate,4.0+tape,0,&offset); appendtone(&buf,770,4.0+tape,0);
appendtone(&output,&outputlength,2500,rate,0,0.5,&offset); appendtone(&buf,2500,0,0.5);
appendtone(&output,&outputlength,2000,rate,0,0.5,&offset); appendtone(&buf,2000,0,0.5);
// compute uncompressed ETA // compute uncompressed ETA
for(j=0;j<segments[0].length;j++) { for(j=0;j<segments[0].length;j++) {
@ -826,10 +838,10 @@ int main(int argc, char **argv)
} }
WRITEBYTE(checksum); WRITEBYTE(checksum);
appendtone(&output,&outputlength,1000,rate,0,1,&offset); appendtone(&buf,1000,0,1);
appendtone(&output,&outputlength,770,rate,4.0,0,&offset); appendtone(&buf,770,4.0,0);
appendtone(&output,&outputlength,2500,rate,0,0.5,&offset); appendtone(&buf,2500,0,0.5);
appendtone(&output,&outputlength,2000,rate,0,0.5,&offset); appendtone(&buf,2000,0,0.5);
// write out basic program // write out basic program
checksum = 0xff; checksum = 0xff;
@ -957,13 +969,13 @@ int main(int argc, char **argv)
WRITEBYTE(checksum); WRITEBYTE(checksum);
appendtone(&output,&outputlength,1000,rate,0,1,&offset); appendtone(&buf,1000,0,1);
if(fast || cd || k8) if(fast || cd || k8)
appendtone(&output,&outputlength,freq_pre,rate,0.25,0,&offset); appendtone(&buf,freq_pre,0.25,0);
else { else {
appendtone(&output,&outputlength,770,rate,4.0,0,&offset); appendtone(&buf,770,4.0,0);
appendtone(&output,&outputlength,2500,rate,0,0.5,&offset); appendtone(&buf,2500,0,0.5);
appendtone(&output,&outputlength,2000,rate,0,0.5,&offset); appendtone(&buf,2000,0,0.5);
} }
// now the code // now the code
@ -982,10 +994,10 @@ int main(int argc, char **argv)
if(qr) { if(qr) {
char loading[]="LOADING "; char loading[]="LOADING ";
outputlength = 0; buf.length = 0;
// 0.25 sec // 0.25 sec
appendtone(&output,&outputlength,freq_pre,rate,0.25,0,&offset); appendtone(&buf,freq_pre,0.25,0);
checksum = 0xff; checksum = 0xff;
@ -1026,10 +1038,10 @@ int main(int argc, char **argv)
WRITEBYTE(checksum); WRITEBYTE(checksum);
// end of parameters // end of parameters
appendtone(&output,&outputlength,freq_end,rate,0,2,&offset); appendtone(&buf,freq_end,0,2);
// time to processes // time to processes
appendtone(&output,&outputlength,freq_pre,rate,0.25,0,&offset); appendtone(&buf,freq_pre,0.25,0);
} }
checksum = 0xff; checksum = 0xff;
@ -1053,11 +1065,11 @@ int main(int argc, char **argv)
WRITEBYTE(checksum); WRITEBYTE(checksum);
if(fast || cd || k8) if(fast || cd || k8)
//appendtone(&output,&outputlength,freq_end,rate,0,1,&offset); //appendtone(&buf,freq_end,0,1);
appendtone(&output,&outputlength,freq_end,rate,0,10,&offset); appendtone(&buf,freq_end,0,10);
else else
//appendtone(&output,&outputlength,1000,rate,0,1,&offset); //appendtone(&buf,1000,0,1);
appendtone(&output,&outputlength,1000,rate,0,10,&offset); appendtone(&buf,1000,0,10);
if(!qr) { if(!qr) {
if(basicload) { if(basicload) {
@ -1095,12 +1107,11 @@ int main(int argc, char **argv)
diskloadcode_len = sizeof(diskload9600)/sizeof(char); diskloadcode_len = sizeof(diskload9600)/sizeof(char);
} }
registerevent(events,outputlength,"770Hz Preamble + Sync Bit"); registerevent(events,buf.length,"770Hz Preamble + Sync Bit");
rate = 48000; appendtone(&buf,770,4.0+tape,0);
appendtone(&output,&outputlength,770,rate,4.0+tape,0,&offset); appendtone(&buf,2500,0,0.5);
appendtone(&output,&outputlength,2500,rate,0,0.5,&offset); appendtone(&buf,2000,0,0.5);
appendtone(&output,&outputlength,2000,rate,0,0.5,&offset);
for(j=0;j<sizeof(diskloadcode2)/sizeof(char);j++) { for(j=0;j<sizeof(diskloadcode2)/sizeof(char);j++) {
byte=diskloadcode2[j]; byte=diskloadcode2[j];
@ -1170,14 +1181,14 @@ int main(int argc, char **argv)
} }
WRITEBYTE(checksum); WRITEBYTE(checksum);
registerevent(events,outputlength,"BASIC Header + 770Hz Preamble"); registerevent(events,buf.length,"BASIC Header + 770Hz Preamble");
appendtone(&output,&outputlength,1000,rate,0,1,&offset); appendtone(&buf,1000,0,1);
appendtone(&output,&outputlength,770,rate,4.0,0,&offset); appendtone(&buf,770,4.0,0);
appendtone(&output,&outputlength,2500,rate,0,0.5,&offset); appendtone(&buf,2500,0,0.5);
appendtone(&output,&outputlength,2000,rate,0,0.5,&offset); appendtone(&buf,2000,0,0.5);
registerevent(events,outputlength,"BASIC Stub/Assembly 9600 BPS Code @ 1333 BPS"); registerevent(events,buf.length,"BASIC Stub/Assembly 9600 BPS Code @ 1333 BPS");
// write out basic program // write out basic program
checksum = 0xff; checksum = 0xff;
@ -1203,17 +1214,17 @@ int main(int argc, char **argv)
WRITEBYTE(checksum); WRITEBYTE(checksum);
registerevent(events,outputlength,"INSTA-DISK Code + DOS Load @ 9600 BPS"); registerevent(events,buf.length,"INSTA-DISK Code + DOS Load @ 9600 BPS");
appendtone(&output,&outputlength,1000,rate,0,1,&offset); appendtone(&buf,1000,0,1);
freq0 = 12000; freq0 = 12000;
if(k8) { if(k8) {
freq1 = 6000; freq1 = 6000;
appendtone(&output,&outputlength,2000,rate,0.25,0,&offset); appendtone(&buf,2000,0.25,0);
} }
else { else {
freq1 = 8000; freq1 = 8000;
appendtone(&output,&outputlength,6000,rate,0.25,0,&offset); appendtone(&buf,6000,0.25,0);
} }
checksum = 0xff; checksum = 0xff;
@ -1364,21 +1375,21 @@ int main(int argc, char **argv)
WRITEBYTE(checksum); WRITEBYTE(checksum);
if(k8) { if(k8) {
appendtone(&output,&outputlength,770,rate,0,2,&offset); appendtone(&buf,770,0,2);
appendtone(&output,&outputlength,2000,rate,0.3,0,&offset); appendtone(&buf,2000,0.3,0);
} }
else { else {
appendtone(&output,&outputlength,2000,rate,0,1,&offset); appendtone(&buf,2000,0,1);
appendtone(&output,&outputlength,6000,rate,0.1,0,&offset); appendtone(&buf,6000,0.1,0);
} }
for(i=0;i<numseg;i++) { for(i=0;i<numseg;i++) {
//appendtone(&output,&outputlength,6000,rate,1,0,&offset); //appendtone(&buf,6000,1,0);
//timing //timing
if(i==0) { if(i==0) {
if(!noformat) { if(!noformat) {
registerevent(events,outputlength,"Format Disk Delay (2000 Hz)"); registerevent(events,buf.length,"Format Disk Delay (2000 Hz)");
j=28; j=28;
} }
else else
@ -1397,7 +1408,7 @@ int main(int argc, char **argv)
// CFFA3000 3.1 failed with IBM 4GB Microdrive (too slow) // CFFA3000 3.1 failed with IBM 4GB Microdrive (too slow)
// Nishida Radio SDISK // (no-format only) // Nishida Radio SDISK // (no-format only)
registerevent(events,outputlength,"Inflate + Write Delay (2000 Hz)"); registerevent(events,buf.length,"Inflate + Write Delay (2000 Hz)");
} }
if(i==1) // seek time for track 0, just in case if(i==1) // seek time for track 0, just in case
j+=2; j+=2;
@ -1412,16 +1423,16 @@ int main(int argc, char **argv)
WRITEBYTE(0x00); WRITEBYTE(0x00);
checksum ^= 0x00; checksum ^= 0x00;
WRITEBYTE(checksum); WRITEBYTE(checksum);
appendtone(&output,&outputlength,2000,rate,0,1,&offset); appendtone(&buf,2000,0,1);
appendtone(&output,&outputlength,6000,rate,1,0,&offset); appendtone(&buf,6000,1,0);
} }
*/ */
if(k8) if(k8)
appendtone(&output,&outputlength,2000,rate,j,0,&offset); appendtone(&buf,2000,j,0);
else else
appendtone(&output,&outputlength,6000,rate,j,0,&offset); appendtone(&buf,6000,j,0);
registerevent(events,outputlength,"Load Segment @ 9600 BPS"); registerevent(events,buf.length,"Load Segment @ 9600 BPS");
checksum = 0xff; checksum = 0xff;
for(j=0;j<segments[i].length;j++) { for(j=0;j<segments[i].length;j++) {
@ -1430,44 +1441,53 @@ int main(int argc, char **argv)
} }
WRITEBYTE(checksum); WRITEBYTE(checksum);
if(k8) if(k8)
//appendtone(&output,&outputlength,770,rate,0,2,&offset); //appendtone(&buf,770,0,2);
appendtone(&output,&outputlength,770,rate,0,10,&offset); appendtone(&buf,770,0,10);
else else
//appendtone(&output,&outputlength,2000,rate,0,1,&offset); //appendtone(&buf,2000,0,1);
appendtone(&output,&outputlength,2000,rate,0,10,&offset); appendtone(&buf,2000,0,10);
} }
fprintf(stderr,"Times: Data: %f, Inflate: %f, Audio: %f, File: %s\n\n",total_data_time,total_inflate_time,outputlength/(float)rate,segments[0].filename); fprintf(stderr,"Times: Data: %f, Inflate: %f, Audio: %f, File: %s\n\n",total_data_time,total_inflate_time,buf.length/(float)rate,segments[0].filename);
registerevent(events,outputlength,"Inflate + Exit"); registerevent(events,buf.length,"Inflate + Exit");
printevents(events,rate); printevents(events,rate);
fprintf(stderr,"To load up and run on your Apple %s, type:\n\n\tLOAD\n\n",modeltypes[model]); fprintf(stderr,"To load up and run on your Apple %s, type:\n\n\tLOAD\n\n",modeltypes[model]);
} }
// append zero to zero out last wave // append zero to zero out last wave
appendtone(&output,&outputlength,0,rate,0,1,&offset); appendtone(&buf,0,0,1);
// 0.1 sec quiet to help some emulators // 0.1 sec quiet to help some emulators
appendtone(&output,&outputlength,0,rate,0.1,0,&offset); appendtone(&buf,0,0.1,0);
// 0.4 sec quiet to help some IIs // 0.4 sec quiet to help some IIs
// appendtone(&output,&outputlength,0,rate,0.4,0,&offset); // appendtone(&buf,0,0.4,0);
// write it // write it
if(outputtype == AIFF) if(outputtype == AIFF)
Write_AIFF(ofp,output,outputlength,rate,bits,amp); Write_AIFF(ofp,buf.sound,buf.length,rate,bits,amp);
else if(outputtype == WAVE) else if(outputtype == WAVE)
Write_WAVE(ofp,output,outputlength,rate,bits,amp); Write_WAVE(ofp,buf.sound,buf.length,rate,bits,amp);
fclose(ofp); fclose(ofp);
return 0; return 0;
} }
void appendtone(double **sound, long *length, int freq, int rate, double time, double cycles, int *offset) void outbuf_init(outbuf *buf, int rate)
{ {
buf->capacity = 65536;
buf->sound = (double *)malloc(buf->capacity * sizeof(double));
buf->length = 0;
buf->offset = 0;
buf->rate = rate;
}
void appendtone(outbuf *buf, int freq, double time, double cycles)
{
int rate = buf->rate;
int length = buf->length;
long i, n=time*rate; long i, n=time*rate;
static long grow = 0;
double *tmp = NULL;
if(freq && cycles) if(freq && cycles)
n=cycles*rate/freq; n=cycles*rate/freq;
@ -1481,13 +1501,17 @@ void appendtone(double **sound, long *length, int freq, int rate, double time, d
*sound = tmp; *sound = tmp;
*/ */
// new code for speed up realloc // grow capacity of buffer if needed, using size-doubling approach
// should use double alg if(buf->capacity < length + n) {
if(*length + n > grow) { long new_cap = buf->capacity;
grow = *length + n + 1000000; while(new_cap < length + n) {
if((tmp = (double *)realloc(*sound, (grow) * sizeof(double))) == NULL) new_cap *= 2;
}
double *tmp = (double *)realloc(buf->sound, new_cap * sizeof(double));
if(tmp == NULL)
abort(); abort();
*sound = tmp; buf->sound = tmp;
buf->capacity = new_cap;
} }
//tmp -> (*sound) //tmp -> (*sound)
@ -1501,26 +1525,26 @@ void appendtone(double **sound, long *length, int freq, int rate, double time, d
if(square) { if(square) {
double last = -1; double last = -1;
if(*offset) if(buf->offset)
last = 1; last = 1;
if(freq) if(freq)
for(i=0;i<n;i++) { for(i=0;i<n;i++) {
double a = (int)(1000*sin(2*M_PI*i*freq/rate + *offset*M_PI)) / 1000.0; double a = (int)(1000*sin(2*M_PI*i*freq/rate + buf->offset*M_PI)) / 1000.0;
last = (*sound)[*length+i] = (a == 0) ? -((last > 0) - (last < 0)) : ((a > 0) - (a < 0)); last = buf->sound[length+i] = (a == 0) ? -((last > 0) - (last < 0)) : ((a > 0) - (a < 0));
} }
else else
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
(*sound)[*length + i] = 0; buf->sound[length + i] = 0;
} }
else else
for(i=0;i<n;i++) for(i=0;i<n;i++)
(*sound)[*length+i] = sin(2*M_PI*i*freq/rate + *offset*M_PI); buf->sound[length+i] = sin(2*M_PI*i*freq/rate + buf->offset*M_PI);
if(cycles - (int)cycles == 0.5) if(cycles - (int)cycles == 0.5)
*offset = (*offset == 0); buf->offset = (buf->offset == 0);
*length += n; buf->length += n;
} }
char *getext(char *filename) char *getext(char *filename)

2
c2t.h
View file

@ -50,7 +50,7 @@ Examples:\n\
c2t -2f moon.patrol,801 moon.patrol.aif\n\ c2t -2f moon.patrol,801 moon.patrol.aif\n\
c2t -2 hello,300 hello.aiff\n\ c2t -2 hello,300 hello.aiff\n\
c2t -1 hello.mon hello.wav\n\ c2t -1 hello.mon hello.wav\n\
c2t -2 thief,801 thief.obj,3ffd thief.pic,2000 theif.aif\n\ c2t -2 thief,801 thief.obj,3ffd thief.pic,2000 thief.aif\n\
c2t foo.dsk foo.wav\n\ c2t foo.dsk foo.wav\n\
\n\ \n\
"; ";

View file

@ -50,7 +50,7 @@ Examples:\n\
c2t -2f moon.patrol,801 moon.patrol.aif\n\ c2t -2f moon.patrol,801 moon.patrol.aif\n\
c2t -2 hello,300 hello.aiff\n\ c2t -2 hello,300 hello.aiff\n\
c2t -1 hello.mon hello.wav\n\ c2t -1 hello.mon hello.wav\n\
c2t -2 thief,801 thief.obj,3ffd thief.pic,2000 theif.aif\n\ c2t -2 thief,801 thief.obj,3ffd thief.pic,2000 thief.aif\n\
c2t foo.dsk foo.wav\n\ c2t foo.dsk foo.wav\n\
\n\ \n\
"; ";

View file

@ -5,7 +5,7 @@ header()
FILE=$1 FILE=$1
VAR=$2 VAR=$2
EOL=$3 EOL=$3
BYTES=$(hexdump -v $FILE | sed 's/^.......//' | wc -w | awk '{print $1}'); BYTES=$(hexdump -ve '1/1 "%.2x "' $FILE | wc -w | awk '{print $1}');
echo "/*" echo "/*"
expand ${FILE}.s expand ${FILE}.s
@ -13,7 +13,7 @@ header()
printf "unsigned char $VAR[] = {\n\t" printf "unsigned char $VAR[] = {\n\t"
for i in $(hexdump -v $FILE | sed 's/^.......//'); for i in $(hexdump -ve '1/1 "%.2x "' $FILE);
do do
printf "0x%02X" 0x$i printf "0x%02X" 0x$i
BYTES=$((BYTES - 1)) BYTES=$((BYTES - 1))
@ -76,3 +76,5 @@ cat mon/dos33.boot2.mon | \
echo "};" >>c2t.h.2 echo "};" >>c2t.h.2
cat c2t.h.[012] > c2t.h cat c2t.h.[012] > c2t.h
rm -f c2t.h.[12]

3
tests/dwine Executable file
View file

@ -0,0 +1,3 @@
#!/bin/bash
docker run --rm -it -v $PWD/..:/pwd wine32 bash -c "cd /pwd/tests && wine $*"

View file

@ -1,7 +1,7 @@
## Automated Tests ## Automated Tests
| Test | Command | Input | Machine | Load | Compare | Offset | Timeout | | Test | Command | Input | Machine | Load | Compare | Offset | Timeout |
|:----:|-------------------------------|-------------------|---------|---------------|-------------|:------:|:-------:| |:----:|--------------------------------|-------------------|---------|---------------|-------------|:------:|:-------:|
| 1 | ../bin/c2t-96h | zork.dsk | iie | LOAD | dskiie.tiff | 0 | 25 | | 1 | ../bin/c2t-96h | zork.dsk | iie | LOAD | dskiie.tiff | 0 | 25 |
| 2 | ../bin/c2t-96h | dd.po | iie | LOAD | dskiie.tiff | 0 | 25 | | 2 | ../bin/c2t-96h | dd.po | iie | LOAD | dskiie.tiff | 0 | 25 |
| 3 | ../bin/c2t-96h | zork.dsk | iip | LOAD | dskiip.tiff | 0 | 25 | | 3 | ../bin/c2t-96h | zork.dsk | iip | LOAD | dskiip.tiff | 0 | 25 |
@ -12,15 +12,15 @@
| 8 | ../bin/c2t-96h -2bc8 | super_puckman,800 | iie | LOAD | spiie.tiff | 0 | 25 | | 8 | ../bin/c2t-96h -2bc8 | super_puckman,800 | iie | LOAD | spiie.tiff | 0 | 25 |
| 9 | ../bin/c2t-96h -2bc8 | super_puckman,800 | iip | LOAD | spiie.tiff | 0 | 25 | | 9 | ../bin/c2t-96h -2bc8 | super_puckman,800 | iip | LOAD | spiie.tiff | 0 | 25 |
| 10 | ../bin/c2t-96h -2ac8 | super_puckman,800 | ii | 800.A00R 800G | spiie.tiff | 0 | 25 | | 10 | ../bin/c2t-96h -2ac8 | super_puckman,800 | ii | 800.A00R 800G | spiie.tiff | 0 | 25 |
| 11 | wine ../bin/c2t-96h.exe | zork.dsk | iie | LOAD | dskiie.tiff | 0 | 25 | | 11 | dwine ../bin/c2t-96h.exe | zork.dsk | iie | LOAD | dskiie.tiff | 0 | 25 |
| 12 | wine ../bin/c2t-96h.exe | dd.po | iie | LOAD | dskiie.tiff | 0 | 25 | | 12 | dwine ../bin/c2t-96h.exe | dd.po | iie | LOAD | dskiie.tiff | 0 | 25 |
| 13 | wine ../bin/c2t-96h.exe | zork.dsk | iip | LOAD | dskiip.tiff | 0 | 25 | | 13 | dwine ../bin/c2t-96h.exe | zork.dsk | iip | LOAD | dskiip.tiff | 0 | 25 |
| 14 | wine ../bin/c2t-96h.exe | dd.po | iip | LOAD | dskiip.tiff | 0 | 25 | | 14 | dwine ../bin/c2t-96h.exe | dd.po | iip | LOAD | dskiip.tiff | 0 | 25 |
| 15 | wine ../bin/c2t-96h.exe -2bcf | moon.patrol,801 | iie | LOAD | mpiie.tiff | 0 | 25 | | 15 | dwine ../bin/c2t-96h.exe -2bcf | moon.patrol,801 | iie | LOAD | mpiie.tiff | 0 | 25 |
| 16 | wine ../bin/c2t-96h.exe -2bcf | moon.patrol,801 | iip | LOAD | mpiie.tiff | 0 | 25 | | 16 | dwine ../bin/c2t-96h.exe -2bcf | moon.patrol,801 | iip | LOAD | mpiie.tiff | 0 | 25 |
| 17 | wine ../bin/c2t-96h.exe -2acf | moon.patrol,801 | ii | 800.A00R 800G | mpii.tiff | 0 | 25 | | 17 | dwine ../bin/c2t-96h.exe -2acf | moon.patrol,801 | ii | 800.A00R 800G | mpii.tiff | 0 | 25 |
| 18 | wine ../bin/c2t-96h.exe -2bc8 | super_puckman,800 | iie | LOAD | spiie.tiff | 0 | 25 | | 18 | dwine ../bin/c2t-96h.exe -2bc8 | super_puckman,800 | iie | LOAD | spiie.tiff | 0 | 25 |
| 19 | wine ../bin/c2t-96h.exe -2bc8 | super_puckman,800 | iip | LOAD | spiie.tiff | 0 | 25 | | 19 | dwine ../bin/c2t-96h.exe -2bc8 | super_puckman,800 | iip | LOAD | spiie.tiff | 0 | 25 |
| 20 | wine ../bin/c2t-96h.exe -2ac8 | super_puckman,800 | ii | 800.A00R 800G | spiie.tiff | 0 | 25 | | 20 | dwine ../bin/c2t-96h.exe -2ac8 | super_puckman,800 | ii | 800.A00R 800G | spiie.tiff | 0 | 25 |
### Future Edit Instructions Here ### Future Edit Instructions Here

View file

@ -9,6 +9,7 @@ on run argv
set my_timeout to item 6 of argv set my_timeout to item 6 of argv
tell application "Virtual ][" tell application "Virtual ]["
-- tell application "/Applications/Virtual ][/7.6/Virtual ][.app"
activate activate
delay 1.5 delay 1.5
-- Close all open machines -- Close all open machines
@ -25,7 +26,7 @@ on run argv
end if end if
tell theMachine tell theMachine
-- Change to a color screen -- Change to a color screen
-- set monochrome screen to false set monochrome screen to false
set scanlines to true set scanlines to true
set speaker volume to 0.25 set speaker volume to 0.25
if dsk = "1" then if dsk = "1" then

View file

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# Path to wine binary for testing Windows binary # Path to wine binary for testing Windows binary
PATH=~/wine/bin:$PATH PATH=.:$PATH
TESTS=$1 TESTS=$1
IMAGES=images IMAGES=images

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

49
ubuntu_notes.md Normal file
View file

@ -0,0 +1,49 @@
# Ubuntu Build Notes
> Assumes building from your home directory. Tested with `docker run --rm -it ubuntu:21.04 /bin/bash`
## deps
```
cd
sudo apt-get -qy update
sudo apt-get -qy install build-essential git curl bsdmainutils unzip
curl -LO https://github.com/mrdudz/cc65-old/raw/master/cc65-sources-2.13.3.tar.bz2
tar xvf cc65-sources-2.13.3.tar.bz2
cd cc65-2.13.3/
sed -i 's!/usr/local!'$HOME/cc65-2.13.3.bin'!' make/gcc.mak
mkdir -p $HOME/cc65-2.13.3.bin
make -f make/gcc.mak
make -f make/gcc.mak install
```
## build
```
cd
export PATH=$HOME/cc65-2.13.3.bin/bin:$PATH
git clone https://github.com/datajerk/c2t
cd c2t
make clean
make
ls -l bin
```
You should see c2t, c2t-96h
## test
```
cd
curl -O https://asciiexpress.net/diskserver/virtualapple.org/Zork%20I.wav
curl -O https://asciiexpress.net/diskserver/virtualapple.org/ZorkI.zip
unzip ZorkI.zip
c2t/bin/c2t-96h Zork\ I.dsk zork1.wav
md5sum *.wav
```
Sums should match:
```
9c6036d312c4a8303d664d26ad91e35c Zork%20I.wav
9c6036d312c4a8303d664d26ad91e35c zork1.wav
```