Skip to content

Instantly share code, notes, and snippets.

@brook2
Created December 25, 2013 05:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brook2/8120547 to your computer and use it in GitHub Desktop.
Save brook2/8120547 to your computer and use it in GitHub Desktop.
diff -x higan -x '*.so' -x '*~' -x '*.o' -uNr higan_v093r11_sockpair/src/gb/cpu/mmio.cpp higan_v093r11_link2/src/gb/cpu/mmio.cpp
--- higan_v093r11_sockpair/src/gb/cpu/mmio.cpp 2013-12-24 06:22:02.000000000 +0000
+++ higan_v093r11_link2/src/gb/cpu/mmio.cpp 2013-12-25 05:20:27.823709075 +0000
@@ -53,12 +53,12 @@
if(interface->tracer.open()) {
char buffer[1024];
- sprintf(buffer, "SB R 0x%.2x\n", 0xff);
+ sprintf(buffer, "SB R 0x%.2x\n", status.serial_data);
interface->tracer.print(buffer);
interface->tracer.flush();
}
- return 0xff;
+ return status.serial_data;
}
if(addr == 0xff02) { //SC
@@ -197,7 +197,17 @@
status.serial_transfer = data & 0x80;
status.serial_clock = data & 0x01;
- if(status.serial_transfer) status.serial_bits = 8;
+ if(status.serial_transfer) status.serial_bits = 16;
+
+ if(status.serial_transfer && status.serial_clock) {
+ // internal clock
+ char bit[2];
+ bit[0] = '0';
+ bit[1] = '\0';
+
+ write(sockSCK, bit, 1);
+ }
+
return;
}
diff -x higan -x '*.so' -x '*~' -x '*.o' -uNr higan_v093r11_sockpair/src/gb/cpu/timing.cpp higan_v093r11_link2/src/gb/cpu/timing.cpp
--- higan_v093r11_sockpair/src/gb/cpu/timing.cpp 2013-12-24 08:34:43.862134958 +0000
+++ higan_v093r11_link2/src/gb/cpu/timing.cpp 2013-12-25 05:27:43.555726032 +0000
@@ -65,17 +65,125 @@
}
status.div++;
-}
-void CPU::timer_8192hz() {
- if(status.serial_transfer && status.serial_clock) {
- if(--status.serial_bits == 0) {
- status.serial_transfer = 0;
- interrupt_raise(Interrupt::Serial);
+ //
+
+ int half_time = !((status.clock & 511) == 0);
+
+ if(!half_time && !(status.serial_bits%2)) {
+ if(status.serial_transfer && status.serial_clock) {
+ // using internal clock
+ // shift clock is low
+
+ // shift highest bit out
+ int highest_bit = 0x80 & status.serial_data;
+ { char bit[2];
+ bit[0] = highest_bit?'1':'0';
+ bit[1] = '\0';
+
+ write(sockSIO, bit, 1);
+ }
+ status.serial_data = status.serial_data << 1;
+
+ // signal that the shift clock went high
+ { char bit[2];
+ bit[0] = '1';
+ bit[1] = '\0';
+
+ write(sockSCK, bit, 1);
+ }
+
+ --status.serial_bits;
+ }
+ else if(status.serial_transfer && !status.serial_clock) {
+ // wait for the shift clock to go low
+ char buf[2];
+ buf[0] = '?';
+ buf[1] = 0;
+ if(1 == recv(sockSCK, buf, 1, MSG_DONTWAIT)) {
+ if(buf[0]=='1')
+ printf("ext SCK went high expected low\n");
+ }
+
+ if(buf[0] == '0') {
+ // shift highest bit out
+ int highest_bit = 0x80 & status.serial_data;
+ { char bit[2];
+ bit[0] = highest_bit?'1':'0';
+ bit[1] = '\0';
+
+ write(sockSIO, bit, 1);
+ }
+ status.serial_data = status.serial_data << 1;
+
+ --status.serial_bits;
+ }
+ }
+ }
+ else if(half_time && (status.serial_bits%2)) {
+ if(status.serial_transfer && status.serial_clock) {
+ // shift clock is high
+ // read a bit in
+ // TODO: If we dont get it what? should we wait next turn or
+ // just say we read a zero
+ // should we take a note that we need to drain the socket of
+ // a bit?
+ char bit[2];
+ bit[0] = '?';
+ bit[1] = 0;
+ if(1 == recv(sockSIO, bit, 1, MSG_WAITALL)) { // this shouldn't(?) block but it helps to do so
+ if(bit[0] == '1') status.serial_data |= 1;
+
+ if(--status.serial_bits == 0) {
+ status.serial_transfer = 0;
+ interrupt_raise(Interrupt::Serial);
+ }
+ else {
+ // signal that the shift clock went low
+ { char bit[2];
+ bit[0] = '0';
+ bit[1] = '\0';
+
+ write(sockSCK, bit, 1);
+ }
+ }
+ }
+ else {
+ printf("disaster 001 occured\n");
+ }
+ }
+ else if(status.serial_transfer && !status.serial_clock) {
+ // wait for the external clock to go high
+ { char buf[2];
+ buf[0] = '?';
+ buf[1] = 0;
+ if(1 == recv(sockSCK, buf, 1, MSG_WAITALL)) {
+ if(buf[0]=='0')
+ printf("ext SCK low expected high\n");
+ }
+ }
+
+ // read a bit in
+ char bit[2];
+ bit[0] = '?';
+ bit[1] = 0;
+ if(1 == recv(sockSIO, bit, 1, MSG_DONTWAIT)) { // could block but not needed
+ if(bit[0] == '1') status.serial_data |= 1;
+
+ if(--status.serial_bits == 0) {
+ status.serial_transfer = 0;
+ interrupt_raise(Interrupt::Serial);
+ }
+ }
+ else {
+ printf("disaster 002 occured\n");
+ }
}
}
}
+void CPU::timer_8192hz() {}
+
void CPU::timer_4096hz() {
if(status.timer_enable && status.timer_clock == 0) {
if(++status.tima == 0) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment