+void peek() {
+ if (!my_strncmp("EEK", (char*)sci_rx_buf+1, 3)) {
+ unknown_command();
+ return;
+ }
+ if (check_badpoke()) return;
+ if (ishex(sci_rx_buf[4]) && ishex(sci_rx_buf[5]) && ishex(sci_rx_buf[6]) &&
+ ishex(sci_rx_buf[7]) && sci_rx_buf[8] == '\0') {
+ u16 v = hex2addr((char*)(sci_rx_buf+4));
+ v = *((u8*)v);
+ send_string("090 ");
+ send_string(u82hex(v));
+ send_string(CRLF);
+ return;
+ }
+ send_string("091 Invalid location given." CRLF);
+}
+
+void poke() {
+ if (!my_strncmp("OKE", (char*)sci_rx_buf+1, 3)) {
+ unknown_command();
+ return;
+ }
+ if (check_badpoke()) return;
+ if (ishex(sci_rx_buf[4]) && ishex(sci_rx_buf[5]) && ishex(sci_rx_buf[6]) &&
+ ishex(sci_rx_buf[7]) && ishex(sci_rx_buf[8]) && ishex(sci_rx_buf[9])
+ && sci_rx_buf[10] == '\0') {
+ u16 v;
+ v = hex2addr((char*)(sci_rx_buf+4));
+ *(u8*)v = hex2u8(sci_rx_buf[8], sci_rx_buf[9]);
+ send_string("080 Written." CRLF);
+ return;
+ }
+ send_string("081 Invalid location or byte given." CRLF);
+}
+
+void jump() {
+ if (!my_strncmp("UMP", (char*)sci_rx_buf+1, 3)) {
+ unknown_command();
+ return;
+ }
+ if (check_badpoke()) return;
+ if (ishex(sci_rx_buf[4]) && ishex(sci_rx_buf[5]) && ishex(sci_rx_buf[6]) &&
+ ishex(sci_rx_buf[7]) && sci_rx_buf[8] == '\0') {
+ u16 v = hex2addr((char*)(sci_rx_buf+4));
+ send_string("070 Jumping now." CRLF);
+ asm volatile ("jsr %0" : : "m"(*(u16*)v) : "d");
+ send_string("071 And back." CRLF);
+ return;
+ }
+ send_string("079 Invalid location given." CRLF);
+}
+
+void do_set_password() {
+ u8 i;
+ bool good = 1;
+ if (check_badpoke()) return;
+ for (i=1; i < 17; i++) {
+ if (sci_rx_buf[i] == '\0') {
+ good = 0;
+ break;
+ }
+ }
+ if (good && sci_rx_buf[17] != '\0') good = 0;
+ if (!good) {
+ send_string("061 Password must be exactly 16 characters." CRLF);
+ return;
+ }
+
+ mic_set_secret((char*)(sci_rx_buf+1));
+ send_string("060 Password has been set." CRLF);
+}
+
+void send_prompt() {
+ if (must_verify()) {
+ send_string(u82hex(mic_challenge >> 8));
+ send_string(u82hex(mic_challenge & 0xff));
+ }
+ send_string(is_standalone()?"% ":"# ");
+}
+
+void about() {
+ if (!my_strncmp("BOUT", (char*)sci_rx_buf+1, 4)) {
+ unknown_command();
+ return;
+ }
+ send_string(
+ "-----------------------------------------------------------------" CRLF
+ "-----------------------------------------------------------------" CRLF
+ " Revision " VERSION_STRING CRLF
+ "" CRLF
+ " This snack machine was brought to you by " CRLF
+ " Bernard Blackham" CRLF
+ " Mark Tearle" CRLF
+ " Harry McNally" CRLF
+ " Michal Gornisiewicz" CRLF
+ " and others." CRLF
+ "" CRLF
+ " Another UCC project in action. http://www.ucc.asn.au/" CRLF
+ );
+}
+
+void set_echo() {
+ if (my_strncmp("CHO ON", (char*)sci_rx_buf+1, 6))
+ sci_echo = 1;
+ else if (my_strncmp("CHO OFF", (char*)sci_rx_buf+1, 7))
+ sci_echo = 0;
+ else
+ unknown_command();
+}
+
+void moo() {
+ if (!my_strncmp("OO", (char*)sci_rx_buf+1, 2)) {
+ unknown_command();
+ return;
+ }
+ send_string(
+" ____________" CRLF
+" |__________|" CRLF
+" / /\\" CRLF
+" / U C C / \\" CRLF
+" /___________/___/|" CRLF
+" | | |" CRLF
+" | ==\\ /== | |" CRLF
+" | O O | \\ \\ |" CRLF
+" | < | \\ \\|" CRLF
+" /| | \\ \\" CRLF
+" / | \\_____/ | / /" CRLF
+" / /| | / /|" CRLF
+"/||\\| | /||\\/" CRLF
+" -------------| " CRLF
+" | | | | " CRLF
+" <__/ \\__>" CRLF
+"" CRLF
+" ... Where's the cheese?" CRLF
+ );
+}
+
+void help() {
+ send_string(
+ "Valid commands are:" CRLF
+ " ABOUT ROM information" CRLF
+ " B[S][nn] beep [synchronously] for a duration nn (optional)" CRLF
+ " C[S][nn] silence [synchronously] for a duration nn (optional)" CRLF
+ " Dxxxxxxxxxx show a message on the display" CRLF
+ " ECHO {ON|OFF} turn echo on or off" CRLF
+ " GETROM download the ROM source code using xmodem" CRLF
+ " H[...] this help screen" CRLF
+ "*JUMPxxxx jumps to a subroutine at location xxxx" CRLF
+ "*PEEKxxxx returns the value of the byte at location xxxx" CRLF
+ "*POKExxxxyy sets the value of location xxxx to yy" CRLF
+ " PING pongs" CRLF
+ " S[...] query all internal switch states" CRLF
+ "+Vnn vend an item" CRLF
+ "+VALL vend all items" CRLF
+ "*Wxxxxxxxxxxxx set a new password for authenticated vends. xxx=16 chars" CRLF
+ " password will be converted to uppercase" CRLF
+ "" CRLF
+ "Very few functions are available when the machine is in standalone " CRLF
+ "mode (DIP SW 1 is set)" CRLF
+ "+ denotes that this item requires authentication if DIP SW 2 is set" CRLF
+ "* denotes that DIP SW 3 must be set to use these" CRLF
+ "Commands starting with # are ignored (comments)" CRLF
+ );
+}
+
+extern const char _rom_src_data[];
+extern const u16 _rom_src_len;
+void getrom() {
+ if (!my_strncmp("ETROM", (char*)sci_rx_buf+1, 5)) {
+ unknown_command();
+ return;
+ }
+ char s[4];
+ send_string("Writing to serial port (maybe). Size is 0x");
+ send_string(u82hex(_rom_src_len >> 8));
+ send_string(u82hex(_rom_src_len & 0xff));
+ send_string("@0x");
+ send_string(u82hex((u16)(&_rom_src_data) >> 8));
+ send_string(u82hex((u16)(&_rom_src_data) & 0xff));
+ send_string(" with signature ");
+ s[0] = _rom_src_data[0];
+ s[1] = _rom_src_data[1];
+ s[2] = _rom_src_data[2];
+ s[3] = '\0';
+ send_string(s);
+ send_string(CRLF " Type YES to download rom.tar.bz2 via XMODEM: ");
+ msg_clr();
+ while (!sci_have_packet); /* spin */
+ if (!my_strncmp("YES", (char*)sci_rx_buf, 3)) {
+ send_string(CRLF "Transfer cancelled." CRLF);
+ return;
+ }
+
+ sci_init();
+ sci_doing_xmodem = 1;
+ if (!xmodem_init_xfer()) {
+ sci_doing_xmodem = 0;
+ send_string("XMODEM init failed. Nobody's listening :(" CRLF);
+ return;
+ }
+ char *p = (char*)_rom_src_data;
+ char *end = (char*)_rom_src_data+_rom_src_len;
+ bool aborted = 0;
+ while (1) {
+ if (p + 128 > end) {
+ /* send partial packet */
+ if (!xmodem_send_packet((char*)p, end-p)) aborted = 1;
+ break;
+ } if ((u16)p == 0xb600) {
+ /* we have an eeprom here. skip it. */
+ p += 0x0200;
+ continue;
+ } else if (!xmodem_send_packet((char*)p, 128)) {
+ aborted = 1;
+ break;
+ }
+ p += 128;
+ }
+
+ xmodem_finish_xfer();
+ sci_doing_xmodem = 0;
+ if (aborted)
+ send_string(CRLF "Transfer aborted." CRLF);
+ else
+ send_string(CRLF "Transfer complete." CRLF);
+}
+
+void quit() {
+ if (my_strncmp("UIT", (char*)sci_rx_buf+1, 3))
+ send_string("013 You can't quit you doofus." CRLF);
+ else
+ unknown_command();
+}
+
+int main() {
+ u8 i;
+ for (i = 0; i < 11; i++)
+ display_buf[i] = ' ';
+ display_buf[10] = '\0';