vectors.o start.o
INCLUDES = vend.h keypad.h chime.h asm.h display_basic.h ports.h types.h
-CFLAGS = -O3 -m68hc11 -mshort -Wall -Os \
- -msoft-reg-count=0 -ffixed-z
+# debugging doesn't get compiled into the ROM image
+CFLAGS = -m68hc11 -mshort -Wall -O1 \
+ -msoft-reg-count=0 -ffixed-z -g
LDFLAGS = -m68hc11 -mshort -Wl,-m,m68hc11elfb \
-nostartfiles \
* bset/bclr on the same memory address. Sigh. Either turn off optimisation
* (-O1 without -Os works), or we do it the dumb way.
*/
- *(u8*)addr |= mask;
- // asm volatile (
- // "ldx %0\n"
- // "bset 00,x,%1"
- // : /* outputs */
- // : "p" (addr), "g" (mask) /* inputs */
- // : "x" /* altered registers */
- // );
+ //*(u8*)addr |= mask;
+ asm volatile (
+ "ldx %0\n"
+ "bset 00,x,%1\n"
+ : /* outputs */
+ : "m" (addr), "g" (mask) /* inputs */
+ : "x" /* altered registers */
+ );
}
extern inline void bclr(const void* addr, const u8 mask) {
/* same issue as above */
- *(u8*)addr &= ~mask;
- // asm volatile (
- // "ldx %0\n"
- // "bclr 00,x,%1"
- // : /* outputs */
- // : "p" (addr), "g" (mask) /* inputs */
- // : "x" /* altered registers */
- // );
+ //*(u8*)addr &= ~mask;
+ asm volatile (
+ "ldx %0\n"
+ "bclr 00,x,%1\n"
+ : /* outputs */
+ : "m" (addr), "g" (mask) /* inputs */
+ : "x" /* altered registers */
+ );
}
extern inline void lock() {
#include "vend.h"
#include "chime.h"
-u8 chime_count;
+volatile u8 chime_count;
void chime() {
/* called from the RTI interrupt, sees if we need to turn the chime on or
#define CHIME_TIME 5 /* number of RTIs to have the chime on (6.6ms each) */
-extern u8 chime_count;
+extern volatile u8 chime_count;
/* outside world interface */
extern inline void chime_start() { chime_count = CHIME_TIME; }
void display_send_byte(char c);
void display_reset();
-void set_msg(char newmsg[10]) {
+void set_msg(char newmsg[11]) {
int i;
display_reset();
+ spi_enable();
for (i=0; i < 10; i++) {
+ if (newmsg[i] == 0) break;
+ }
+ for (i--; i >= 0; i--) {
display_send_byte(newmsg[i]&0x7f);
}
+ spi_disable();
}
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 */
+ while(!(_io_ports[M6811_SPSR]&M6811_SPIF)); /* wait for completion */
+ _io_ports[M6811_SPDR]; /* SPDR read to clear SPIF flag */
bclr_misc_output(A3800_DISPLAY_WRITE); /* disable the display clock */
+ delay(1); /* guarantee t_BUSY (40us) */
}
#define DISPLAY_DELAY 100 /* ms to delay between ops - could be tweaked */
bclr((void*)&_io_ports[M6811_PORTA], PORTA_DISP_RESET);
delay(DISPLAY_DELAY);
bset((void*)&_io_ports[M6811_PORTA], PORTA_DISP_RESET);
+ delay(DISPLAY_DELAY);
spi_enable();
- delay(DISPLAY_DELAY);
display_send_byte(0xC0 | 10); /* tell the controller there are 10 digits */
- display_send_byte(0xE0); /* set duty cycle to 100% */
+ //display_send_byte(0xE0); /* set duty cycle to 0% */
+ display_send_byte(0xFF); /* set duty cycle to 100% */
spi_disable();
}
#include "types.h"
void display_init();
-void set_msg(char newmsg[10]);
+void set_msg(char newmsg[11]);
#endif /* _DISPLAY_H_ */
#include "chime.h"
#include "vend.h"
#include "keypad.h"
+#include "display_basic.h"
-u8 last_key; /* the last key registered */
-bool new_key;
+volatile u8 last_key; /* the last key registered */
+volatile bool new_key;
/* first 8 from the first row, then 3 from the second row */
/* keys are 1-9, 0, reset */
-const u8 keymap0[8] = {KEY_8, KEY_7, KEY_6, KEY_5, KEY_4, KEY_3, KEY_2, KEY_1};
-const u8 keymap1[3] = {KEY_RESET, KEY_0, KEY_9};
+const u8 keymap0[8] = {KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8};
+const u8 keymap1[3] = {KEY_9, KEY_0, KEY_RESET};
#define NO_KEY 8
* register (from 0..7). If no bits were turned on, it returns 8 (aka NO_KEY)
*/
extern inline u8 keypad_read_row(u8 row) {
- u8 i, num;
+ u8 i, j, num;
+
if (row)
bset((void*)&_io_ports[M6811_PORTD], PORTD_KEYPAD_ROW);
else
bclr((void*)&_io_ports[M6811_PORTD], PORTD_KEYPAD_ROW);
+ spi_enable();
+
+ bset_misc_output(A3800_KEYPAD_STROBE);
+ bclr_misc_output(A3800_KEYPAD_STROBE);
+
bclr_misc_output(A3800_DISPLAY_WRITE); /* disable the display clock */
- _io_ports[M6811_SPDR] = 0;
- while(!(_io_ports[M6811_SPDR]&M6811_SPIE)); /* wait for completion */
+ /* _io_ports[M6811_SPDR] = 0; */
+ asm volatile (
+ "ldab #0\n"
+ "stab %0\n"
+ : "=m" (_io_ports[M6811_SPDR])
+ :
+ : "b"
+ );
+ while(!(_io_ports[M6811_SPSR]&M6811_SPIF)); /* wait for completion */
+
+ /* SPDR read to clear SPIF flag is performed below: */
+ i = _io_ports[M6811_SPDR];
+
+ /* print out the row & read in key in binary */
+ char msg_buf[11] = "XKXXXXXXXX";
+ msg_buf[0] = row?'1':'0';
+ for (j = 1, num = 0; num < 8; j = j << 1, num++) {
+ msg_buf[num+2] = (i & j)?'1':'0';
+ }
+ set_msg(msg_buf);
+
+ num = 0;
+ while (((i & 0x01) == 0) && (num < 8)) {
+ i = i >> 1;
+ num++;
+ }
- for (i = _io_ports[M6811_SPDR], num = 0;
- ((i&0x1) == 0) && (num < 8);
- i=i>>1, num++);
+ spi_disable();
return num;
}
#define KEY_0 10
#define KEY_RESET 11
-extern u8 last_key;
+extern volatile u8 last_key;
/* returns true if a key has been pressed since the last call */
bool keypad_pressed();
int main() {
u16 last_coin_value;
bool last_door_open;
+ int display_pos;
+ unsigned int i;
+ char display_buf[11];
+ for (display_pos = 0; display_pos < 11; display_pos++)
+ display_buf[display_pos] = '\0';
+ display_pos = 0;
+ delay(1000);
+
+ chime_on();
+ for (i = 0; i < 40000; i++) {}
+ chime_off();
+ for (i = 0; i < 20000; i++) {}
chime_on();
+ for (i = 0; i < 60000; i++) {}
- misc_output = 0;
changer_output = 0x7f;
- _io_ports[M6811_PORTA] = 0xc8;
+ //_io_ports[M6811_PORTA] = 0xc8; /* for talking to coin mech */
+ _io_ports[M6811_PORTA] = 0xc0; /* for talking to serial port */
+ _io_ports[M6811_DDRA] = 0xfc;
_io_ports[M6811_DDRD] = 0x3e;
_io_ports[M6811_SPCR] = 0x12;
+ set_misc_output(0x00);
- delay(1000); chime_off(); /* mainly for debugging */
+ chime_off(); /* mainly for debugging */
+
+ display_init();
+ set_msg(" HELLO ");
unlock(); /* enable interrupts */
- display_init();
comm_init();
coinmech_init();
keypad_init();
+ chime_count = 100;
+ while (chime_count != 0);
+
+ set_msg(" CRUEL ");
+
last_coin_value = 0;
last_door_open = 0;
+ dispense_motor(22);
+
+ chime_count = 50;
+ while (chime_count != 0);
+
+ set_msg(" WORLD ");
+ delay(1000);
+ set_msg("*5N4X0RZ* ");
+ delay(1000);
+
while(1) {
if (door_open() != last_door_open) {
last_door_open = door_open();
send_door_msg(last_door_open);
+ if (last_door_open) {
+ chime_on();
+ set_msg("DOOR OPEND");
+ delay(100);
+ chime_off();
+ } else {
+ chime_on();
+ set_msg("DOOR CLOSE");
+ delay(100);
+ chime_off();
+ }
}
if (rx_queue_state) {
keypad_read();
if (keypad_pressed()) {
+ if (last_key == KEY_RESET)
+ display_buf[display_pos] = 'R';
+ else
+ display_buf[display_pos] = '0'+(last_key%10);
+ display_pos++;
+ display_pos %= 10;
+ set_msg(display_buf);
send_keypress(last_key);
}
.globl _start
_start:
+ ;; set port a to output
+ ldab #0xfc ; 11111000
+ stab 0x1001
+
+ ;; turn display on
+ ldx #0x1000
+ bset 00,x #0x80
+
+ ;; start chiming
+ ldx #0x1000
+ bset 00,x #0x10
+
;; enable the RTI
ldaa #0x40
staa 0x1024
ldaa #0x81
staa 0x1026 ;; RTI interval becomes E/2^14 = 6.6ms (or 150 Hz)
+ ;; stop chiming
+ ldx #0x1000
+ bclr 00,x #0x10
+
;; clear ADC register
clra
staa 0x1030
;; set the stack pointer
- lds _stack
+ lds #_stack
+
+ ;; start chiming
+ ldx #0x1000
+ bset 00,x #0x10
;; blank initialised variables - should match memory.x's page0
ldx #0x0000
bra loop1
out1:
+ ;; wait a while
+ ldx #0x0000
+loop2:
+ cpx #0x00ff
+ bcc out2
+ clr 00,x
+ inx
+ bra loop2
+out2:
+
+ ;; stop chiming
+ ldx #0x1000
+ bclr 00,x #0x10
+
jsr main
infinity:
.sect .text
rti:
jsr chime
+ ldaa #0x40
+ staa 0x1025
rti
;;
.word def ; ffee
;; Misc
+ ;.word def ; fff0 (RTII) ; uncomment to disable the RTI & comment below
.word rti ; fff0 (RTII)
.word uart_interrupt ; fff2 (IRQ)
.word def ; fff4 (XIRQ)
* with buffered_addr, and also in LDFLAGS in the Makefile
*/
#define buffered_addr(a) \
- extern volatile u8* _##a; \
+ extern volatile u8 _##a; \
u8 a; \
- extern inline void set_##a(u8 b) { a = *_##a = b; } \
- extern inline void bset_##a(const u8 m) { bset(&a, m); *_##a = a; } \
- extern inline void bclr_##a(const u8 m) { bclr(&a, m); *_##a = a; }
+ extern inline void set_##a(u8 b) { a = b; _##a = b; } \
+ extern inline void bset_##a(const u8 m) { bset(&a, m); _##a = a; } \
+ extern inline void bclr_##a(const u8 m) { bclr(&a, m); _##a = a; }
buffered_addr(changer_output);
buffered_addr(misc_output);
-extern volatile u8* _switch_input;
-#define switch_input (*_switch_input)
-extern volatile u8* _misc_input;
-#define misc_input (*_misc_input)
-extern volatile u8* _home_sensors;
-#define home_sensors (*_home_sensors)
+extern volatile u8 _switch_input;
+#define switch_input _switch_input
+extern volatile u8 _misc_input;
+#define misc_input _misc_input
+extern volatile u8 _home_sensors;
+#define home_sensors _home_sensors
extern u16 _stack;
#define A3000_MOTOR_ROW_DISABLE 0x80
/* Address 3800 bits */
-#define A3800_DISPLAY_WRITE 0x04
+#define A3800_KEYPAD_STROBE 0x04
+#define A3800_DISPLAY_WRITE 0x08
#define A3800_MOTOR_DATA 0x10
#define A3800_MOTOR_COL8_ENABLE 0x20
#define A3800_MOTOR_COL9_ENABLE 0x40