From 78faadd7fc4709e03423d757711cf60b7ed2d9c1 Mon Sep 17 00:00:00 2001 From: Bernard Blackham Date: Wed, 23 Jun 2004 19:04:48 +0000 Subject: [PATCH] General cruft removal Added peek, poke and jump Added silence Added ability to change password --- ROM2/Makefile | 11 +-- ROM2/README | 15 +--- ROM2/helpers.c | 19 ++---- ROM2/main_basic.c | 169 +++++++++++++++++++++++++++++++++++++--------- ROM2/src2asm.pl | 2 +- ROM2/vend.h | 7 +- 6 files changed, 154 insertions(+), 69 deletions(-) diff --git a/ROM2/Makefile b/ROM2/Makefile index 49c8f89..f3cfd3b 100644 --- a/ROM2/Makefile +++ b/ROM2/Makefile @@ -7,7 +7,7 @@ OBJS = \ INCLUDES = vend.h keypad.h chime.h asm.h display_basic.h ports.h types.h # debugging doesn't get compiled into the ROM image CFLAGS = -m68hc11 -mshort -Wall -O1 \ - -msoft-reg-count=0 -ffixed-z -g #-fomit-frame-pointer + -msoft-reg-count=0 -ffixed-z -g -fomit-frame-pointer LDFLAGS = -m68hc11 -mshort -Wl,-m,m68hc11elfb \ -nostartfiles \ @@ -56,7 +56,7 @@ size: rom2.s19 rom.tar.bz2: rm -f romsrc.s crctab.h - tar cjf rom.tar.bz2 README Makefile gdbsimrc *.pl *.c *.h *.s *.x + tar c README Makefile gdbsimrc *.pl *.c *.h *.s *.x | bzip2 -c -9 > $@ romsrc.s: rom.tar.bz2 src2asm.pl perl -w src2asm.pl < $< > $@ @@ -69,13 +69,6 @@ gencrctab: gencrctab.c crctab.h: gencrctab ./gencrctab > $@ -# -# Implicit rules -# -# .elf is for the simulator and gdb -# .s19 is for some downloader and the simulator -# .b is a binary dump -# .SUFFIXES: .elf .s19 .b .elf.s19: diff --git a/ROM2/README b/ROM2/README index 3bfc653..653d561 100644 --- a/ROM2/README +++ b/ROM2/README @@ -1,14 +1,3 @@ This is the source code for the Snack Machine's new ROM at the University -Computer Club. - -To build, you'll require the gcc-m68hc1x & binutils-m68hc1x packages. - -You can also run it in a simulator using gdb-m68hc1x. Except to do so, you'll -need to use a local copy generated as such: - -sed -e 's|m68hc11eepr/reg 0xb000 512|m68hc11eepr/reg 0x4000 1 |' < /usr/bin/m68hc11-gdb > my-m68hc11-gdb - -This is in order to move the internal eprom out of the way in the simulator that -would otherwise cause the simulator to fail when loading the ROM. - - +Computer Club. To build, you'll require the gcc-m68hc1x & binutils-m68hc1x +packages. diff --git a/ROM2/helpers.c b/ROM2/helpers.c index f7bb406..13c2d36 100644 --- a/ROM2/helpers.c +++ b/ROM2/helpers.c @@ -2,18 +2,9 @@ #include "vend.h" void delay(u16 ms) { - /* delay routine written in assembly so we know what we're really getting. - * each inner loop should take ~1 ms to execute. - * 15 cycles * (1/4.9152Mhz) * 327 = 0.997 ms + a little bit on the fringes. - * - * XXX - how do we know gcc isn't optimising this? it seems to optimise after - * parsing C -> asm, but before asm -> machine code. - */ - //asm volatile ("pshx\npsha\npshb\n"); /* save registers */ asm volatile ("ldx %0\n" :: "m" (ms) : "x"); asm volatile ( "delay_loop:\n" - //" ldd #327\n" /* 3 */ " ldd #150\n" /* 3 */ "delay_inner_loop:\n" /* 15 cycles each */ " cpd #0x0000\n" /* 5 */ @@ -25,9 +16,6 @@ void delay(u16 ms) { " beq delay_out\n" /* 3 */ " bra delay_loop\n" /* 3 */ "delay_out:\n" ::: "x", "d"); - /*" pulb\n" - " pula\n" - " pulx\n");*/ } u8 my_strlen(char* s) { @@ -87,3 +75,10 @@ char* u82hex(u8 a) { return hexconv_buf; } +bool ishex(char b) { + if (b >= '0' && b <= '9') return 1; + if (b >= 'a' && b <= 'f') return 1; + if (b >= 'A' && b <= 'F') return 1; + return 0; +} + diff --git a/ROM2/main_basic.c b/ROM2/main_basic.c index a6a8a15..5797318 100644 --- a/ROM2/main_basic.c +++ b/ROM2/main_basic.c @@ -4,7 +4,7 @@ * and snacks. */ -#define VERSION_STRING "R 20040622" +#define VERSION_STRING "V 20040624" #include "display_basic.h" #include "keypad.h" @@ -34,6 +34,14 @@ bool check_standalone() { return 0; } +bool check_badpoke() { + if (cant_poke()) { + send_string("099 Can't poke without flipping DIP SW 3." CRLF); + return 1; + } + return 0; +} + void unknown_command() { send_string("012 Unknown command. Type HELP for help." CRLF); } @@ -252,6 +260,86 @@ void ping_pong() { send_string("000 PONG!" CRLF); } +u16 hex2addr(char* addrptr) { + u16 v; + v = hex2u8(addrptr[0], addrptr[1]) << 8; + v |= hex2u8(addrptr[2], addrptr[3]); + return v; +} + +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)); @@ -322,16 +410,26 @@ void help() { send_string( "Valid commands are:" CRLF " ABOUT ROM information" CRLF - " PING pongs" 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 - " Vnn vend an item" CRLF - " VALL vend all items" CRLF - " DXXXXXXXXXX show a message on the display" CRLF - " B[nn] beep for a duration nn (optional)" CRLF - " S[...] query all internal switch states" CRLF - " H[...] this help screen" CRLF " GETROM download the ROM source code using xmodem" CRLF - "Comments start with a #" CRLF + " H[...] this help screen" CRLF + "*JUMPxxxx jumps to a subroute 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 + "" 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 ); } @@ -404,9 +502,6 @@ void quit() { unknown_command(); } -//SHA1_CTX ctx; -//u8 sha1_digest[SHA1_SIGNATURE_SIZE]; - int main() { u8 i; for (i = 0; i < 11; i++) @@ -444,7 +539,6 @@ int main() { send_string("5N4X0RZ R US" CRLF); mic_challenge = 0; - mic_set_secret("ABCDEFGH12345678"); last_standalone = is_standalone(); if (last_standalone) @@ -494,17 +588,8 @@ int main() { case '#': send_string(CRLF); break; - case 'E': - set_echo(); - break; - case 'H': - help(); - break; - case 'V': - dispense_something(); - break; - case 'D': - write_to_display(); + case 'A': + about(); break; case 'B': do_chime(); @@ -512,23 +597,43 @@ int main() { case 'C': do_silence(); break; - case 'P': - ping_pong(); + case 'D': + write_to_display(); break; - case 'A': - about(); + case 'E': + set_echo(); break; - case 'S': - print_switches(1); + case 'G': + getrom(); + break; + case 'H': + help(); break; case 'M': moo(); break; + case 'P': + if (sci_rx_buf[1] == 'I') + ping_pong(); + else if (sci_rx_buf[1] == 'O') + poke(); + else if (sci_rx_buf[1] == 'E') + peek(); + break; + case 'J': + jump(); + break; case 'Q': quit(); break; - case 'G': - getrom(); + case 'S': + print_switches(1); + break; + case 'V': + dispense_something(); + break; + case 'W': + do_set_password(); break; default: // shurg diff --git a/ROM2/src2asm.pl b/ROM2/src2asm.pl index 2d38015..b723c6d 100644 --- a/ROM2/src2asm.pl +++ b/ROM2/src2asm.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl -w # keep the format of this next line the same to match regex in check-romsrc.pl -$origin = 0x9d80; +$origin = 0x9c80; $hole_start = 0xb600; $hole_size = 0x0200; diff --git a/ROM2/vend.h b/ROM2/vend.h index 5d4f5ac..f2f7106 100644 --- a/ROM2/vend.h +++ b/ROM2/vend.h @@ -27,11 +27,13 @@ extern volatile u8 _home_sensors; #define home_sensors _home_sensors #define is_standalone() (misc_input & 0x01) /* DIP sw 1 */ -#define must_verify() !(misc_input & 0x02) /* DIP sw 2 */ +#define must_verify() (misc_input & 0x02) /* DIP sw 2 */ +#define cant_poke() (misc_input & 0x04) /* DIP sw 3 */ extern u16 _stack; extern char _nvram[]; /* 2048 bytes of nvram! */ -// uncomment for testing. char _nvram[20]; /* 2048 bytes of nvram! */ +// uncomment for testing. +//char _nvram[20]; /* NVRAM map: * * START LEN @@ -51,6 +53,7 @@ char* u82hex(u8 a); u8 hex2u8(char msb, char lsb); char nibble2hexchar(u8 b); u8 hexchar2u8(char b); +bool ishex(char b); /******** Some meaningful bits ******/ #define PORTA_CHIME 0x10 /* chime is on when set */ -- 2.20.1