Path: blob/master/libsnes/bsnes/snes/controller/usart/usart.cpp
2 views
#ifdef CONTROLLER_CPP12//Synchronous serial communications cable emulation34//Hardware:5//Teensy++ 2.0 USB6//AT90USB128678//Connection Diagram:9//[SNES] [Teensy]10// +5v ---11// Clock D512// Latch D213// Data1 D314// Data2 ---15// IOBit ---16// GND GND1718void USART::enter() {19if(init && main) {20init({ &USART::usleep, this }, { &USART::read, this }, { &USART::write, this });21main();22}23while(true) step(1000000); //fallback; main should never return24}2526void USART::usleep(unsigned milliseconds) {27step(milliseconds);28}2930//SNES -> USART31uint8 USART::read() {32while(txbuffer.size() == 0) step(1);33uint8 data = txbuffer[0];34txbuffer.remove(0);35return data;36}3738//USART -> SNES39void USART::write(uint8 data) {40rxbuffer.append(data ^ 0xff);41}4243//clock44uint2 USART::data() {45//SNES -> USART46if(txlength == 0) {47if(latched == 0) txlength++;48} else if(txlength <= 8) {49txdata = (latched << 7) | (txdata >> 1);50txlength++;51} else {52if(latched == 1) txbuffer.append(txdata);53txlength = 0;54}5556//USART -> SNES57if(rxlength == 0 && rxbuffer.size()) {58data1 = 1;59rxdata = rxbuffer[0];60rxbuffer.remove(0);61rxlength++;62} else if(rxlength <= 8) {63data1 = rxdata & 1;64rxdata >>= 1;65rxlength++;66} else {67data1 = 0;68rxlength = 0;69}7071return (data2 << 1) | (data1 << 0);72}7374//latch75void USART::latch(bool data) {76latched = data;77}7879USART::USART(bool port) : Controller(port) {80latched = 0;81data1 = 0;82data2 = 0;8384rxlength = 0;85rxdata = 0;8687txlength = 0;88txdata = 0;8990string filename = interface()->path(Cartridge::Slot::Base, "usart.so");91if(open_absolute(filename)) {92init = sym("usart_init");93main = sym("usart_main");94if(init && main) create(Controller::Enter, 1000000);95}96}9798USART::~USART() {99if(opened()) close();100}101102#endif103104105