#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; }