Saya suka game komputer lama. Saya suka besi tua, tetapi tidak cukup untuk mengumpulkannya di rumah. Hal lain adalah memilih chip lama dan mencoba mereproduksi sesuatu sendiri, gabungkan yang lama dengan yang baru. Pada artikel ini, ceritanya tentang bagaimana saya menghubungkan mikrokontroler AVR ke YM3812, yang digunakan dalam kartu suara seperti Adlib, Sound Blaster dan Pro AudioSpectrum. Saya tidak menciptakan sesuatu yang pada dasarnya baru, saya hanya menggabungkan berbagai ide. Mungkin seseorang akan tertarik dengan implementasi saya. Atau mungkin pengalaman saya akan mendorong seseorang untuk membuat proyek retro mereka sendiri.

Berjalan di Internet, suatu hari saya menemukan proyek yang menarik Dewan Audio OPL2 untuk Arduino & Raspberry Pi . Singkatnya: sambungkan papan ke Arduino atau Raspberry Pi, muat sketsa atau perangkat lunak, masing-masing, dengarkan. Gagasan yang menggoda untuk memilih chip OPL2, mendengarkan bunyinya dan mencoba melakukan sesuatu sendiri tidak meninggalkan saya, dan saya memesan, mengumpulkan, dan mulai mencari tahu cara kerjanya.
Beberapa kata tentang manajemen chip YM3812
Agar musik dapat diputar, kita harus mengatur register. Beberapa bertanggung jawab untuk menyetel instrumen, beberapa untuk memainkan catatan, dll. Alamat register adalah 8 bit. Nilai register adalah 8 bit. Daftar register diberikan dalam spesifikasi .
Untuk mentransfer register, kita harus mengatur pembacaan dengan benar pada input kontrol CS, RD, WR dan A0 dan bus data D0..D7.
Input CS diperlukan untuk memblokir bus data selama instalasi. Set CS = 1 (matikan input), set D0..D7, set CS = 0 (nyalakan).
Input RD harus unit logis
Untuk menulis alamat register, atur WR = 0, A0 = 0
Untuk menulis nilai register, atur WR = 0, A0 = 1
Papan Audio OPL2 untuk Arduino & Raspberry Pi

Registrasi Prosedur Transfer:
- Selama inisialisasi, atur PB2 = 1 untuk memblokir input
YM3812
- Kami melewati alamat register
2.1 PB1 = 0 (A0 = 0)
2.2 Kami mengirimkan byte alamat register melalui antarmuka SPI. Data disimpan dalam register geser 74595
2.3 PB2 = 0 (WR = 0, CS = 0). Chip 7404 membalikkan sinyal dan memasok 1 ke input ST_CP 74595
, yang mengalihkan outputnya Q0..Q7. YM3812
menulis alamat register
2.4 PB2 = 1 (WR = 1, CS = 1) - Kami melewati nilai register
3.1 PB1 = 1 (A0 = 1)
3.2 Kami mentransfer byte data melalui antarmuka SPI yang serupa dengan hal.2.2
3,3 PB2 = 0 (WR = 0, CS = 0). YM3812
menulis data
3,4 PB2 = 1 (WR = 1, CS = 1)
Inverter 7404
dan kuarsa XTAL1
mengimplementasikan generator pulsa persegi panjang dengan frekuensi 3,579545 MHz, yang diperlukan untuk pengoperasian YM3812
.
YM3014B
mengubah sinyal digital menjadi sinyal analog, yang diperkuat oleh penguat operasional LM358
.
Penguat audio LM386
diperlukan agar speaker atau headphone pasif dapat dihubungkan ke perangkat Daya LM358
tidak cukup.
Sekarang mari kita coba mengekstrak suara dari semua ini. Hal pertama yang saya (dan mungkin bukan hanya saya) pikirkan adalah bagaimana membuat semuanya berfungsi di DosBox. Sayangnya, bermain di luar kotak dengan perangkat keras Adlib tidak akan berhasil, karena DosBox tidak tahu apa-apa tentang perangkat kami, dan tidak tahu bagaimana mengirimkan perintah OPL2 di mana saja (sejauh ini tidak).
Penulis proyek menawarkan sketsa untuk Teensy, yang berfungsi sebagai perangkat MIDI. Secara alami, suara akan terdiri dari instrumen yang telah dikompilasi dan suara akan berbeda, kita akan mendapatkan emulasi perangkat MIDI pada chip OPL2. Saya tidak punya Teensy, dan saya tidak bisa mencoba opsi ini.
Operasi Port Serial
Ada SerialPassthrough sketsa. Dengan itu, kita dapat mengirimkan perintah melalui port serial. Tetap hanya menerapkan dukungan di DoxBox. Saya menggunakan versi dari SVN: svn://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk
Dalam file src/hardware/adlib.cpp
kami mengubah implementasi OPL2:
#include "serialport/libserial.h" namespace OPL2 { #include "opl.cpp" struct Handler : public Adlib::Handler { virtual void WriteReg( Bit32u reg, Bit8u val ) {
Sebelum perakitan, ganti nomor port COM dengan yang sekarang.
Jika Anda menghapus komentar di baris //adlib_write(reg,val);
, maka suara akan diputar secara simultan melalui emulator dan perangkat.
Di pengaturan DosBox, Anda perlu menentukan penggunaan OPL2:
[sblaster] oplemu=compat oplmode=opl2
Begini cara saya mendapatkannya:
Itu terlihat cukup besar. Bahkan jika Anda menggunakan Arduino alih-alih papan tempat memotong roti, Anda perlu menghubungkan kabel. Nomor port pada sistem dapat berubah dan Anda harus membangun kembali DosBox. Saya benar-benar ingin membawa semuanya ke tampilan yang ringkas, menghapus bagian yang tidak perlu dan mengumpulkan semuanya di satu papan.
OPL2-USB
Sebuah ide muncul, dan mengapa tidak membuat perangkat independen dengan minimum komponen dan masalah saat terhubung. Pertama, Anda dapat menghapus 74595
dan menggunakan port atmega. Di sini digunakan hanya untuk mengurangi jumlah kabel. Kedua, Anda dapat menggunakan osilator kristal yang sudah jadi dan menyingkirkan chip 7404
. Penguat audio juga tidak diperlukan jika Anda menghubungkan perangkat ke speaker. Dan akhirnya, Anda dapat menyingkirkan USB-UART jika Anda menghubungkan atmega ke USB secara langsung, misalnya menggunakan perpustakaan V-USB: https://www.obdev.at/products/vusb/index.html . Agar tidak perlu repot menulis driver dan menginstalnya, Anda dapat menjadikan mikrokontroler sebagai perangkat HID khusus.

