#include <vectrex.h>
#include "controller.h"
#define true (0==0)
#define false (0!=0)
static inline void set_scale(unsigned int s) {
VIA_t1_cnt_lo = s;
}
static void sprintl(char *dest, long num) { // left-aligned
#define show_digit(x) *dest++ = (char)((x)+'0')
int digit, zeroes;
// This replaces code that used divide by 10 and modulo 10. Much faster.
// handles full 16 bit range of -32768:32767 - Uses negative numbers to avoid the issue of negating -32768
if (num >= 0) num = -num; else *dest++ = '-';
digit = 0;
zeroes = 1; // CLRing is shorter
// max 11 add/subtracts...
if (num <= -20000) { num += 20000; digit += 2; zeroes = 0; }
if (num <= -10000) { num += 10000; digit += 1; zeroes = 0; }
if (!zeroes) show_digit(digit);
digit = 0;
if (num <= -8000) { num += 8000; digit += 8; zeroes = 0; } else if (num <= -4000) { num += 4000; digit += 4; zeroes = 0; }
if (num <= -2000) { num += 2000; digit += 2; zeroes = 0; }
if (num <= -1000) { num += 1000; digit += 1; zeroes = 0; }
if (!zeroes) show_digit(digit);
digit = 0;
if (num <= -800) { num += 800; digit += 8; zeroes = 0; } else if (num <= -400) { num += 400; digit += 4; zeroes = 0; }
if (num <= -200) { num += 200; digit += 2; zeroes = 0; }
if (num <= -100) { num += 100; digit += 1; zeroes = 0; }
if (!zeroes) show_digit(digit);
digit = 0;
if (num <= -80) { num += 80; digit += 8; zeroes = 0; } else if (num <= -40) { num += 40; digit += 4; zeroes = 0; }
if (num <= -20) { num += 20; digit += 2; zeroes = 0; }
if (num <= -10) { num += 10; digit += 1; zeroes = 0; }
if (!zeroes) show_digit(digit);
show_digit((int)-num);
show_digit(0x80-'0');
show_digit(0-'0');
//*dest = 0x80;
}
#define high ((these_buttons & 16) == 0)
#define low ((these_buttons & 16) != 0)
#define BIT_TIMEOUT 70U
unsigned int these_buttons = 0;
int falling(void) {
unsigned int timeout = BIT_TIMEOUT;
// it's high
do {
Read_Btns (); these_buttons = buttons_held();
timeout -= 1U;
if (timeout == 0U) return false;
} while high;
// it's low now
return true;
}
int rising(void) {
unsigned int timeout = BIT_TIMEOUT;
// it's low
do {
Read_Btns (); these_buttons = buttons_held();
timeout -= 1U;
if (timeout == 0U) return false;
} while low;
// it's high now
return true;
}
int main(void) {
static char Text[85];
static char Num[11];
unsigned int textp = 2;
unsigned int key = 0;
Text[0] = Text[1] = ' '; Text[2] = 0x80; Text[3] = '\0';
Num[0] = '0'; Num[1] = Num[2] = ' '; Num[3] = 0x80; Num[4] = '\0';
enable_controller_1_x();
enable_controller_1_y();
// buttons to press in order to enter a character by hand, to check algorithm!
// \ \ \ \ \ \ \ 1
// \ \ \ \ 1 3 6 2
// 1 2 4 8 6 2 4 8
// data W: 1 0 0 0 0 0 1 0
// clock Q: 1 0 1 0 1 0 1 0
// Although an earlier version of the code did get an occasional corrupted
// lower bit - this version gets the character correct every time ... however
// it does sometimes miss characters - probably due to the inclusion of the
// timeout code. Up to the application developer whether he wants to retain that.
for (;;) {
Wait_Recal();
Joy_Analog ();
Intensity_7F ();
Reset0Ref ();
set_scale(127);
Moveto_d(0,0);
Print_Str_d(-4, -120, Text);
Print_Str_d(-32, -4, Num);
// When the strobe is asserted ((these_buttons & 16) != 0) the data bit is
// already in place, as the data bit is always written first and then the strobe.
// default quiescent state is low.
Read_Btns (); these_buttons = buttons_held(); // start bit *not* in a loop so that
// screen doesn't blank...
if (high) { // Rising edge - bit 0
// Extra 'start' bit to solve noise issue. (first bit was sometimes wrong)
// Wait for start-bit clock
if (!falling()) continue;
key = 0; // Wait for next trigger = falling edge - bit 1
if (!rising()) continue;
key |= ((these_buttons&32U) ? 1U : 0); // Wait for next trigger = rising edge - bit 2
if (!falling()) continue;
key |= ((these_buttons&32U) ? 2U : 0); // Wait for next trigger = falling edge - bit 3
if (!rising()) continue;
key |= ((these_buttons&32U) ? 4U : 0); // Wait for next trigger = rising edge - bit 4
if (!falling()) continue;
key |= ((these_buttons&32U) ? 8U : 0); // Wait for next trigger = falling edge - bit 5
if (!rising()) continue;
key |= ((these_buttons&32U) ? 16U : 0); // Wait for next trigger = rising edge - bit 6
if (!falling()) continue;
key |= ((these_buttons&32U) ? 32U : 0); // Wait for next trigger = falling edge - bit 7
if (!rising()) continue;
key |= ((these_buttons&32U) ? 64U : 0);
if (!falling()) continue;
key |= ((these_buttons&32U) ? 128U : 0);
//if (!rising()) continue;
// swallow stop bit. Back to quiescent 'low' state between characters.
// first two places in Text are spaces.
if (key >= 'a' && key <= 'z') { key = key - 'a' + 'A'; }
if (key == 10 || key == 13) {
textp = 2;
} else if ((key == 127 || key == 8) && (textp > 2)) {
textp -= 1;
} else {
if (textp == 80) textp = 2;
Text[textp++] = key;
}
Text[textp] = 0x80; Text[textp+1] = '\0';
sprintl(Num, (long)key);
}
}
return 0;
}