Cleanups
[uccvend-snackrom.git] / ROM2 / display.c
index ee3e94b..7da3b10 100644 (file)
 /*
  * display.c - functions for controlling the display on the vending machine.
  *
- * Use set_msg(char*) to write a new message to the screen, replacing the previous
- * one. The message can be at most 1023 characters long. Use set_wrap_mode with
- * one of the WRAP_* options in vend.h to set the scrolling behaviour. If the
- * message is less than 10 characters, it is centered and is not scrolled.
+ *
+ * XXX obsolted - with a backend on the server machine, we don't need to
+ * handle scrolling, etc here. Replaced by display_basic.[cho]
+ *
+ * Use set_msg(char*) to write a new message to the screen, replacing the
+ * previous one. The message can be at most 255 characters long. Use
+ * set_wrap_mode with one of the WRAP_* options in vend.h to set the scrolling
+ * behaviour. If the message is less than 10 characters, it is not scrolled.
  * Otherwise, the message will scroll.
  *
  */
 
-
+#include "display.h"
 #include "vend.h"
 
 char display_buffer[10];    /* what each byte on the display reads          */
-char current_message[1024]; /* message that is scrolled or switched between */
+char current_message[256];  /* message that is scrolled or switched between */
+u8   msg_length;            /* length of current_message                    */
 u8   wrap_mode;             /* whether to scroll or alternate between msgs  */
+u8   scroll_point;          /* how far through the message we have scrolled */
+bool have_scrolled;         /* true after one scroll (used for scroll_msg())*/
 
-void set_msg(char* newmsg) {
-       char* dest = current_message;
-       /* while (dest++ = newmsg++); */
+/* private prototypes */
+void display_send_byte(char c);
+void display_reset();
+void display_update();
+
+void append_msg(char* newmsg, u8 wrap) {
+       char* dest = current_message+msg_length;
+       /* equivalent of a string copy */
        while (newmsg) {
                dest = newmsg;
                dest++;
                newmsg++;
+               msg_length++;
        }
+       wrap_mode = wrap;
 }
 
-void __inline__ set_wrap_mode(u8 new_wrap_mode) {
-       /* in theory it should be inlined anyway? */
-       wrap_mode = new_wrap_mode;
+void set_msg(char* newmsg, u8 wrap) {
+       msg_length = 0;
+       append_msg(newmsg, wrap);
+       scroll_point = 0;
+       display_update();
 }
 
-void display_send_byte(u8 b) {
-       bset_3800(A3800_DISPLAY_WRITE);
+void scroll_msg(char* newmsg) {
+       /* puts a message on display and does not return until the message has
+        * scrolled across once.
+        */
+       set_msg(newmsg, WRAP_SCROLL);
+       have_scrolled = 0;
+       while (!have_scrolled);
+}
+
+void display_shift() {
+       /* update the display for WRAP_SCROLL or WRAP_ALTERNATE modes */
+       switch (wrap_mode) {
+               case WRAP_SCROLL:
+               case WRAP_ALTERNATE:
+                       scroll_point++;
+                       if (scroll_point >= msg_length) {
+                               scroll_point = 0;
+                               have_scrolled = 1;
+                       }
+                       display_update();
+                       break;
+       }
+}
+
+void set_char(char c, u8 pos) {
+       /* sets a single character */
+       display_buffer[pos] = c;
+       display_update();
+}
+
+void display_send_byte(char c) {
+       bset_misc_output(A3800_DISPLAY_WRITE);  /* enable the display clock */
+
+       _io_ports[M6811_SPDR] = c;                  /* load SPI with byte */
+       while(!(_io_ports[M6811_SPDR]&M6811_SPIE)); /* wait for completion */
+       _io_ports[M6811_SPDR];                      /* SPDR read to clear SPIE flag */
 }
 
 #define DISPLAY_DELAY  100 /* ms to delay between ops - could be tweaked */
 void display_reset() {
-       /* lower the reset line for 100ms */
-       bclr(PORTA, PORTA_DISP_RESET);
+       /* lower the reset line for a while */
+       bclr((void*)&_io_ports[M6811_PORTA], PORTA_DISP_RESET);
        delay(DISPLAY_DELAY);
-       bset(PORTA, PORTA_DISP_RESET);
+       bset((void*)&_io_ports[M6811_PORTA], PORTA_DISP_RESET);
 
-       /* enable the SPI */
-       bset(SPCR, SPCR_SPE);
+       spi_enable();
        delay(DISPLAY_DELAY);
 
-       /* tell the controller there are 10 digits */
+       display_send_byte(0xC0 | 10);    /* tell the controller there are 10 digits */
+       display_send_byte(0xE0);    /* set duty cycle to 100%                  */
+
+       spi_disable();
+}
+
+void display_update() {
+       u8 i;
+
+       for (i=0; i < 10; i++) {
+               display_buffer[i] = current_message[
+                       (i+(wrap_mode==WRAP_ALTERNATE?scroll_point/10:scroll_point))
+                       %msg_length];
+       }
+
+       /* hmmm, will this cause some flickering of the display? */
+       display_reset();
        
+       for (i=0; i < 10; i++) {
+               display_send_byte(display_buffer[i]&0x7f);
+       }
 }
 
-void display_refresh() {
+void display_init() {
        display_reset();
 }
+

UCC git Repository :: git.ucc.asn.au