Port B dan C sebagian sibuk menghubungkan ke programmer ISP dan kuarsa. Port D tetap sepenuhnya gratis, kami menggunakannya untuk transfer data. Saya menetapkan port yang tersisa dalam proses desain PCB.
Skema lengkap dapat dipelajari di sini: https://easyeda.com/marchukov.ivan/opl2usb
LED1
dengan resistornya adalah opsional dan selama perakitan saya tidak menginstalnya. Sekering U4 diperlukan agar tidak secara sengaja membakar port USB. Itu juga tidak bisa diatur, tetapi diganti dengan jumper.
Untuk membuat perangkat kompak, saya memutuskan untuk mencoba merakitnya pada komponen SMD.
Papan sirkuit tercetak dan perangkat jadi Bagian digital di sebelah kiri, analog di sebelah kanan.
Bagi saya, ini adalah pengalaman pertama dalam mendesain dan merakit perangkat jadi dan tidak bisa melakukannya tanpa tiang tembok. Misalnya, lubang di sudut papan harus berdiameter 3 mm untuk rak, tetapi ternyata berukuran 1,5 mm.
Firmware dapat dilihat di github . Dalam versi sebelumnya, satu perintah dikirim dalam satu paket USB. Kemudian ternyata pada trek dinamis DosBox mulai melambat karena overhead yang besar dan kecepatan rendah USB 1.0, DosBox hang mengirim pengiriman paket dan menerima respons. Saya harus membuat antrian asinkron dan mengirim perintah dalam batch. Ini menambahkan sedikit keterlambatan, tetapi tidak terlihat.
Pengaturan V-USB
Jika kita sudah tahu mengirim data ke YM3812 sebelumnya, maka USB harus mengotak-atik.
Ganti nama usbconfig-prototype.h
menjadi usbconfig.h
dan tambahkan (di bawah ini hanya suntingan):
Dalam file main.c
, kami mendefinisikan struktur data paket
Nyatakan pegangan untuk HID
PROGMEM const char usbHidReportDescriptor[] = {
Penangan acara:
Saya merekomendasikan artikel berbahasa Rusia ini tentang V-USB:
http://microsin.net/programming/avr-working-with-usb/avr-v-usb-tutorial.html
http://we.easyelectronics.ru/electro-and-pc/usb-dlya-avr-chast-2-hid-class-na-v-usb.html
Dukungan DosBox
Kode untuk DosBox dapat dilihat di repositori yang sama .
Untuk bekerja dengan perangkat di sisi PC, saya menggunakan perpustakaan hidlibrary.h
(sayangnya, saya tidak menemukan tautan ke aslinya), yang harus diubah sedikit.
Saya memutuskan untuk tidak menyentuh emulator OPL, tetapi untuk mengimplementasikan kelas terpisah saya sendiri. Beralih ke USB dalam konfigurasi sekarang terlihat seperti ini:
[sblaster] oplemu=usb
Dalam konstruktor modul Adlib di adlib.cpp
tambahkan ketentuan:
else if (oplemu == "usb") { handler = new OPL2USB::Handler(); } else {
Dan di dosbox.cpp
opsi konfigurasi baru:
const char* oplemus[]={ "default", "compat", "fast", "mame", "usb", 0};
Exe yang dikompilasi dapat diambil di sini: https://github.com/deadman2000/usb_opl2/releases/tag/0.1
Video
Perangkat siap beraksiKoneksi:
Suara yang direkam melalui kartu suara:
Hasil dan rencana
Saya puas dengan hasilnya. Menghubungkan perangkat itu mudah, tidak ada masalah. Tentu saja, modifikasi DosBox saya tidak akan pernah masuk ke versi resmi dan cabang populer, seperti Ini adalah solusi yang sangat spesifik.
Baris berikutnya adalah memilih OPL3. Masih ada ide untuk membangun pelacak pada chip OPL
Proyek serupa
VGM Player
Kartu Suara OPL2 di ISA Bus