diff --git a/src/snes/chip/serial/serial.cpp b/src/snes/chip/serial/serial.cpp index 80bde888..01ce0e1f 100644 --- a/src/snes/chip/serial/serial.cpp +++ b/src/snes/chip/serial/serial.cpp @@ -5,40 +5,16 @@ namespace SNES { Serial serial; +static void snesserial_tick(unsigned clocks) { serial.add_clocks(clocks); } +static uint8 snesserial_read() { return serial.read(); } +static void snesserial_write(uint8 data) { serial.write(data); } + void Serial::enter() { - scheduler.clock.cop_freq = cartridge.serial_baud_rate() * 2; - + scheduler.clock.cop_freq = cartridge.serial_baud_rate() * 4; latch = 0; - add_clocks(512); - - for(unsigned i = 0; i < 6; i++) { - latch = 1; add_clocks(2); - - latch = 1; add_clocks(2); - latch = 0; add_clocks(2); - latch = 0; add_clocks(2); - latch = 1; add_clocks(2); - latch = 0; add_clocks(2); - latch = 1; add_clocks(2); - latch = 1; add_clocks(2); - latch = 0; add_clocks(2); - - latch = 0; add_clocks(2); - } - - while(true) { - while(cpu.joylatch() == 0) add_clocks(1); - while(cpu.joylatch() == 1) add_clocks(1); - add_clocks(1); - - uint8 data = 0; - for(unsigned i = 0; i < 8; i++) { - add_clocks(2); - data = (data << 1) | cpu.joylatch(); - } - - print("Read ", strhex<2>(data), "\n"); - } + add_clocks(256 * 4); + if(snesserial_main) snesserial_main(snesserial_tick, snesserial_read, snesserial_write); + while(true) add_clocks(scheduler.clock.cop_freq); } void Serial::add_clocks(unsigned clocks) { @@ -46,10 +22,42 @@ void Serial::add_clocks(unsigned clocks) { scheduler.sync_copcpu(); } +uint8 Serial::read() { + while(cpu.joylatch() == 0) add_clocks(1); + while(cpu.joylatch() == 1) add_clocks(1); + add_clocks(2); + + uint8 data = 0; + for(unsigned i = 0; i < 8; i++) { + add_clocks(4); + data = (cpu.joylatch() << 7) | (data >> 1); + } + + return data; +} + +void Serial::write(uint8 data) { + latch = 1; + add_clocks(4); + + for(unsigned i = 0; i < 8; i++) { + latch = (data & 0x01) ^ 1; + data >>= 1; + add_clocks(4); + } + + latch = 0; + add_clocks(4); +} + void Serial::init() { } void Serial::enable() { + if(opened()) close(); + if(open("snesserial")) { + snesserial_main = sym("snesserial_main"); + } } void Serial::power() { diff --git a/src/snes/chip/serial/serial.hpp b/src/snes/chip/serial/serial.hpp index 24604a30..51b60918 100644 --- a/src/snes/chip/serial/serial.hpp +++ b/src/snes/chip/serial/serial.hpp @@ -1,4 +1,4 @@ -class Serial : property { +class Serial : property, public library { public: void enter(); @@ -9,8 +9,11 @@ public: readonly latch; -private: void add_clocks(unsigned clocks); + uint8 read(); + void write(uint8 data); + + function snesserial_main; }; extern Serial serial; diff --git a/src/snes/snes.hpp b/src/snes/snes.hpp index 4b3a76ec..f823f5dd 100644 --- a/src/snes/snes.hpp +++ b/src/snes/snes.hpp @@ -1,4 +1,4 @@ -static const char bsnesVersion[] = "065.01"; +static const char bsnesVersion[] = "065.02"; static const char bsnesTitle[] = "bsnes"; static const unsigned bsnesSerializerVersion = 10; @@ -16,7 +16,7 @@ static const unsigned bsnesSerializerVersion = 10; #define CHEAT_SYSTEM //enable debugging extensions (~15% speed hit) -//#define DEBUGGER +#define DEBUGGER #include