Add code and readme
This commit is contained in:
parent
1970448668
commit
1278fa3e47
63
README.md
63
README.md
|
@ -1,3 +1,62 @@
|
||||||
# baud
|
---
|
||||||
|
title: baud.c
|
||||||
|
---
|
||||||
|
|
||||||
Modem simulator
|
[baud.c](baud.c) is a program to simulate going through a modem.
|
||||||
|
It reads stdin, and prints it to stdout at the provided baud rate (bits per second).
|
||||||
|
|
||||||
|
|
||||||
|
Building
|
||||||
|
--------
|
||||||
|
|
||||||
|
Download [baud.c](baud.c). Change to that directory, and type
|
||||||
|
|
||||||
|
make baud
|
||||||
|
|
||||||
|
That will generate a file named `baud` in whatever directory you're in.
|
||||||
|
If you like,
|
||||||
|
you can put it in `~/bin` or `~/.local/bin` or `/usr/games/bin` or
|
||||||
|
wherever you prefer.
|
||||||
|
|
||||||
|
|
||||||
|
Running
|
||||||
|
-------
|
||||||
|
|
||||||
|
If you'd like to see what life was like when I got my first modem, try
|
||||||
|
|
||||||
|
cat file | ./baud 110 40
|
||||||
|
|
||||||
|
Run that for a few hours, then try
|
||||||
|
|
||||||
|
cat file | ./baud 1200 20
|
||||||
|
|
||||||
|
And you will understand how mind-blowingly fast 1200 baud modems were at the time.
|
||||||
|
|
||||||
|
frotz zork1.zip | ./baud 4800
|
||||||
|
|
||||||
|
Gives Zork a retro vibe,
|
||||||
|
without being so slow that it's aggravating.
|
||||||
|
I don't think more than a dozen or so people every played Zork over a modem link,
|
||||||
|
but whatever.
|
||||||
|
|
||||||
|
|
||||||
|
Why
|
||||||
|
---
|
||||||
|
|
||||||
|
Every 10 years or so, somebody asks me for this program.
|
||||||
|
I don't know why.
|
||||||
|
|
||||||
|
The other day it happened again, and I couldn't find it soon enough,
|
||||||
|
so I just wrote it again from scratch.
|
||||||
|
I'm putting it on my web site so I don't have to write it again.
|
||||||
|
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
I'm placing this in the public domain.
|
||||||
|
So there's no license.
|
||||||
|
|
||||||
|
Some jurisdictions don't recognize the existence of a public domain.
|
||||||
|
If you live in one of those,
|
||||||
|
you can use the terms of [Creative Commons 0](COPYING.txt).
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* Pretend to be a modem by throttling output.
|
||||||
|
*
|
||||||
|
* 2023-09-12
|
||||||
|
* Neale Pickett <neale@woozle.org>
|
||||||
|
*
|
||||||
|
* To the extent possible under law,
|
||||||
|
* I waive all copyright and related or neighboring rights to this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <sysexits.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
const int MICROSECOND = 1;
|
||||||
|
const int MILLISECOND = 1000 * MICROSECOND;
|
||||||
|
const int SECOND = 1000 * MILLISECOND;
|
||||||
|
|
||||||
|
const int NOISINESS_DENOMINATOR = 36000;
|
||||||
|
const int NOISELEN_DEFAULT = 16;
|
||||||
|
|
||||||
|
int
|
||||||
|
usage(char *me, char *error) {
|
||||||
|
if (error) {
|
||||||
|
fprintf(stderr, "ERROR: %s\n", error);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "Usage: %s BAUD [NOISINESS] [NOISELEN]\n", me);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr, "Reads stdin, and writes it back to stdout at BAUD bits per second.\n");
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr, "NOISINESS\tEvery bit can begin line noise, with probability NOISINESS/%d\n", NOISINESS_DENOMINATOR);
|
||||||
|
fprintf(stderr, "NOISELEN\tUp to this many bits of noise happens per burst (default: %d)\n", NOISELEN_DEFAULT);
|
||||||
|
return EX_USAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[]) {
|
||||||
|
if (argc < 2) {
|
||||||
|
return usage(argv[0], NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int baud = atoi(argv[1]);
|
||||||
|
if (baud < 1) {
|
||||||
|
return usage(argv[0], "Invalid baud rate");
|
||||||
|
}
|
||||||
|
|
||||||
|
int noisiness = 0;
|
||||||
|
if (argc > 2) {
|
||||||
|
noisiness = atoi(argv[2]);
|
||||||
|
}
|
||||||
|
int noiselen = NOISELEN_DEFAULT;
|
||||||
|
if (argc > 3) {
|
||||||
|
noiselen = atoi(argv[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cps = baud / 10; // 8N1 has 10 bits per octet: 8 data, 1 start, 1 parity
|
||||||
|
int delay = SECOND / cps;
|
||||||
|
int noisybits = 0;
|
||||||
|
int c;
|
||||||
|
while ((c = getchar()) != EOF) {
|
||||||
|
usleep(delay);
|
||||||
|
for (int bit = 0; bit < 8; bit++) {
|
||||||
|
int r = rand() % NOISINESS_DENOMINATOR;
|
||||||
|
if (r < noisiness) {
|
||||||
|
noisybits = rand() % noiselen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noisybits) {
|
||||||
|
c ^= (rand() & 1) << bit;
|
||||||
|
noisybits -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
putchar(c);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EX_OK;
|
||||||
|
}
|
Loading…
Reference in New Issue