104 lines
1.8 KiB
C++
104 lines
1.8 KiB
C++
#ifdef CONTROLLER_CPP
|
|
|
|
//Synchronous serial communications cable emulation
|
|
|
|
//Hardware:
|
|
//Teensy++ 2.0 USB
|
|
//AT90USB1286
|
|
|
|
//Connection Diagram:
|
|
//[SNES] [Teensy]
|
|
// +5v ---
|
|
// Clock D5
|
|
// Latch D2
|
|
// Data1 D3
|
|
// Data2 ---
|
|
// IOBit ---
|
|
// GND GND
|
|
|
|
void USART::enter() {
|
|
if(init && main) {
|
|
init({ &USART::usleep, this }, { &USART::read, this }, { &USART::write, this });
|
|
main();
|
|
}
|
|
while(true) step(1000000); //fallback; main should never return
|
|
}
|
|
|
|
void USART::usleep(unsigned milliseconds) {
|
|
step(milliseconds);
|
|
}
|
|
|
|
//SNES -> USART
|
|
uint8 USART::read() {
|
|
while(txbuffer.size() == 0) step(1);
|
|
uint8 data = txbuffer[0];
|
|
txbuffer.remove(0);
|
|
return data;
|
|
}
|
|
|
|
//USART -> SNES
|
|
void USART::write(uint8 data) {
|
|
rxbuffer.append(data ^ 0xff);
|
|
}
|
|
|
|
//clock
|
|
uint2 USART::data() {
|
|
//SNES -> USART
|
|
if(txlength == 0) {
|
|
if(latched == 0) txlength++;
|
|
} else if(txlength <= 8) {
|
|
txdata = (latched << 7) | (txdata >> 1);
|
|
txlength++;
|
|
} else {
|
|
if(latched == 1) txbuffer.append(txdata);
|
|
txlength = 0;
|
|
}
|
|
|
|
//USART -> SNES
|
|
if(rxlength == 0 && rxbuffer.size()) {
|
|
data1 = 1;
|
|
rxdata = rxbuffer[0];
|
|
rxbuffer.remove(0);
|
|
rxlength++;
|
|
} else if(rxlength <= 8) {
|
|
data1 = rxdata & 1;
|
|
rxdata >>= 1;
|
|
rxlength++;
|
|
} else {
|
|
data1 = 0;
|
|
rxlength = 0;
|
|
}
|
|
|
|
return (data2 << 1) | (data1 << 0);
|
|
}
|
|
|
|
//latch
|
|
void USART::latch(bool data) {
|
|
latched = data;
|
|
}
|
|
|
|
USART::USART(bool port) : Controller(port) {
|
|
latched = 0;
|
|
data1 = 0;
|
|
data2 = 0;
|
|
|
|
rxlength = 0;
|
|
rxdata = 0;
|
|
|
|
txlength = 0;
|
|
txdata = 0;
|
|
|
|
string filename = interface->path(Cartridge::Slot::Base, "usart.so");
|
|
if(open_absolute(filename)) {
|
|
init = sym("usart_init");
|
|
main = sym("usart_main");
|
|
if(init && main) create(Controller::Enter, 1000000);
|
|
}
|
|
}
|
|
|
|
USART::~USART() {
|
|
if(opened()) close();
|
|
}
|
|
|
|
#endif
|