# debugging doesn't get compiled into the ROM image
CFLAGS = -m68hc11 -mshort -Wall -O1 \
- -msoft-reg-count=0 -ffixed-z -g
+ -msoft-reg-count=0 -ffixed-z -g -fomit-frame-pointer
LDFLAGS = -m68hc11 -mshort -Wl,-m,m68hc11elfb \
-nostartfiles \
_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 */
+#define DISPLAY_DELAY 50 /* ms to delay between ops - could be tweaked */
void display_reset() {
/* lower the reset line for a while */
bclr((void*)&_io_ports[M6811_PORTA], PORTA_DISP_RESET);
* 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 ("pshx\npsha\npshb\n"); /* save registers */
asm volatile ("ldx %0\n" :: "m" (ms));
asm volatile (
- "loop:\n"
- " dex\n" /* 3 */
- " beq out\n" /* 3 */
- " ldd #327\n" /* 3 */
- "inner_loop:\n" /* 15 cycles each */
- " cpd #0x0000\n" /* 5 */
- " beq inner_loop_end\n" /* 3 */
- " subd #0x0001\n" /* 4 */
- " bra inner_loop\n" /* 3 */
- "inner_loop_end:\n"
- " bra loop\n" /* 3 */
- "out:\n"
- " pulb\n"
+ "delay_loop:\n"
+ " dex\n" /* 3 */
+ " beq delay_out\n" /* 3 */
+ " ldd #327\n" /* 3 */
+ "delay_inner_loop:\n" /* 15 cycles each */
+ " cpd #0x0000\n" /* 5 */
+ " beq delay_inner_loop_end\n" /* 3 */
+ " subd #0x0001\n" /* 4 */
+ " bra delay_inner_loop\n" /* 3 */
+ "delay_inner_loop_end:\n"
+ " bra delay_loop\n" /* 3 */
+ "delay_out:\n");
+ /*" pulb\n"
" pula\n"
- " pulx\n");
+ " pulx\n");*/
}
void my_strncpy(char* dst, char* src, u8 max_size) {
/* 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};
* 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, j, num;
+ u8 i, num;
if (row)
bset((void*)&_io_ports[M6811_PORTD], PORTD_KEYPAD_ROW);
bclr_misc_output(A3800_DISPLAY_WRITE); /* disable the display clock */
- /* _io_ports[M6811_SPDR] = 0; */
- asm volatile (
- "ldab #0\n"
- "stab %0\n"
- : "=m" (_io_ports[M6811_SPDR])
- :
- : "b"
- );
+ _io_ports[M6811_SPDR] = 0x55; /* doesn't matter what we send. */
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;
+ while (((i & 0x80) == 0) && (num < 8)) {
+ i = i << 1;
num++;
}
send_packet();
}
-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;
+u16 last_coin_value;
+bool last_door_open;
+char display_buf[11];
+u8 cur_motor[2];
- delay(1000);
+int main() {
+ u8 i;
+ for (i = 0; i < 11; i++)
+ display_buf[i] = ' ';
+ display_buf[10] = '\0';
- chime_on();
- for (i = 0; i < 40000; i++) {}
- chime_off();
- for (i = 0; i < 20000; i++) {}
- chime_on();
- for (i = 0; i < 60000; i++) {}
-
changer_output = 0x7f;
- //_io_ports[M6811_PORTA] = 0xc8; /* for talking to coin mech */
- _io_ports[M6811_PORTA] = 0xc0; /* for talking to serial port */
+ _io_ports[M6811_PORTA] = 0xc0; /* display on. talking to serial port */
_io_ports[M6811_DDRA] = 0xfc;
_io_ports[M6811_DDRD] = 0x3e;
_io_ports[M6811_SPCR] = 0x12;
set_misc_output(0x00);
- chime_off(); /* mainly for debugging */
-
display_init();
set_msg(" HELLO ");
coinmech_init();
keypad_init();
- chime_count = 100;
- while (chime_count != 0);
+ delay(500);
set_msg(" CRUEL ");
last_door_open = 0;
dispense_motor(22);
-
- chime_count = 50;
- while (chime_count != 0);
+ delay(1000);
set_msg(" WORLD ");
delay(1000);
- set_msg("*5N4X0RZ* ");
- delay(1000);
+ chime_start();
+
+ cur_motor[0] = 0;
while(1) {
+ if (cur_motor[0] == 0xff) { /* signal to say redraw screen */
+ set_msg("*5N4X0RZ* ");
+ cur_motor[0] = 0;
+ }
+
if (door_open() != last_door_open) {
last_door_open = door_open();
send_door_msg(last_door_open);
if (last_door_open) {
- chime_on();
+ chime_start();
set_msg("DOOR OPEND");
- delay(100);
- chime_off();
} else {
- chime_on();
+ chime_start();
set_msg("DOOR CLOSE");
- delay(100);
- chime_off();
}
}
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);
+ if (last_key == KEY_RESET) {
+ cur_motor[0] = 0xff;
+ } else {
+ if (cur_motor[0]) {
+ cur_motor[1] = last_key%10;
+ display_buf[1] = cur_motor[0]+'0';
+ set_msg(display_buf);
+ dispense_motor(cur_motor[0]*10 + cur_motor[1]);
+ set_msg(" DONE ");
+ display_buf[0] = ' ';
+ display_buf[1] = ' ';
+ cur_motor[0] = 0xff;
+ delay(1000);
+ } else {
+ cur_motor[0] = last_key%10;
+ display_buf[0] = cur_motor[0]+'0';
+ set_msg(display_buf);
+ }
+ }
send_keypress(last_key);
}
}
/* Setup the stack on the top of the data internal ram (not used). */
-PROVIDE (_stack = 0x007f-1);
+PROVIDE (_stack = 0x007f);
else
bclr_misc_output(A3800_MOTOR_DATA);
+ delay(1);
+
/* clock pulse */
bset((void*)&_io_ports[M6811_PORTA], PORTA_MOTOR_CLOCK);
+ delay(1);
bclr((void*)&_io_ports[M6811_PORTA], PORTA_MOTOR_CLOCK);
+ delay(1);
data = data << 1;
}
bclr((void*)&_io_ports[M6811_PORTA], PORTA_MOTOR_CLOCK);
bclr_changer_output(A3000_MOTOR_ROW_DISABLE);
+ bclr((void*)&_io_ports[M6811_PORTA], PORTA_MOTOR_COL_DISABLE);
}
void motors_off() {
}
u8 dispense_motor(u8 slot) {
- if (!is_motor(slot)) return MOTOR_NOSLOT;
+ //if (!is_motor(slot)) return MOTOR_NOSLOT;
motor_on(slot);
+ delay(1000);
+ motors_off();
+ return MOTOR_SUCCESS;
if (!left_home(slot)) {
motors_off();
ldab #0xfc ; 11111000
stab 0x1001
- ;; turn display on
- ldx #0x1000
- bset 00,x #0x80
-
;; start chiming
ldx #0x1000
bset 00,x #0x10
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
- ;; start chiming
- ldx #0x1000
- bset 00,x #0x10
-
;; blank initialised variables - should match memory.x's page0
ldx #0x0000
loop1:
- cpx #0x0080
+ cpx #0x0100
bcc out1
clr 00,x
inx
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
extern volatile u8 _##a; \
u8 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; }
+ extern inline void bset_##a(const u8 m) { \
+ bset(&a, m); \
+ asm volatile ( "ldab %1\nstab %0\n" \
+ : "=m"(_##a) : "m"(a) : "d"); } \
+ extern inline void bclr_##a(const u8 m) { \
+ bclr(&a, m); \
+ asm volatile ( "ldab %1\nstab %0\n" \
+ : "=m"(_##a) : "m"(a) : "d"); }
buffered_addr(changer_output);
buffered_addr(misc_output);