パソコンから3バイト単位(アドレス16ビット、データ8ビット)で信号を送ることができるようになりました。クロック43Hz、アドレス+データ24ビット、リセット信号をキーボドから入力した値に応じて送りLEDを点灯しています。最後のビットを送った後に書き込み信号を送ることができればROMに書き込みができるはずです。

#include <iostream>
#include <windows.h>
#include <math.h>
#include <MMSystem.h>
#pragma comment (lib, "winmm.lib")
constexpr auto SAMPLING = 192000;
constexpr auto CHANNEL = 2;
constexpr auto BITSPERSAMPLE = 16;
constexpr auto MAXAMP = 32767;
constexpr auto DIV = 4;
constexpr auto BUFFERING = 10;
void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) {
double wavelength = (double)sampling / (double)frequency;
double d = 360.0 / wavelength;
double pi = 3.14159265359;
for (int i = 0; i < wavelength; i++) {
lpData[i] = (WORD)(amplitude * sin(d * i / 180.0 * pi));
}
}
BOOLEAN isON(unsigned char data, size_t bit, size_t bitLength, size_t value) {
int oneByte = 8;
for (int i = 0; i < oneByte; i++) {
unsigned char mask = 0x80 >> i;
if (((data & mask) == mask) &&
(bitLength *((bit-oneByte )+i)) <= (value % (bitLength * bit)) &&
(value % (bitLength * bit)) < (bitLength * ((bit - oneByte + 1) + i))) {
return true;
}
}
return false;
}
DWORD soundOut(
LPWORD *lpWaveData,
HWAVEOUT hWaveOut,
unsigned char data,
size_t bit,
size_t cFrequency,
BOOL reset
) {
LPWORD lpSinWave;
LPWORD lpWave;
LPWORD lpWave1;
LPWORD lpWave2;
LPWORD lpWave3;
LPWORD lpWave4;
size_t i, j, end;
size_t cWavelength = SAMPLING / cFrequency;
size_t dataLength = (size_t)CHANNEL * (BITSPERSAMPLE / 8) * cWavelength * bit;
size_t dWavelength;
size_t dFrequency;
WORD amplitude = MAXAMP / DIV;
lpWave = (LPWORD)calloc(sizeof(WORD), dataLength);
lpWave1 = (LPWORD)calloc(sizeof(WORD), dataLength);
lpWave2 = (LPWORD)calloc(sizeof(WORD), dataLength);
lpWave3 = (LPWORD)calloc(sizeof(WORD), dataLength);
lpWave4 = (LPWORD)calloc(sizeof(WORD), dataLength);
end = dataLength/(BITSPERSAMPLE / 8);
for (i = 0; i < end; i++) {
lpWave[i] = 0;
lpWave1[i] = 0;
lpWave2[i] = 0;
lpWave3[i] = 0;
lpWave4[i] = 0;
}
/* チャンネル1 ********************************/
lpSinWave = (LPWORD)calloc(sizeof(WORD), cWavelength);
createWave(lpSinWave, cFrequency, SAMPLING, MAXAMP);
for (i = 0, j = 0; i < end; i += CHANNEL) {
lpWave[i] = lpSinWave[j];
++j;
if (j >= cWavelength) { j = 0; }
}
free(lpSinWave);
/* チャンネル2 ********************************/
// クロック
dFrequency = 3200;
dWavelength = SAMPLING / dFrequency;
lpSinWave = (LPWORD)calloc(sizeof(WORD), dWavelength);
createWave(lpSinWave, dFrequency, SAMPLING, amplitude);
for (i = 1, j = 0; i < end; i += CHANNEL) {
lpWave1[i] = lpSinWave[j];
++j;
if (j >= dWavelength) { j = 0; }
}
for (i = 1, j = 0; i < end; i += CHANNEL, ++j) {
if (j < cWavelength/2) { lpWave1[i] = 0; }
if (j >= cWavelength) { j = 0; }
}
free(lpSinWave);
// 制御データ
dFrequency = 8000;
dWavelength = SAMPLING / dFrequency;
lpSinWave = (LPWORD)calloc(sizeof(WORD), dWavelength);
createWave(lpSinWave, dFrequency, SAMPLING, amplitude);
for (i = 1, j = 0; i < end; i += CHANNEL) {
lpWave2[i] = lpSinWave[j];
++j;
if (j >= dWavelength) { j = 0; }
}
for (i = 1, j = 0; i < end; i += CHANNEL, ++j) {
if (j < cWavelength/1.2) { lpWave2[i] = 0; }
if (j >= cWavelength) { j = 0; }
}
free(lpSinWave);
// シリアルデータ2
dFrequency = 11300;
dWavelength = SAMPLING / dFrequency;
lpSinWave = (LPWORD)calloc(sizeof(WORD), dWavelength);
createWave(lpSinWave, dFrequency, SAMPLING, amplitude);
for (i = 1, j = 0; i < end; i += CHANNEL, ++j) {
lpWave3[i] = lpSinWave[j];
if (j >= dWavelength) { j = 0; }
}
for (i = 1; i < end; i += CHANNEL) {
if (isON(data, bit, cWavelength * CHANNEL, i)) {
lpWave3[i] = 0;
}
}
free(lpSinWave);
// リセット
if (reset) {
dFrequency = 17000;
dWavelength = SAMPLING / dFrequency;
lpSinWave = (LPWORD)calloc(sizeof(WORD), dWavelength);
createWave(lpSinWave, dFrequency, SAMPLING, amplitude);
for (i = 1, j = 0; i < cWavelength; i += CHANNEL, ++j) {
lpWave4[i] = lpSinWave[j];
if (j >= dWavelength) { j = 0; }
}
free(lpSinWave);
}
// チャンネル2に合成
for (i = 1; i < end; i += CHANNEL) {
lpWave[i] = lpWave1[i] + lpWave2[i] + lpWave3[i] + lpWave4[i];
}
*lpWaveData = lpWave;
return (DWORD)dataLength;
}
int main() {
LPWORD lpWave[BUFFERING];
WAVEHDR whdr[BUFFERING];
WAVEFORMATEX wfe;
HWAVEOUT hWaveOut;
wfe.wFormatTag = WAVE_FORMAT_PCM;
wfe.nChannels = CHANNEL;
wfe.wBitsPerSample = BITSPERSAMPLE;
wfe.nBlockAlign = CHANNEL * BITSPERSAMPLE / 8;
wfe.nSamplesPerSec = SAMPLING;
wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign;
waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL);
for (int i = 0; i < BUFFERING; i++) {
whdr[i].dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
whdr[i].dwLoops = 1;
lpWave[i] = NULL;
}
std::string str;
do {
std::cout << "2桁毎の16進コードを入力しEnterを押して下さい。(00 ~ FF)" << std::endl;
std::cout << "続けて入力する場合は間を空けないでください。" << std::endl;
std::cout << "Ctrl+Zを入力しEnterで終了します。" << std::endl;
std::cin >> str;
// Ctrl+Zで終了
if (std::cin.eof()) { break; }
char strData[3];
strData[2] = 0x00;
size_t bit = 9;
size_t frequency = 43;
int freeBuffer = 0;
for (int i = 0, j = 0, k = 0; i < str.size(); i += 2, j++, k++) {
if (j >= BUFFERING) {
j = 0;
}
freeBuffer = j + 1;
if (freeBuffer >= BUFFERING) {
freeBuffer = 0;
}
if (lpWave[freeBuffer] != NULL) {
std::cout << "free=" << std::dec << freeBuffer << std::endl;
free(lpWave[freeBuffer]);
lpWave[freeBuffer] = NULL;
}
strData[0] = str[i];
strData[1] = str[(size_t)i + 1];
// 入力された文字列をデータに変換
unsigned char data = (unsigned char)strtol(strData, NULL, 16);
// サウンド出力
if (i % 3 == 0) {
whdr[j].dwBufferLength = soundOut(&lpWave[j], hWaveOut, data, bit, frequency, true);
}
else {
whdr[j].dwBufferLength = soundOut(&lpWave[j], hWaveOut, data, bit-1, frequency, false);
}
whdr[j].lpData = (LPSTR)lpWave[j];
waveOutPrepareHeader(hWaveOut, &whdr[j], sizeof(WAVEHDR));
waveOutWrite(hWaveOut, &whdr[j], sizeof(WAVEHDR));
std::cout << "no=" << std::dec << j << ", data=" << std::hex << (int)data << "H" << std::endl;
if (k > BUFFERING-3) {
Sleep((1000 * (DWORD)bit) / (DWORD)frequency);
}
}
int num = (int)str.size() / 2;
if (num == 0) {
num = 1;
}
else if (num > BUFFERING) {
num = BUFFERING;
}
Sleep((1000 * (DWORD)bit * (num +1)) / (DWORD)frequency);
for (int i = 0; i < num; i++) {
if (lpWave[i] != NULL) {
std::cout << "free=" << std::dec << i << std::endl;
free(lpWave[i]);
lpWave[i] = NULL;
}
}
} while (true);
waveOutClose(hWaveOut);
}